From ec815397a254a5f2d5b38c932d1142117d1b3665 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 4 Feb 2026 13:38:48 +0000 Subject: [PATCH 001/226] Test flow out of varargs parameter in source function --- .../library-tests/semmle/go/dataflow/VarArgs/main.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go index 8e3a498656a..84e76965980 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go @@ -4,7 +4,7 @@ func source() string { return "untrusted data" } -func sink(string) { +func sink(any) { } type A struct { @@ -19,6 +19,10 @@ func functionWithVarArgsParameter(s ...string) string { return s[1] } +func functionWithVarArgsOutParameter(in string, out ...*string) { + *out[0] = in +} + func functionWithSliceOfStructsParameter(s []A) string { return s[1].f } @@ -38,6 +42,12 @@ func main() { sink(functionWithVarArgsParameter(sSlice...)) // $ hasValueFlow="call to functionWithVarArgsParameter" sink(functionWithVarArgsParameter(s0, s1)) // $ hasValueFlow="call to functionWithVarArgsParameter" + var out1 *string + var out2 *string + functionWithVarArgsOutParameter(source(), out1, out2) + sink(out1) // $ MISSING: hasValueFlow="out1" + sink(out2) // $ MISSING: hasValueFlow="out2" + sliceOfStructs := []A{{f: source()}} sink(sliceOfStructs[0].f) // $ hasValueFlow="selection of f" From d6c8767647f7b2983e65cafe63dc69d5cd6d6165 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 4 Feb 2026 13:40:01 +0000 Subject: [PATCH 002/226] Test flow out of varargs parameter in function model --- .../VarArgsWithFunctionModels/Flows.ql | 3 +++ .../dataflow/VarArgsWithFunctionModels/go.mod | 2 +- .../VarArgsWithFunctionModels/main.go | 20 ++++++++++++++----- .../github.com/nonexistent/test/stub.go | 3 +++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql index 78e21d534e0..884e67cfb06 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/Flows.ql @@ -19,6 +19,9 @@ class SummaryModelTest extends DataFlow::FunctionModel { this.hasQualifiedName("github.com/nonexistent/test", "FunctionWithVarArgsParameter") and (inp.isParameter(_) and outp.isResult()) or + this.hasQualifiedName("github.com/nonexistent/test", "FunctionWithVarArgsOutParameter") and + (inp.isParameter(0) and outp.isParameter(any(int i | i >= 1))) + or this.hasQualifiedName("github.com/nonexistent/test", "FunctionWithSliceOfStructsParameter") and (inp.isParameter(0) and outp.isResult()) or diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/go.mod b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/go.mod index ed18764ed28..43614028d1b 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/go.mod +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/go.mod @@ -1,5 +1,5 @@ module semmle.go.Packages -go 1.17 +go 1.25 require github.com/nonexistent/test v0.0.0-20200203000000-0000000000000 diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go index c561de0da2f..e8d53eb9b28 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/main.go @@ -8,7 +8,7 @@ func source() string { return "untrusted data" } -func sink(string) { +func sink(any) { } func main() { @@ -21,10 +21,17 @@ func main() { s0 := "" s1 := source() sSlice := []string{s0, s1} - sink(test.FunctionWithParameter(sSlice[1])) // $ hasValueFlow="call to FunctionWithParameter" - sink(test.FunctionWithSliceParameter(sSlice)) // $ hasTaintFlow="call to FunctionWithSliceParameter" MISSING: hasValueFlow="call to FunctionWithSliceParameter" - sink(test.FunctionWithVarArgsParameter(sSlice...)) // $ hasTaintFlow="call to FunctionWithVarArgsParameter" MISSING: hasValueFlow="call to FunctionWithVarArgsParameter" - sink(test.FunctionWithVarArgsParameter(s0, s1)) // $ MISSING: hasValueFlow="call to FunctionWithVarArgsParameter" + sink(test.FunctionWithParameter(sSlice[1])) // $ hasValueFlow="call to FunctionWithParameter" + sink(test.FunctionWithSliceParameter(sSlice)) // $ hasTaintFlow="call to FunctionWithSliceParameter" MISSING: hasValueFlow="call to FunctionWithSliceParameter" + sink(test.FunctionWithVarArgsParameter(sSlice...)) // $ hasTaintFlow="call to FunctionWithVarArgsParameter" MISSING: hasValueFlow="call to FunctionWithVarArgsParameter" + randomFunctionWithMoreThanOneParameter(1, 2, 3, 4, 5) // This is needed to make the next line pass, because we need to have seen a call to a function with at least 2 parameters for ParameterInput to exist with index 1. + sink(test.FunctionWithVarArgsParameter(s0, s1)) // $ hasValueFlow="call to FunctionWithVarArgsParameter" + + var out1 *string + var out2 *string + test.FunctionWithVarArgsOutParameter(source(), out1, out2) + sink(out1) // $ hasValueFlow="out1" + sink(out2) // $ hasValueFlow="out2" sliceOfStructs := []test.A{{Field: source()}} sink(sliceOfStructs[0].Field) // $ hasValueFlow="selection of Field" @@ -37,3 +44,6 @@ func main() { sink(test.FunctionWithVarArgsOfStructsParameter(aSlice...)) // $ MISSING: hasValueFlow="call to FunctionWithVarArgsOfStructsParameter" sink(test.FunctionWithVarArgsOfStructsParameter(a0, a1)) // $ MISSING: hasValueFlow="call to FunctionWithVarArgsOfStructsParameter" } + +func randomFunctionWithMoreThanOneParameter(i1, i2, i3, i4, i5 int) { +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/vendor/github.com/nonexistent/test/stub.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/vendor/github.com/nonexistent/test/stub.go index 66f3da7d659..28aecd6d479 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/vendor/github.com/nonexistent/test/stub.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/vendor/github.com/nonexistent/test/stub.go @@ -16,6 +16,9 @@ func FunctionWithVarArgsParameter(s ...string) string { return "" } +func FunctionWithVarArgsOutParameter(in string, out ...*string) { +} + func FunctionWithSliceOfStructsParameter(s []A) string { return "" } From 4b830c18647dcddee02a19c308ca1e0592bfc050 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 4 Feb 2026 13:40:33 +0000 Subject: [PATCH 003/226] Test varargs flow with models-as-data --- .../VarArgsWithExternalFlow/Flows.expected | 2 + .../VarArgsWithExternalFlow/Flows.ext.yml | 21 +++++++ .../dataflow/VarArgsWithExternalFlow/Flows.ql | 22 ++++++++ .../dataflow/VarArgsWithExternalFlow/go.mod | 5 ++ .../dataflow/VarArgsWithExternalFlow/main.go | 56 +++++++++++++++++++ .../github.com/nonexistent/test/stub.go | 32 +++++++++++ .../vendor/modules.txt | 3 + 7 files changed, 141 insertions(+) create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/go.mod create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/github.com/nonexistent/test/stub.go create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/modules.txt diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.expected b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.expected new file mode 100644 index 00000000000..42831abaf15 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.expected @@ -0,0 +1,2 @@ +invalidModelRow +testFailures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ext.yml new file mode 100644 index 00000000000..ca3f9559536 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ext.yml @@ -0,0 +1,21 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "", False, "FunctionWithParameter", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithSliceParameter", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithVarArgsParameter", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithVarArgsOutParameter", "", "", "Argument[0]", "Argument[1].ArrayElement", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithSliceOfStructsParameter", "", "", "Argument[0].ArrayElement.Field[github.com/nonexistent/test.A.Field]", "ReturnValue", "value", "manual"] + - ["github.com/nonexistent/test", "", False, "FunctionWithVarArgsOfStructsParameter", "", "", "Argument[0].ArrayElement.Field[github.com/nonexistent/test.A.Field]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "", False, "VariadicSource", "", "", "Argument[0]", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "", False, "VariadicSink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ql b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ql new file mode 100644 index 00000000000..873143a6f81 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/Flows.ql @@ -0,0 +1,22 @@ +import go +import semmle.go.dataflow.ExternalFlow +import ModelValidation +import utils.test.InlineFlowTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + sourceNode(source, "qltest") + or + exists(Function fn | fn.hasQualifiedName(_, ["source", "taint"]) | + source = fn.getACall().getResult() + ) + } + + predicate isSink(DataFlow::Node sink) { + sinkNode(sink, "qltest") + or + exists(Function fn | fn.hasQualifiedName(_, "sink") | sink = fn.getACall().getAnArgument()) + } +} + +import FlowTest diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/go.mod b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/go.mod new file mode 100644 index 00000000000..43614028d1b --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/go.mod @@ -0,0 +1,5 @@ +module semmle.go.Packages + +go 1.25 + +require github.com/nonexistent/test v0.0.0-20200203000000-0000000000000 diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go new file mode 100644 index 00000000000..0a4fc6fa941 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/main.go @@ -0,0 +1,56 @@ +package main + +import ( + "github.com/nonexistent/test" +) + +func source() string { + return "untrusted data" +} + +func sink(any) { +} + +func main() { + s := source() + sink(test.FunctionWithParameter(s)) // $ hasValueFlow="call to FunctionWithParameter" + + stringSlice := []string{source()} + sink(stringSlice[0]) // $ hasValueFlow="index expression" + + s0 := "" + s1 := source() + sSlice := []string{s0, s1} + sink(test.FunctionWithParameter(sSlice[1])) // $ hasValueFlow="call to FunctionWithParameter" + sink(test.FunctionWithSliceParameter(sSlice)) // $ hasValueFlow="call to FunctionWithSliceParameter" + sink(test.FunctionWithVarArgsParameter(sSlice...)) // $ hasValueFlow="call to FunctionWithVarArgsParameter" + sink(test.FunctionWithVarArgsParameter(s0, s1)) // $ hasValueFlow="call to FunctionWithVarArgsParameter" + + var out1 *string + var out2 *string + test.FunctionWithVarArgsOutParameter(source(), out1, out2) + sink(out1) // $ MISSING: hasValueFlow="out1" + sink(out2) // $ MISSING: hasValueFlow="out2" + + sliceOfStructs := []test.A{{Field: source()}} + sink(sliceOfStructs[0].Field) // $ hasValueFlow="selection of Field" + + a0 := test.A{Field: ""} + a1 := test.A{Field: source()} + aSlice := []test.A{a0, a1} + sink(test.FunctionWithSliceOfStructsParameter(aSlice)) // $ hasValueFlow="call to FunctionWithSliceOfStructsParameter" + sink(test.FunctionWithVarArgsOfStructsParameter(aSlice...)) // $ hasValueFlow="call to FunctionWithVarArgsOfStructsParameter" + sink(test.FunctionWithVarArgsOfStructsParameter(a0, a1)) // $ hasValueFlow="call to FunctionWithVarArgsOfStructsParameter" + + var variadicSource string + test.VariadicSource(&variadicSource) + sink(variadicSource) // $ MISSING: hasTaintFlow="variadicSource" + sink(&variadicSource) // $ MISSING: hasTaintFlow="&..." + + var variadicSourcePtr *string + test.VariadicSource(variadicSourcePtr) + sink(variadicSourcePtr) // $ MISSING: hasTaintFlow="variadicSourcePtr" + sink(*variadicSourcePtr) // $ MISSING: hasTaintFlow="star expression" + + test.VariadicSink(source()) // $ hasTaintFlow="[]type{args}" +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/github.com/nonexistent/test/stub.go b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/github.com/nonexistent/test/stub.go new file mode 100644 index 00000000000..4c38a21f6d0 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/github.com/nonexistent/test/stub.go @@ -0,0 +1,32 @@ +package test + +type A struct { + Field string +} + +func FunctionWithParameter(s string) string { + return "" +} + +func FunctionWithSliceParameter(s []string) string { + return "" +} + +func FunctionWithVarArgsParameter(s ...string) string { + return "" +} + +func FunctionWithVarArgsOutParameter(in string, out ...*string) { +} + +func FunctionWithSliceOfStructsParameter(s []A) string { + return "" +} + +func FunctionWithVarArgsOfStructsParameter(s ...A) string { + return "" +} + +func VariadicSource(s ...*string) {} + +func VariadicSink(s ...string) {} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/modules.txt b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/modules.txt new file mode 100644 index 00000000000..b62dbf8819b --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithExternalFlow/vendor/modules.txt @@ -0,0 +1,3 @@ +# github.com/nonexistent/test v0.0.0-20200203000000-0000000000000 +## explicit +github.com/nonexistent/test From 7632bdba88e510adc42e6f68f1da8bd878892eb1 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 4 Feb 2026 13:40:52 +0000 Subject: [PATCH 004/226] (Misc) fix variable names --- .../semmle/go/dataflow/ExternalValueFlow/completetest.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ql index 6bbf16c2020..a5dedbeacf4 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/completetest.ql @@ -9,9 +9,9 @@ import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import utils.test.InlineFlowTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { sourceNode(src, "qltest") } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node src) { sinkNode(src, "qltest") } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } import ValueFlowTest From 408ba2e139442d4451db9004f05ba71467f3e5e8 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 4 Feb 2026 13:41:14 +0000 Subject: [PATCH 005/226] (Misc) Delete spuriously committed binary file --- .../semmle.go.Packages | Bin 1142176 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/semmle.go.Packages diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/semmle.go.Packages b/go/ql/test/library-tests/semmle/go/dataflow/VarArgsWithFunctionModels/semmle.go.Packages deleted file mode 100755 index e3880ac8d5d9d893c3ee41a8c4aafe2702f1a859..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1142176 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�MD|S##F~b&+)q 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

q}H7R1tPs&LZJwhx4uZ%vC`ArbuAE) zdr~b#TQp&;3V-vn>Ql4|g1|hv@x`W|tku+G#J|1w+9syEABzqJd#Y$M@MjB^Ij!`H zKW&S@20Gi~%TmRkQSm_(cNde%_HW-^yzaJTZq?b()98#l@y2BOG@JB2jT)qceo~$L z5?>R`B;Sv->ElxAla&5TzMA^u2q%(G?v?&2A%1Fd;MS_=YoP((hbF zIwC3Yv%Pf3raxh+`o*dAyS?;En?BE`fAVr_{9gKWn?B95oYFO<3oG17UOM61t9cz~ z)0d~ppX8+zJxb}rZTg=DKVgkK$V<2WYwkYUcQ4hPO|c{0aRHKNY~;M51As94@zrL0 zf561CyjG68&eB@LVGM;DfLy@uy+_J3anXDE@?8$)9jVRUO^Ie{`}K z4b>GJqWsE7?6sbcau@cwALpiJbo#dQqkjnGhkW8a;?Kt;^BFTgBk$Euq~KBWGx9Nh z@VB{K^~>KYZw?=fzt>GXxC%K08>om=v1zkTZGOgm36f*jcDrd1jsYS~_$Ok&$!IJw z*~*mdch#t!cu4sN`+krtKTHXKp?u~Zh}BqM&Te0UKJLAlqImN(e&XIp6cIMjuEj$KxBLH!|D-c@yZO^o z40Lq6neGxAakpHToG$l|`;t?2ZE7di&d)yu-@g8hG2d@EYlMD*xzF_P^bZ;3@6T2L z@`f^W(XV`_Aj3Sf^<{G9D%Y=>Kf#Y=zC)AY*y8Zf-2I0Br)7;wTaHhh_~$fqKIH{1 z#88rj@NmAJ0%I@!DA(M_bv9?TyXECS>sdm|b^6-AEo3$zjldk?iWAT*1cPF@v_iP- zwLbgH;mqt`d;x#f-4+LzpH2`C_R}#77G95hAf7~&!i?^0PIO3nVqCc5g-g{s=iIZ}P0bk0&TgmL z-7M0?8dLG%s%HR|3RYHm)^-KMY$M(U-paQo>%iAkz1zlaOEC)Lde!lU`|=w=vLl5* zeKl)Mb0HJe^vGjrvyPKrLXS)ltb)T4AXaD=c*rPWc7S`sG z$(5}h4O}XVV&X!){fSCBpp?a!J_~QToyO9p0az6r2M4pF+*ALV$@0K><^F<2uG^}5 zc{h6|-18M5^}F@k)r}yYuq7))oH5os62}V@urCyNeZJGHV9NYUOwtE}>$ZnVHUtBE zXMdldvZd86L&kGbh>L}~8ea?s+Gf{uRG-<6o%j6xi9cxml#`fkn0d)q^0{0wh-hof zx}Q6-tTOH)3*r8%2(CS&;ZwW2eY5sA+uhCl0xmtiZXP>1;A46U0mj*|bN&UoBP=yg zMT52GYOlXFCF`8PzS-At4=(-9_4?b^_*eDM39Oubeovo&s+@S^eO-SKbxPP->gg=! z=ka0&-eXMH-f~CV-s;mR9$T&bQTY*ZF`v9_{X~2L z`*RjQtpAJb`j6xt#XI&@xf%O;bZ7lT-QAi+iF2rkYMz>62v>l&PT!s@QUonu$(g>v z_UADBbGUxOZ5a{YKgikX8^}9iyXx7>hnSNQ$=k;R{o17WA?dNH8Ighyc}~Ypk@s@1 zk6V%-U)0B}^jIa;uHo5itQldAIZXXLY2H|3ozJBt`wh58+wVpQmCc2KjK~SR=I>SnfDI@O=nMPQH8kJfo-& zaf1tuL~d6ak{nD(ARyh zL(jf(5YAwSYsUwB)%c1fztCU(k$*^ZF!)(;>$JSI1xGb4U83PN3^z9K2&_!G!UW#x z^#pk=ZH=}_8PK?#XzODt{%kt5Sj0HC7!@x4wgA(t6SqYfaHOZqg1*)Fmj|yLk|kx_)c~`7N5v_cpotg+v!%c;1#6Az=l~v0wX(knw?v+!3|<@kGGlBKbutl zqLpR{Px0ozQyY1#r<3VE^2rE(N^sqN%YWyiCL#Cj*6973V4~bN3}}@-4`FWEQ+zQl zJ_W~83uX#^IKW0(UKT~94BuM?u93Sp?u*;%%m zv$yW-LXBB&qEXyM?UXWejel=VJg%Nr2BSl|xUy+06^Eh^xct=M0}_2;FVL=zj{FX? ze&p@y5+doqy}ClMRNbB}{bV0GRCT2jo5Z5=>gGdf)S{4#$+h@K-|>iv7~Z=%aRQnX zU$D)&wz*G`u?}d?#n5)}mWq3|3Kth8t16i(w0!s5zv#N=C}~&%-qvh z%o4E+I~FP*;3k*iI1SYa|0CR+Zxk&E6&2w13~_>D_p*Ym|CxGl12_;?Kp(Z=(d1Q= z`U--*1cD8wcK6%gf@rw=2nQa2^J|%i;5Yl*z^+uZ6%L?3^3i$!FoPdX;IldCVo9++ z6uUDG#X*t&OFkp$dDT+AhWry&I_Wz(*q)1j5%N^oZg(YHOg-hyT*|_T5yNns`2srT zQPV#ShFMao(L~JoZ`{9hJ`IPJ1C)kdoY2lc=Z`i2j>Z5Y^G724+!=`4^WZIziw2(6 zG@g;Z@A9mFMjpRNnP!)hDLkLh0}Z1LQ7E>W5CwXkAbXTgAhf6vV~Ql5C3!i0Pj??! zf+3Y0Y-1@USENB|W9UkGh|w|g90 zQCkq`HQ(>Q_nFBAvArLynRCv5uf1M-?X}l#*=E~&2Yt)@X`(u1li{@%@sv9#ZcMP1 z(k)WToGDe=kj}+x_+%^iu_}1>Y*moyhk1M>ll;-4CRz5+Po4d945AGCrxOdmEN@r0 z67DxX@gIM*D%D@!&`-@D`H^nkeE?6b^tln8^FA=pa#?L9M&iZik^?I{3fvq1@$W$N zVUoh}QLlFpi}}qVVWJV>N5k1kV#pHJ>{Bf`19!|-rbJTrBuG>4-hY00?AD7C0}JXC z?RiCGiM9W_;==}RKbMSP2zWU|J5SsLBAGH?Mv^}b?j_@gDXQ{ z3+MM;kC_Z}wmnF{qYuJjE{Z>}E05PH%Vy5>&#%_D|AXz=^TmH?xv{-w%>~5>nq#NL zXJR1Yd{p({nv3faHx^8({vgn~kxtkU>EXoWHjQLX((L@Q!-bF+|86_!>6)bIVUBsr zB8iNZpa5s_8I)+G0m1;S1P`*!R+wP;l9vj~5QlgGg`RG|WoUlO$AKrr`)-=;#c#%L zzo!}UK!gw`Y409f&Ng`YpQ^q#vx==0i@BHpO04Rl>f7LriQ=bD0o(Q-<1)}iDoEdN z22IG%tBYM%K7sQIH#w!|G1!h(h)zLyqGJ=xSnVuxzRP170%m1g!ow(tR+WAl#u^F(NB-WOOH^5OE zt*)ARB2mKN4EVvKNHIiLc$@uMiW3H6t7Fol>fm6C?d4U`87rd%lu0dO8g#$NY zB`Ya@DbG5FZTvVAIE_FR`w=^N^?}Gnac*{w1CgzS9bR+^Hy+(uF0VtXQY|+BrbvNp zOm`T?>=Q?<^WCS|_Ie0u@6JeK^dr;Q8m$j>AIW`!pdVY9bg;c<YPntKrfALaQ$&|X;P9+Z`Ug*DeMt1bRr-R3Wlj%W!IU)A{B(!^PXAUt)8PMiZpT9-x%ALYJdlu*KE1_NwmaI!<^{Yyn|UW=|~HDgz2i&Edt)r|VqPp#v? z%`)L;iEy(7I}`s+a`t0r-?m-?{^3mVJcCMa?h~-!H}>P-JN$-$NaRSqb}%ItZumb> z7G$xgWg(j$jLmDn21UYqxmJ;#T1rW^fb?6-$j^nEKZSc>PH{ch@;?I(p2mUYt6^+x zF_hj^51Qec+Pf(}`f{GFep3BhpyLk~Go;1=g@!(*&C>UZ`<>#};1oCZg>$Yo_7Y3% zCJk(`(j0C**)W9nDP6Wg(`c(G%@4D+2a$1(6QSMbp$n}*aTrK+HCn;Yn2ZE=e$9&M_z$20fhD8Ne_n6f z_^NbVbp`wN8Yf@M%x|3NxHa3#k6g+qvs_Jl!nTz8t1JJTrzx*R80F8Q{#?F4%-X{< z`e-tB;0qYPPa;--zOp}ki9?*rRJ!#&*DRrbPT(D$R&$!BnDG>8Sy?3e`>V9C5<^Kb ze>q*bMWdod!DrXg5aj)R1bNVtlRw46xqdplYFx!FrDg%`$BXOFvjNsR6lg=PPmoIK z&q+q8{D7ZixM#_OBKjtr4|idBQ{K*y3~1~O1A#SGQ$7pT8&`|ZwGKIyBq)%MIO z{ITbU&3z~ptHg+NN~p*y(4<*)T5s<`iRR(|_U&i?i}(nECI9|8_^~Gsb7JhHk4y`K*DH`%V~dOrMP=b$gwoBXs7>pq=91#~I!E z&V*xFFl=~A;Q`O`gy!3jOp9)zZEUqD49N!tj9BUKZSr>Qcoe?Ov;L84nNa>_Yu~wb zIcMAS0iU||2W<}JDgHUxsg7yZ7C>yVlG2zQkgEx8P8#mOdoc`KqO4VF`mAYDU9k z3G=C@EB4Fs-TF=VzgW6tkc}s`z~{=F;g){{qCdf$l==AaaQwgK55tYBIgt7bVjBC< zz`z|}r5=t$VIT-}Y~ZUGZJUD*-@Zy4_j$w*+nx?AONvc%^59;31VLBL7110={)cR6 z|1C-R=~8ppI;{a+M|2~ma(D?{(ww+$tAyun3D4cc)D{4~#eWS&kvNp}ussoFoj)|D zXj?;GbETJPXaI4l$7nJ5hQ~b~ZB9EU4D@yEg&*7!{N<_g9V(A2vrIAi$E>sg0ab02 zP?_5F@}}}J2<2nHs$6+Rr&ydgg;Oh`%k4p~kZuv~>9S%tw$2RsiaPHPGVy?|7J0w@ zY<<4hPC_JpEf&Ow%ePW_3PlrR+#uX4y*2F5N|UlAsA%%NVR@ZPuf&1m{vLg^28H9cX#riWYmJou)ikZ{w6((KYwyf zd@NaEZ6y;Uy5J8-dHPi!57Bw|oc$)Z^Z%kV;b>b~9vXcjROaR)QGEYsSt6hECtFU+ zJ#@Pd6s{%;R=9!{nSxE9D|pu-3f8tWe}Rs#S|!NUm8oFN=PIbrsleiY>LitmUmdg& zyS#*5JexmVC~m-bAJOb{YGoC_gjf0NG))2rMf6#Du^)LnYV?&h>%9(9IeE=gD_aWt z7s|8v{0kA3N(J0opJeqNiA^o4k9#Fk!0{=a+ZVF0l%9w=>{88glK{MtlC^txhG(wj z>MC>h3T`yP4#s zS!nizw5G+sYL05~L5xzj(~G(@fq5+_>+wNGhJVCJJulbu=Lv)si=~;>~P-96tRTrN+a7zBhy6UdL?elDZrkABT&|bKxi_&E(eHo<{uA}n~ z^qDN-HTEOC26h=J)c7ccM0l2du93>bFvMHU7MvN#@yw6NA>xz%WYa}{3j1nzp22fP%a;3@Ez zDk-+-MB)t<_2ah9B0lJ**3-G^+0&g~e}oS)vLeew1r0iA4R5DdLm3zAQ4e)^sso3U zP$;+9HduyM@41nnJkn&R;N3s@d*gLXkCBp36vEPB3$3 zIS7Nq>K4+WNr+f!8xxqzB5~y3rsi?=@k>fDtJ!;@j;qIgzdm+V38v)#Vc>x%r-$;U z#UtBF*ng5<-4ZerucKJ z7k6p?Q|DUIMOCRYGf%dQwlR&fGIfj+2-2b#+qX2ArR}y~GNXlq;Qv!P%pc`Y4R9X2 zX#ipzE1QjGNOoNQV8nSnNU;IEVaICCk$LZNM-%{%S-PsPFr?7(^y_6i>^ku=54tHUG)e ztYr1Rc{7>O%m3(T38ZCYsShn0TT(qoq8lV5B}=LcPXd9bPVm>##8uDIod8(EG3cXH zzf={rvLD+gofqQ@XHYo^Dp!EY8yzYiD+MA^_>j=Ts)Av5tCD?Ez#OwJ7b8+bsjg4S zaQxrSQS^f*@&88g|3=OD90`y%9UzwV(Mo?+JDcTl5tmy#{iFJ&*3sPIj^p7Vu1q}~ zCNU(OXbABsy$g=3Xy2+Xy1r>0+YH;@4@bMWhIC)it^aMyNAQpPEvxywd0f#rg0#X1vyn>Q56=v_FxierzuqHaF_A631_nVNusj*Kv=Ua|;`@1rK$T(sL zp74K(&)1D3?|`KDG|BAFkSBiwQ8)1I%Q7>}A5v7l*mfif!ME;`eUP%L}T>aD2KwBGYlX zTEOJ+ARUOXd)Ng3w>we;@>(ycufDb{(0Ma+!3~(#Ut7E9+58rk;V?mMn9c@HRdoOm zp?qgKy=M;@Qv-{V)QuGJ@-KzK^grw&q-cP1a(!u6kxV;F2D-`*Cwk+Q*ekU!y|0^* z2L_^I4Vs+B+Q36E1fqBFdQoCT5L}afxSfmLW3SYYdplCSeg2K$-MK=(HuY)_y_yh- zy@MEz#0={ji+9bVE$aNvj?>4UCQWLixp5#Zfi;c1oh$CrAS=;>G{{U(sKqmfgf?A@ zJxA9VH_b{$_Z7?=Qip4HirwJedT#a^2AN=?Nij9Bxs6;6hFSIv^O71@jkaKHOKogN zICelcL#w?^Gmi5JTKSUn{UN4_3KvZ0rrWpuX{miuAPxsE+@AWCxXj|UdasXPKfAu* zdV4=sr274NJ(2jS^__odK0X|uQsUK!-&&b9VqRl7cG>KFhUH6M}hz0y!Q%T{rx>_xg;9L z1-7%(KgMmserF{x6~70&=f4L#b@lfwYde<*$I`53^pcfK=5G@PW{U~xGtdMjwG@NT zgarSp6h|N6QEb9uLowH(>k7Ws^s|y4Cb3n5F;+L+=3ig25$vX`!ANzea{dKLqWhoV z6?h)&B(C}GR-pe{yZ=@D(%USAwzZt_FM6;Z9AkMkyFT#ijS)g&(@QYdu6PK*-7GL~ zHKz!e|9m71g{%KO%T+c@M(;yDp7b9e5dK;C7gY6=j|VgBsXxg@po5w9^VyY?W7LwL zt@Yqem1HL-UH<5n`Pa?c*V_BP5l!X(@@Xrrb0ReH8@neNdjsgYtY?!TFl%lchCj9+LE0t*UVs1KFMT(V8;e6rMv7(R6{T?5Z!i6VmI|hiQ zcBe|b#c$z&&ZgSq#7*Kr3yWdmKi#cI$`&K3xcnIhHP`Dmr*w3;4BTB;G$8Q!mDfT~ zy07Mf60hJw2$)}>8v?qXU5)!skn@~K?Da_O#k$y^>Os91AL#96J>MYQ;t$DQ{3yvw z5F1y+#l1f3+ms$LZz9vQzs&2MRN|JK_8u{|X|zDwZBD$@&FJUb{M2b}*P#+*E)p^G z?TgeGgifV-q~4meK9Ze#G+;4LT)_wR$rN91lis_RBrU-?Kjf!XnvX8CX{X0Y6Hu&v zWfu79Rc4z@AE$J%!B4-2bo01t@i`?S!e~r<0M=1Oe0g4pPM{>F!zMN4+;6dfZ;E5l zcfZ9e50cdx2t%A-n_zpjRCdl2$ZHI{B>f`BkTnrzuON?7Nt2u}ycB>>VLw7M z8npbEBaXazR^R5xYQwcofW{la-5FxvthYecGIN(2N)-O>JJdXs%8-96Y~8HZ%}4BX zlXwMTE9}8hfByaS2D8njm)=J@#GILbKixBzTw=@r{ch5QTdw>$etO7^cj>)}e)W$e z-L(1u2rlzx1|DZybM(tcYtv-nEBdK^bHOUB0=$C^2uCxwA{wN-(XWOUP`Jk+bmHnZ}~L` z0qyK%p_%6nXgN|#I~Gy?vLWFWDJZZ1Mt?YmHGWt6RCAJR?&r&>Q2f(ORE0@fp^UHA ztcMZ+epGJ@EGgIgfkcqb+)-X)PP zj4>zAyu|F7FWD9(qJ3=PstiI1-~bYV_>-96s>+F{|RA|k9&8zNv=>Hi+c*N6wNQyMg}653vlvkj45?ZPtTM!ov zX9MvOX}6CotGwvjG`P*GQ!l;Uv9qOMcTtIr{+jjX$zS=1Jb3a~t<(h5R1Q;rgCX==kH0 zNB*D$W}&C^b!b~~*%EUJZHtnMU_>S9pSlK}eEBw9g*H6FFC(RcCM-!Ef`o_PNn_t-$+I6zN|H z5h&S4V91SR8~sb0ZN_tYE@3R(4DtH>!}NANDZD+`dLDnbwhr}r+1lYkT5zf)aZ{FTP695zdt{a@$oK(W(Ubx1i3llQUO<_#?<=mPwbPjVgJu zbeRPg+Vr1xkZxJ|^?rJ#LVe+%Ig(^)>(@p{0ee_!P-Lw+C8&nU3yTK>7~0=VB<`ZHc5>C;n%myB=Cavv*GHyyO} zun4L{oehv#BVe54VP_@8OYJI|+iP(Gmj1G9;ZRK=SB$PT68 z5e$YlcCk4|zl!I+Y>{+hwEH?c@j~6NZuF{OTR2pHkej^fEsI9_HTI~$;eG+7?$bHn z=QumUp#g)8TCG1`Ai{By*RbR|D{A1PeVOt;#y{s{JX5x4lXr*34O(5R_io;0^Exyq zaP)Zw@(iKeF8ah5hd-J1Psgr6CwFfFSPwjE2+0+)b5j;1-8g5{UoLOC$-0Y)g4Vwq+=m{7~Oc`rOSY2y$a<0d-lnKy$^Jd{mbn zbx@18Za_~BohXz}8?pEewjUlTpQ8?JR|mGIkI8hvZ{2=|Su}1ZE1_!44ciZL3$>^= zhrgHw)IDSpPN8=?<@nUvHWbiB<2hU3m>Hxuvvk-|kRTUU`ps^o96sYEr5|n+YBX+3 z7wPRS`&LpsWV^o35LdgZgg@7bN@u*o)5HyA36$)o{Ht|=60mH>I(}hnSFPpuW!~Q; zTj9@aO;@d_?sd_cvSTc-m;|+b3|m39VQg53^n&XMFAK{X?Qk3P39BtHkP{JDLSj2G zj!TgFb_?$+j2*JQcM_W@aOJxK;+q2E1~2+1Q~pnT#XOGMwNSWSgy9DR?3bV)z#Hqxy+Gn8}&h3VMR_kl?^y?aq6{e9^_;!m#p zE)GmmetkAw`jIU^$Ch8?$}h>LKkApSbmdpL^093CvP^kvzcUM5`Dxko>s@-`^sSmU z(1O`&)Z}5u&UiF-nL0PDtFy(voT;|aRJbZ9XVZ@Mt9w1>aqy+Tk{tt!zU8ik-KUtksPhebe=_@kn=*Og+H1lQt zbY6zXilMe4y4xY?610Hqt0uT;spS4u_xK!EPDv%HNBe1$j=!8Lxz%rfOa}+(Lf)df zXw9x8I0L?DygUq9Esjwjay@Wg(cLon=y_=T2oQ1v+7(uj%offepL)AoK+m60QWr_Z zC*Df+@ijrZP#2GCsZke;>a8}mulvu3*N)#;7wefaeq(KSYVeft-LE!#mP7vHh}-ZF-qe)O33;iYd8a(qp}hG@5x56%G@J!I{L&Cw0yv>n=1;?JgQ6c z`P=GWG&7uCsUjT;|BCgX-Hn4o z519x&_*j(=o9a;MI$asnP0FuG8NZ$SReoSce%ilG(+{2!f2^J9b@lIAbeu;-WvoVc z);_jc2~^h;>ga8LP4atB;5#qy4fI_sh0TeV?v~*${&66FKOeO|42sji051cjXFY$A z6mVQ$nS7RCF9kegC@b7i0#v0Oo1gCgte2Bq{@32-Z^z!$2ZejzU)Sk7FM(@J& z1xBlAmz19HoY<_BpRaA!^Htk`=-T-Off593N#SqY$8P)a@IcAh^l&%FPK7`uT~HD| z5BCmvI(hMnLcacDCu);~nbk$m>a70Kr%h0K>9=gT0%+jfALO3n_GuSTf=`m z&01o{Hv8fQo=lzZ#lKnyQs{&d&uH$?jU8KYhPZFqX+tfa=JyA!*%YuEmJ{I6`Y=VxLS5*EqO3jGKQyXnkD76$OKD`0dwmJ=WSmom55 zDKo!4+X}y{WpX+~*t`}&Cd{uit7>dgkyMP~O8S|fR3ZDHOB{UT z)reS`F23k~`zUW4>&|sKG-~7YaChIOQdlR0eLKuBnggmh45_+k#vM~rWiHNi%~}9D zB(iM#+%cGIMFJd)n;9g_3f8xqKI3Tlfr6G%vldr{KaLb(#f#HOmi{XkIKXDN zf_dK?ve`%5wJ3F6WMAKxy^mq^%WglT-Zxqdr^q+X%C_*oD8lJDnApEk(g=XT_&0EVJob25`6NK&9)ns?=6Z!v{LF(X;qLz49+9?uI>& z4CWgTg7K=qi#*&P2!3QI+kCJT0~cHQ8GXpfA31H%za0CLSO$A_iNXb{YrtT$pv&e3!BxC_;6fgtR+Q8wZtgG=ENJ|JUCrpLy73TgX~i{k-qSfMspU0@>ThtkewX8 zJ(~B`+Oc^?f82?z0(5oDe?Q--7LaOf9EwtQTTSY;IgHVXXAxiAAEFzd4S?G3{B*SD zrXirU?stxTMEHXTj^oPM01j67@W3bY5VUBacncrQeSiC`cSGSK9*J*Sct?cexdTdd zG3=?Th1)V?h1ZkFX_}d984|&gS!O3{u29*lASf>ZEE2^RkZ8h|$_w8fsr;kk-F({f zAn>K)SJ|cF+hB^V7BjR_xSxjbIA1u~vciFu9Hj@1-_#M!&xJ`b8ATz(X?(Er<8| z@WH>-%C3I#d!!pRsK4IQNcpK9pzZiQ<9qRYO4rB@>@-xe*cOHIU{fY`AQF4c%*DE* zRYj$j&k1b`+Wna~9Q)WC z_gT7-U!q`i?rDjeOSJ^(+Zj$wz)|DeW7*%^YxD0Qj-m4JV6%h8=<%*6uEidl=kV>a zow7YiRm1%vtOp2rsGce@MqIy-SgD)MYKX6($PJLc4fex`K@wCDfKg^<_j6%Vjb*9d zeF20W{$X+!{#6M7g2KNbHNs@rQKiO^x#D!`l7-(nT6j|2ZhuN|vOlA5(a$(Vs0?)U z0xXL}-Z#6iLtZ#$LR}^1NL7(2{LT%~hP87Ye-`I#U}bn*AN^(2zcblz(zvRyiw`ve z`9$_R=aOA#ea$BmT{4^LB)@m2P2M+;WUE!a>?fC)%`WLzY6xdc?nfZWjG%czBE*7y zq*-#BEnf6(^2ico?o*!Kd^O+HpFe$xKX38$MK^4;9A;^3OFk!9uj2HV<|4>kRID>Y z@kB}XpOCW`6Y4-yB)!nhM~6Qjz#sg6PjKr8e?hUbgPo6S2O>xojf^MX%o6~X@8)Ox zCY((sQG>&S1omx>XZb4qFlpFbHkxbK3r{2~;`e`Q%YHYH#g*6R;F&lVqui_9XwTwn zr>ZJ5f9cK^A_5w@7qcQgpP#q$^16Caum%x!$dJ&x*!HJqvHGKbaH6vJhS0ogC0_de zyY|gBoq>*qRb+ZHzDbGJ^xpOp?iV5AoAvhS#(styLd)D1cU_~XmfGmZVH zU34f*yLkQ-dHJui)eb3YmljfFvvlY9U3Pzi_-`y6tKxUr5fS=~x%90AFa!2yPqbsF z!4j|7M+ELT)z~Rj*Pfnyss}Ta#o%%yXnh6UZ0~9iXw1V0?k75yU_!9ykzZ)ytvH-q3jGsna7U#X9M81DWHzL)Jx zN?v_+In%@PvZ}!1f?!%l`p_O#4W*CCv$jcjj z<&l79$UxO3G1&cfv8~PK+UmuBS>CQz{9sv0HcuAfD~cN1#%J8XOE1ETA)oBoBF{M* zbz8Xmy`#cDD);tYoS0FXm%e5^n}vA!98{m&cfD};yZ!QyVx^rkAUlG-{z?JvKg5d@ z3DfnDSxSRypF(cJUCxHv7T7o=Fv z-5qk?=0yDL-fbF@m&BRSPAyX8RE+;8YbVS>ezC2|oMu!FSu;7cDR45oh#e0AB3fFD z{3_1D-x@dlD+E{$2dFX})Hbx$!U3GCJku~(*IlmZrT6|6Gpi<_?P%zKS76Cni2|k* zu6Xctdgd$EvZOF_|9m>_;KQ-sYi`~;cy3m!mnLw#oDK=xt(O7z#oz#G_9EX9)<-@9 zA32=?m_fy#=OZG7pu#6sn4TZ{JW*|ySZ-p^GXx&jd4^578z@dcIaed^uOBlV!OSHp zRN<853h$W=C42dAK=MbWxheGK-aZPzHx>FzLEas76j)ck7`S~E4=CL5f~id&AEImd zP#+(@4}yP71dk|j1fPQ7-x9%xt3R3tQ`(n)kU!!r3V$Bt>h4=n`}Pygq0Nh*Z|(QJ zfsUK$lnw=ysj!$&_gjOfCI({b|AhNDaq8`IuFnie^Mo`i>FcpDzRX6zwIbR&0f>ED zg+94X$C9$ISTp?Dxvm`$$3DeBfd|koqad1LZMm>drdIq*`HO%1MW2H|*lFFJ8215< zI}jbEJhTI|(;%2_cpq+O3};7M$DkZ!MjjvKC8m>+8&mg*mp#sDd5yin;V4)@fXSo0 z{Esu*3iz$t(ff245xrONgw-ypUu{Jk-l6CAXUb$icJ?v1{{>X>d8f{#W^1)H2R{`ZoWcEuDSIDVNoHn2Uh`+U#dO=b%v&MonVeC7t> z5n*1DBE4g9pxEub^jB}}$I|u20hS%!-mN*~OB6mm3pS@UiQQiwS=5i!nQ1M#bIAGs zFPu87B)R#6U26WoryG3z&q-%>tMm0h=Pv~s39yG8v_kX$O-Nj^S{SS&a%`4)iK$ld zz(1_V!ls3%3$;q1)c9o^L*B3v8%1i*VT90S70sKi=etJc6hXI#>7LEMk3o^E z@OR5I%@uqAp)1YxC$ctrcC4&>btJ5DIbZw+Ig6EZ=wQ-MbYH)bEk7Y!{uGt(%$8r^ za*mP?I#%U359$xl{qu4GntHB3JRST7z(j$cC-{Yg|L_(mWL%2qb#4xH{!}th7Owx$ zgTja2(a4kI&n+1EH>XRn-;Ka-JRM28MRx#3CUED& zz@fvz*H!l2LsT|El_BrJ&cJ_f^?Ejd)xBPz?p5xC;OiS+v=@BlybLYb^BQjs;?&xJ z`o#47ixLC*4dq7?SECPe+GHbA+wVGhi}kbD;Vgu~e#`?4FP3D0M}d?YGUFb&%^Oy? zEhLO>GUE@Z|FrCOLFvF|Vz^pq=#AUrCD{I=b3e$bmby8y$$9=QY!?!&b!}KCHJMY{DNA3dAk zv^uKVlP=&7;#3l=Z@4gYne)vKiPX%?bG(?75QdP?^&$#OJ`+KD&2^JGl}%=|giS58 z*k!s;?8H*e)&jn!v2{`OjBL^UxM8@WyCE7gO+_zoMgJ^UeM>a=Q8Y)&3&sE%h0Cm& zlS@81GG(pZH*@rZ-BR=u?BhRK__+hIfjjILgF6fxSn`(c4P$S}u;nE!^ZzUFpxTyjz*(68t30 zwvz=ipP!(3i11J)gHo*l*eVPE_-(-RJk@%a4#g9v3MO)427niG)*^84x~cKH9;>-z z=z6J}yGS)7^3j2h}nSfKmz0eP6T8kecO(T8u&{WK1KoE$g^|Ezd( zxMaC+JXvMYXM4+;W@$OOdqQOZiUG?;9$Q?g)YxL1$+1(ry0w;Gz`$jToqHDD;>BeI zv7xKk4#aB){h;@Jr|)~+e=e+xN4^rQD~NohJcIwW#9g=p?Ue3)c7Dsb7RAlrgE|0o zYk`;RiMn8Ul#QAPKZ3cZ3*_kBWszB2=6pJ1{=M1a^QiBE&*Svr-d>IWQ$&-P#{wW1zccW$QdROwjWkIg?#2m(P1tQH_Ke)DK`P;{6Ws@xEovh| zz#=<4WPS_bE4U>l4D%ALLFccXxFw$pbk1ujQfPzm_U<3-lLQ$NT&p7EHXsZ@+pQSI z%{7vG8C+))7Rsp6d^CURj;<0pfd5$mW$z((ijI%kL_x3s9f6jSv}oD~GOOP$_~z%p zmiluaPjK*ArdjI8KP~=t5LmE+^@#W)z8d*#QI;@_5s9zDy-?r8^cEk`?pz@HC@@UM z{$(~Q!A4hyg6s+Y-l&6|1bp2l{> z_Em42$Nu6vm7Dk+A1QKF;NEV;%Ioq4*RrV(|6^O-ji0k_D#*(`U(K`VLSQoWytrvJ zYro-7T&l5ex(;UF{{GwV1+0Gdh4i4_!YaCBMp}(gm%GJF_ue*Kb165>uWN$Yi+Bfv zxC}3e;{EMd9upIeL5;jyY$6Ec(ZxbVW;p) zhA|?xIdeX|M&r7bD~U&i`p@v~w`f+ST01s5TjM)uKHX|7`;{s)FMmcz+PfC% zekRP@XW@^@GwztDZ75u!CQ#K2zv=2*c!>Izs=kwKegCHVR&l*W`l#N*>v&Po<-`Io z@BDj#^nY`XoqFc?jdZaR7btN9iK~DKkXvzrwa>hpngO`Yx4sS>H|F4zqyKZ=`eU}> z*ChBg>5^`DUpGE9x6=DfEk`M^ZezUoF<#+$!3}lg<$39mHfM}gBr?s#&}15$P^gLg zl_;FCkbTqdOEVTBK0%i_BFPo+%}2)@8qt@6)h{*gNX#p!{l48^%_7y8X8>PQqnxo~)%J)-6q zLwDw8R*3`G$v_ACZJq^<g)Cy|5f=4%;m*;CRCYk!-|1pj z0ONI96~}$dw~n$owqHYz!_=&~CY#RSJ^8dK-xQbc@82Y!^{SiTXA7BAT+;N*NWv*7 z&m2P%9YM00!;ZAo|KLi}L?rCrA1FiLzk-fQA7xNL3f?%LZf^S#6cyuQq2)6V^8QHL znFHQGJTN5h4qsEIdvKg^Wv|0E$5tJl0j{IrSfiMRGIM>v_TfJ5ydJCm-AoU%M`dp) zwW*^rJv7&liYyytrn{7`OEcrDbtz@0iWGAXTTA9HSN99@?H7O<->yA^V(E3z)k?b} z>Cd7aef^uGFRyQXFRF>I7S({)(bc>8&66(>L3$4lbdDr{yx6k)5QqUMad!Q0#Dr?tJSbJ;dT(Ep9M64Q)oCgtsTO-n&B^jj+-D# z+XL%#h=17Xn_Vltn@EQ*6vvBy%qPqfM47W;00JGl+ys=a|C2@OFG&W)3qx>Zp)+bt z@$V?%XfR&7+&-i33!NY0#iDc2>EA1`ErBdIFZ4lf9u@vEV^}nFer<(AxxA}L7ep?IK0-IUY~@;(T7;hIXR9z*xunIHkYo|sBgrCkkoi5w(NvGnT_|nw-*l>1bfO`} zIbiySEQODJhi4yh9WseousKgi;$yd2u;uq|BygUXCG$Y=EcFx+%VjNYw7~JD-1OYgw`2wnQvhg1)AH1{yzO@ z({sT!#pV0^*U9JT-_KTIPH{=o8%T2WPm%+dIn2?=4@5&5`X3?sSFf^aEYX+&4&13u z{abMe^L2xh0-SF|2n>#{EvVksLd4sw9!!WBfRd=Yz@+7<=#!2bv7YR~|K-d;=X8~fmv9Xh9^Dj! zI4Az172<3zuLv!>WoBsU!txVB?Y$fw`4J$gOI*;KSzpvuPihQw#`(JRf$}#gDb>oW zg9=V-uep)CQu7pCV-klc-z+xYc}3y1N#~HX&5W{LVI6#kzY&Ziif^P*4qS9s2OhuW zTD2Nv%V)L=78bv|o$6)gsw9Gyd-iWQBOG>;v^4x>zp4y8Zc9F3zuJw(Ka*S=cw(}` zI|e#lV{6uWzl3q6!zvZ{b$2BGwX$&j`Xn3LugFg|9DR?tDKAE1sb@5oFa0?gF1V7| z4QGZrK5L#++rD6E0atuP{A>EcaZDSo6R9?-eK{YpA;n@x)oz%4cs?--*|j7fi^Got zlfV=o92OMXPYTH_M*t-bVW%pnZ))P)qSUM+5Fzl3Eup1nTKT~(9bHNJ#>>Jmn-HmE zZ5AS41v(bcXD|9>J3o0XH*wiaq(%2V*(2?f%ED{(J+GaWcK$kc$&b}7NqHewF&_`s zPWp(QWYs>X?3X8MM~s&OPQ4GLuhI47!2tjZ<=wjQ3Ae++*-Mye_rA1yO7Pfd&CIu; zkCq|Pn&b4)d|@O$y&(dKbl_w|NBM*N7LS8@=UsR{A_v`5Bf*Iti$mZ zViyqauc=k7b5$XMZCK70T%f>oge>=XC?8w9_vI;LUk=*?{u{BI)^7h`O2@m+RUW(l z?bIYA`%eL-HmU9V!3b%wr*A5}gqNQhjRuvZ@hVKNgVm$n8LSv(_4zx6 zopbO3pLatfesx2Ad{jXs@c4<}{QYp^+P>R7_>=m;s$B$jhB_KS1G|1*GeaBFuCmY3 z#z9>XR?Jb2$53O~`MNZwqk$);Hr2+St0NvR3RL;5Db+gzcMv8rZ&qDwdXv{PsgjOz z+~$orBFC}yoI0zIuh`1B+Kz&{z!Psp6c8-%>ksPlf8lXxhjBJ|v8iZclZX#fs}EA0 zVzqoF7=WobN;>9@a&OtRnW!cwpza1biJYGozqAnxP5Ehc)!6iZ!w0=pOi5glUstWb z*L>lnz`oqBs>lfhR7bz9+UzalhEU zrAmq}C;PO-@GvHmK`6y{&PA3bhNB0D8|}K#E<3fBocezWx_+((sqtmYbE-7Ae8iPM zjPgbO%MVp~8BH0-AHU7&*<_W(F7jebLozWZg{ffEM- z$Q=)J5S;Gk3A{@c$yW#yvTw8PL=^rH9;{~NPrjg|J`m=elLNqMH+>NRhx|}v=fw{i zES4h8gn1t!S?9ke91MqpKTQ7;i6_+Dvb)LoSPJ_ae8%3UNreL7eB*r$9 zdZbd1K;sdno}h>{g+p!XJdad}D$o4QY5*$u{t%mVmDDZZmuFrl2?eFXY$e5<%J!K# z$yI)Z7BVL*PYX>$tux9`647N?mDaxt*g2q=`=@8BTV`8wyo>QIaLt`Qg><-Dp1I!d z$(+CwU8G;*(x1GV^iriyB|Y#&UHM5){+#2||EDff{uDnQdQth2>U3)%e{OO;+0;zV zAT_!2Yu;zNxnC?ky(%1CJD3oX1rcKAM7Qi$EV$_nK6AcW%z4x?$cHK1(?{SHYmMAW z{qQNFOVht%e(C$YUT!v^VXwCO~_o*=_UBLPW${!>faVU=o!dgc6M^|q2Xn_0p}nbote(dXHbz^}JP2&5RTd0?lc*ZD#T#1~ru#3v<=f|(Lm zudOZrAa&*tEW3&`@3tO=x4jLwEXeXf+7$nzx71}*;v-~t z1=U$ws8ruIhK#sO{T{oAUrxE~{G@vHv1j1W51;L8MAA#t1d6U+Y-||LkKF_*7B1t3Gt+;bfZ*Sm< zxkTywED&wur9S?D$|CuH)HR09$I9}60(-9uNx(f2zNVC31Eb-vEw?IAkuHl6{f1+p z|5iM2tcFDYsu>AnH#Var$%H(+Pdw*nO0yZ1IdvUGJjoHUvmZHf)cVHK@l+5xL&xCv zInX2Y^>g9BrQ}mY5KL{G!|#zUeOW!}CG^h>CEb#9J}J-_)>?A~TLe^c_jP0%sZ2ll zGoaymBdsq+>BGHz00=m?EXCq)p1sW1{oL#ECTzw zFfpUbc$m2CW;HQGq$x8#r6&r%J)fSGt0z-glxGSs{sXuJkUm}fgJl5gKby|_(;q*i zPx^lfJ~n-*pYF#eIN(^>yNgNxlFGj?|AHy~d)1&`g;*|nD0NT``RId(PJz*b&rSC8 zY<-4Aj`Diz6ywrbUvn-suJ#~x`B$k}kRwpDIk?NsXT-H+tQDr=Gu0|iyFvV_+kYje zuU=KxR<;hd_N_FhT)8D$&~JkBVG{SPU3yvh7$W_THbp9!D14%ZA)#~TnWHtNxqMBJ zH0l4biL0`S`^C^N_uC3dd0=^y*Rin~1tx_5h0EU=qB52p&VRz3sLGBLey(uozsjaR zs`?5KQQuHu?U?B9eChmXK@<FRh(eHyGbW~q*DzB2#(HIFkL<}sdB#c`D3 z5dFR7?PO)^ZMH%P!wR0!A6(7%S{P!`9>o3MW&vZzt&&l-?`!88aHhshWO~rHx6uAP zeQB^cnv~;6y}LP8|5BCkADgi$bs~?zwMBM9YyS4{Qgu%Uzt?Qgn$vDGu@69Y-71^)hRRLA zYP09-C>`hJ~lStOjZ{oq*|mO4W#x7b#;u(NyXsir;!h~)iKifv@J?alCV78K3vQw?x8 zo$cZT^#38Dy{5#DvCzD3N0=Rwc#NRnpWnTv!3V0EEU{t7b1is+FU}Xy4=8h5xtHKS zDkw4Q?P5!wAhCR7*UMOS3eB(jKG!k`a!1z}u?Iw(=A(=KmeP;*wczIOkHWNr_TTId zBgBf~0kAgD@)qAx0*25+dIZ4>~_!)emgLf|KrIT`2Y+krTJva=s#}0vKdC9Nkurvo)|L3CcO+ z_oQ)xR)taBk1+1V$hb{m9A);tfs<>2*WG)5gfqDLoWSbQR`Ffm*G$m@LYOsxnyE}d zpzxQ9ZezPH>^jP~5me12+cqjSP>nhnmDkAw)OOiAah)$u+^gQ{6Gb7;_GBfhv z%go3*Y(w-7P>cIbK0Y*B?2!Mi51vcFDnJC{Ixx|+#;6AE8Bngj;*yU~HL1;yr-srf z!SBq~m%B)=cCPDrNm_Kbb1nEFe6Ti|Pa?Uqt`^Hwb1-%6|6=~164d+c@2L&?XQ#Zx zT!FdI2bP`V=q>o0T#5vQKxn_ji!~OxkSXU0>}BReU=SEnN3A%c5CY2{f5C`rA{a6R z@e)^E?C?zFk{}3DfwLGs5Q)ib-cNG;!-WH%7l3u`q|6O)Smo=B-@Sl?bq*qC_cR{_ z_R=!P0~~&DaO0z&H^7|0Z~9&2_is}(C(*Q58@-u9X?W&m1KpgJ+53I@uqX3DQ|k3V zEy}<|M%ySe+_YxW(}$VOnP-=`7G8m@#bDD-3E(OJxkTxDs96it0bWn7)H+pHmP!21 z_P)e2m#8jB*O&OLZct{V$<#>Dq>tTw?#YdRg&K%{@CD;r7;+KH_YC zS!OtJH;pJgPP35d%vQ6@$L}&F8d>EX?t$jfn$epxw9>o{S_wSiXvHs`Q;+!f_^Fxc zyRdIe>VNBa`VN{vX_$pH1-5C?F_TcjUa{rJ(}X9T*H@4Lc&t?A!=4mf=H!unfs zLMTxG_G#2_2#!9Mbu3sc-{E_(ud6`ibQ;eHa* zazD2-AFY{V^Ih!rtHpB6f5~Jw`YN6s7vR9?X!@uM%`aHbi?0Bx!VC4`*m1xk$=g`H zJx{D8rv^k9(n7MO)t=G`kxrOY+c?i6SGs{Hu>Sh&AzpUjL3@avD9PQQ;^5Sa0>2=25euX$uH@ZMoeT{%)QGD}ip?xnkojpSiJ$P+uy1u5mR! z5JW-cOBFWa%w>76{8qyf&tt=Eum)I_e$@V$oq{PJDpK(5k-s!8>pgWgyw-dJ zP^AX?T-V~4^qUIJeNb~B%$!DHB!v&m80G?ftcH&A%&$N(4HRrA4s3?onbr%4+405r zJMkd;5C)m!ZO3Mm2l1{-6#icHckyF_lBFQI;*+h&tf6Xwr|AE;{%fsF$kcD?`@@x= zum76=Mg8**>VLfWM7o>h&xe?rLegQMnW=dpGd09MjKG{=+3VyJp>gF7cw^s-Sv#eG z{pHkxK3?-h{2{O;DIDrQhX9WiDE>cvqVW=lhBz_rUE`wTD3|!vuL1wWvd0;5y{9r_;X!`YhH4w zkvRVUw(CDwmEoac2qjxZpTdb~&2L|X83j5;%tShQRBw8W7Z;F8MCJTt{y>6RYKbk2 zMv2lF`Rc_OK9Qu!`WK2l#V7G!(FnUEU1}Vez6hCMmi(~u{RU=-! z+~v?a*9Xsasq^@ORn_P>HHV=xfJfv$0e|8C$5-Jp=EKQQp7f@^nRMgFx^&R|v3{)- z42Dyk`963HpVg&vu>EMwXDHp=-)p&AnrHL9-(=#EIrSsUp0OR2X|3L(2AJ0pEpRKT zoXNFJ6xMmnq=Q%|^~MWVP_LyxO5dS2&ZG^8uy)tFZ`!G?$c$iUs=Fw4$|1)0f8F>( zn%^q%m@4@{c=1@5?H9~7@c8s185nT)iKtoF5u{7oN2=}Cv2>sC=Z(Xd8opa*Wa-ab zGnyo+!*V^-I(&@y6D)a~?kXI^Vli~jeSoeZS88@;9*LHYXo*`j1C+e5HqPq*uK%#82Q(>^v4=o_daJF+5J~S@A{ZhNH#g zI+wZ-T&wcP52dyOGat^tMk7?j|(E<)OD@x1t5YEEpVLi#f#vrvlg z)AnophgC}K>|Hd5bAW{QdQmeL^s0B@wT|F0#nVNNww@(6Yy5|H5Y$AB98g0m3vkF* zhu!lon<-{rBe5mQi<^}0tV|UD2o(|gwEAglghMbl4Zy|qC24C;T$Ildhq+iEminJ< zmDOA39p=SGecU$za2Ruu$Kiub{9&@6l|_CG5HxKsK|Br@0d0wSB;>Oct4E}C)kz;g z9rTpUIYyt~&CVpZ9qf}Wm)j0D>9&K?=~pV2xfdV4S-jv_|Aec*tsB3yJC7-1*_7en z$9dJYW%J9D%PyJOOZ>R@{rU5;>(K}Et`H#_>J8a!3e5Geu zl`z>(5~scrtMtI z)Q3Ih1>ThL5ng-RSMk^HO_%=|t=adCMylSdLgQnk8%eUg(F31+nYC4kT6TD^e}$ADREsfdfQ_r`CZw~YfpRLH?mzR@*kr$H)gwXx$8;^ zNwzC`peyI8E31L_<8CSUa@sfu@I zoxeU<8vMs-&D&24EJJ`tBj2==ZEB)r%d1q$%>o>pLf5aam+x&xkBSHXE$^-UEhCV&0rjsF;}dH26Fquboj+>bT53*OR!GG_aIT+h7u@)OXEop1cJsH#VjK;@18>s zrT(R^&bTV|;~SY5N52CHSo)nU`Pn4-*(CXsTnan(L;U3BwMVKq&-<2YpCfmsWbf@o z4Afq|gvq0!y(W*#VC8KD4{bB+IW?^I=SW(@v-#FnlNVoFq)}-Z5s4@Bc-H0~_NY}Q z_WMG%zxSj|G^i$|=WK2!?25$F_AozvVzX*_l3(bPt+Lj$!qvM7Vh{;j$j^KA<9^TW zd)z0tyFT#PgUZI$&Fk4;d^a5XLu4F*4&IFfrlixqBuoXv-W>^aFV{d74narSIMA}> zdrY9lQK?`EEhj1%f|pF1Z~x4xC=808OFV|O{bfTU;63wFB=)D;RjSmyrwXi|P`!2j zP;VUfJVeUpKzif0+9x?#Emq%%0FH$w1sipds7 zh#l=8J)%C@3Al}0Q?Uye&%&Nh$+(>(?(>W-(_}?I&2KrPw*6_Vs5BRadoC#XBiqD% zV9pVO4^{gJeMtfn$Jllv?Gw~fyK?OnJj{%@=3z5L%+>Nny4;``IZdxT$O(;smD zad`1;<(-2drB7aL4-b@~QjQ|yTCBx~O-oEzEBj{sIATD3T92l(MA^fHwCnzBvDL4u zKME}Q8ZCoI%Qe>$wG%$++n>%{&sa&GaD2kY9mKoX?8h0Xk3C1Mg96+iwDl6WL-%3T zCw`O%#ehiR?tfrZee0q``C;{mhs*QwxEO2i9|(}ZYfSfw)W>>s(OiA?v-1n;V zMXdD#-NSk}IcM1Wc<<*7yO*kP> zstGB6QW|6DRd|>?JdecPX1h);&$~yr-&pU)+L!)Z+wofSD;FouO^5Se%px!REgS#l zLfW_}{uKL?!MrK)E3KnfS#7lYvnkb^n~SC>w%exkH4cedj?Uhbd_x4}(LKpRseJi^ zmEi*RS#9s8Iu0{T2|RW&w|3s!Jq4e6*sX)Gf5ErC$4L-(l}BV|C!e!;37r~+w+-R= z#X-GQFaiG_+7&1sq0(hsY@&lfOhg0wAKH63njHv5 zi}M0g4(K*Z(Ti075FQ%?kE`9gwT`e1ejmj(X`kc9A~w(zLE=+f+^0B%2khA=JAb=1 zb)$Hw9|XkON3Y>*3c`Y`?o6e9-01u=3Tohg{xz89EK;<7_!7T4D+LYPE|35KZm;fc zwd*J3GEVigOoI%nr)~|D>VfI{Ow`HWT^eb>^RaTi{aSXJt%ox5Kpt%Bplf_Z5BBIR zTHFpLXxl;bPFDcyQlUQ+QKC<*h_(2Ou@+C9dC*#16mE_3^?}E|>zG{@wO<2+$AA!A zXU?t2@kX47-@z4iqxm*^mUT2s7n1W{4Ek(jY?yQ%vqUYqXTSR&ckL4^^s7umJH|}@ zaxR#(ur8D9&M_(C3}t`=j0B(77GM+VTia`s1P5hX(HJ(+E%YmK+$xHfwuN>0rFnR~ zbS_VvkJ|3GU)*}%6kFFBYfWXDuLj3(aq$yczF2APtd4HQ?$-YY#ukV@u zm9@(LNGEOp$mmX-bZ9<&e6RVMtyLeRih`Udd{T!4&SkR9plAE7I0Y56oo!6P5sMIu zPz#XskDjMyW-ep3vRawMT)&%$BZ+~>>AFYu&b0EJcXOC?oTxIo?okmR59=5(HTKkY zagO@LzYB1gG7j!{dHGEir0%xch_R`f=}oV0a7H z#kR9d4lKD9Fln?a?Pv!jy=VA>3=!6oYu>6!a2WdfQSpRl20P$a&jXgIPO zASfbOZ$Y?vM{VHyYpu8PTLd{PA67erwHSWjxS%CI!6s_w*%F{r3D9z3QEFJznQ=TdiLba$ zI)D$VKcD@1He$}K%$G8TD-9xF)m(iu(>3^J|Shx~yu+pWl&c1q2|FnQ-r`z?06``IV} zx$LWz#q2(d5x^2z`z}?TfDQi@TdzJsV4!lx=1Ntpz!mf&sbC`uH+wy{&JeYvJ1n;_ z>)6+{h|#p!vP+v>u4ALKo%G!p9EEcG55oNiYUF z|4a`1!l?GMcu$;9V#r|{unW<83&HXP zq%gV^WF$-pWon&Btya`4OQr3iMiO)ts49fsdD*}hu?vt(1kdBTgW#;53!2cFFSr(? z&;_%BkJjRg+BRH(Sn9bzMiu+POL~bbW@=JB?pauZ-(!y(C1>QXWUmCLtYMnEAo46f zP1pe*m4P`^OK-V0wDm*FzjWgRxvwTn;G`Dim;#h-r30NP0u zZ@Fg(zQePY{^XF#tw@yt(75#-txv4Sj3LaXw@=Yo@YLQDqgH z=tAHl46|%zAlp|nTs*NN24C^WRe>a$kBBg5#O+BG{)JVL`LtQUE8HgsqF=I8;rbcdtU^WJ-kthw zDAG{`wa00S`NwrwY{lQ$rj?}65H#FNS^D_)eFKEdnJ*RTlJ;CuqoEGg8JYRz>-C(f^LS)=~|&^Lu5aLkf|P}eKxxvD&kdt+ER*P4s!jT-p6-IKL0`) z<4bItVOTnb6P zEMWCP>bFLbYW)hX_fviU?I7MnmgqO3I0lsHoISkXbm47!m=!CN1{0O%O^YC2v z*@2U);ddNT7Hx*i9nw(Zr7N*Q;2^r%{y@Q6W`@FvQQXXcQ>u-)0&YCs4i(`&N|+8l zSMMa$7D-e%Ugww1H9zj{wZ{c>2b&=a@rRRg=^-`zAUm5~{{W+0-46M-5W4DH6Bb`# z(arAs+clp?!kQ1-W6gJe`R52cqqp@DsQK-Qx&27r(WhUQv|dd6An^@CSp8w8W#>w~ z#D(E6OL9I*BHYd(&9kcd5uI}KJ!me!SBWYcU0=D*{FE-GA664~{d9T%@v$5NUE%a< zq*7R$yU*b=)N5XK<^f>8h znfiw?^*;|LoLg*P_TFUdBD?E?1JXye6V|5lW~!MLUC>0A{*6bnDi{S?3Br->H@1ig z-Iu8O!zxE90V^~08DKTYQFOG}R#h`sg%qwNlfv??`j)y;xLU3PH{2*aCQ?3HV)CR} zNkkWNMb>Z^=hG`mSM_@@OIJu-_Rmz2K2j1B3sX+XAZ=W(Hj2J2P$+&D3b$BcBP;$O z3w=268=OpG^kzLGC#g)01TmaBe%F#?57MuX_u_7yVwW$s9y#wqFLvizxAw3J>C-50 zb=PE@7AvPF-I~R{#gk2T1%p52Qu_q*hCnNCos(|^PqEVPZn?#c13Ao>|H}fYG5g_o zeUPPz={0{x$i}BNO6RSNw+m$ia46|g#)PJ6M!aB)e=vdiMyb9N@aRzg8qMpk*rbue zNn)J?eEg)KcnNoG$&G-+kVc@%6E}yu`}*)IEpZhH~<~ zR>*%4kC|5D?E4#AB3^ZwVqM|&R>am>d>YS3;!5n&8;j(s$hVkRltu?D$h^QN&*5BU z30-Bt8Qvqf!&ngZnhdaNa!{Y({HlU=s);>k$60j|<2+puSuPL*u`+Yl|6}b;;G?Xr z{+~bsVTltI5ESb~Vw<=IMN5=ufwZOZ3qtkf1{F~_y^m<590h- zFETGLs~#)YJiL8TTtO6w#(}s3b#YxCA)YSDOXgT7XzmJ&auHYx-MarG##%s`Q*6V2hb(mSN*JJ(H0!zQi(NVTpugKc0Kd11xK!q6}y}cm4f5Up)evVVn!-8h*-3 zKE;kVB)aCD{_J6DVT?{>CW-INrBMtN@VT_)7SA0~3CPC^I*TGSodxVLv;5eq@qnu>z#gvOc!5X@$Rl((6> z5Fn^8^VGd_ms&E*KZFUx!>f~ zLicwbOsfVW#i3-F|I1-M%P=?mPX;D6Lx-7rkLZq0J0}w__$<}oZ@;9!9(xo+ZhR2H z;>piOe2btj_1Z z%5#c;v-bI$aq+=ha6eaD*vq+c74j+eoxtk)iT9KOL4^j7YBvfz{KRv%bOUc>ckm?N z`ta$@2=L{l;k%3vl3%t8&RBjG@MtY@u&`4GGx#JE7Cxq6VfA7EcGL#&ca{&$Yd$pT zQgi#*^lx}2dsFp9Mq4Nb6J2m>LCSuHEdQWr*&a;cz)wcIj8CdfA^&t3ui9Y^7`@B# zSAQ_=&~UrgM*lq!!5E?rm!>-0biY1`p6KmGnhD4&=&}>_xFp*S(8;3fqVkI z=S4(>6Xc8TZLw(XKpt(GeWK_u?4U~Z>sE%v#pc+o9IyI0m``1`wsw1o=bolnfK3qj z;!%OR<5>}cIYY7p0Tb=ZiM+U{k?E)5Jh>IteE)ENrX=3>#XZfBxkoWKU=%Z9NUWXQ zZ$zS+PMxBGQ<+m!MUw~NPZoC>b%RKCJnG0bIaWrB+rB*$9F29aV0 z0@-pUhveF0UXh|M6qxnz1uU?oUqqP;XyJDu+Uux{OgtVN@kRQ!gQ}-(v zpZV<&Iuh#M5eL7*r2v0WV~9MWKd~W&^As*JvUf;e$$hGr6|Yn`a_zonp!4)wT7aHo zJ^l1xMhzDsN$ZI>+Y7ne%CV(dK=Ij>9;2uH%{LPr6BYy8|6v0?jg8P2oe!$Vt6J5XHm2Bu z@`kUp^W5ur(<>xC(Hb&juM$f3QO?YDg-<<>!d6IFL}7*@2>z9IV+()UU8c{^CKK9e zN`B`^ftwvx{&XwKxr64F|I>y4=_s>BjWi;J&cZyx zd>Bk<)gO1ijf{R5%QC8)$rzlV4p@XOjuj;-_Pa)qOF@rP+<2ik8IDEq$Fcr+B zFY0o`Wozd44M!KMfKHSWio-XUF_r_5#_M^g`c>hT{ctH+=CG{W2l4lP2nOolEW}th z>TBR8U5fmQNlLe7@ueE=Zr6GdB^ffP(Y<7hz3srg%A(yFYau5>r51TFS;eJLE4dU( zHj|^NujO50uFGyR6(^i$vxGfllvyXLDFlyjd>k%0l-80q3r=V23zfCanaiz$Y%b@g zS6J;Y2N}!A9TwSjMPnw!Ze7`c7uZVT<2NvWJL?w;9i>7{trxpjv<_($_~XAd-_1|E zPStu#5bbPdsY$SxCMub3a*AnG1KiAIJ%aEty+ZF0@pOoIhNP4!GO-ThEBC|so5?|5 z?q^yZKw$3-I*`Dg%#>Umo9*Vm*MxE5fAQbL;D;#*5*bdQHY8~NHL_Qgy*cIHCf_=! zL9fjuhE~uyE*`pa#s9S%l%UT0Xr^8;9N?mNNb=IR;%!1YtH+1`0 zIQp>l7)sRV2qQ$Dh}BLf&JA~jRj_}**NqQapS@UYGj&)KmWK!4L%d9gh1(jMvb$X^ z6wW4=YpW?_OH7nGMjl^+7D5XwUM-s&7fq?C7bQY5E?X;kCK~*#aBT8)MXqV&J?;P1 z7FgJ%GSF10Y*k<(LGrUgC2gV3R;=kdaS>|S%^~lV;q2DxXj`acgKjQU2pU1!jCVcz zw~6CbgDx<+Pqd08XnI>c)k5b3lLo{gD)D_~jd`G>X1b1PFTRiuIB75f!c7y^14#-$ z$1Aru!dK#B(8;O~)ll&ca0q$2XeAYJtvdHUolC#nklL0uGGG&IxieA{~tbtVz;hkrDW%#Syx(gnCe1k>%~w^o*>bI$ zRbBEzbqQ^35ADJcS!5&k(`^&Ei$oERo*FLrEaOfMOn74+8udnXp*BR&yJIGSyii$7 zU0^~qXO&fcn-hHjRtKlPmH3hc1{V|)Vv*<9kMFb3zO4&K-!xCy$5!Ln-?nEpvCNtN z$5Z+B7+T>64ITn(z!1uw9gURf1cS$V)cu+8gS#Wu^W?_2yO6m*Eo^33@b&UPrmxVmm@~B9sF!POz`1!NQLHQ zUV8F!8-`QHp+XZFcmP+o;jZL7S(q4gunklvKb$7^5_zFf@QN(8?GA|%m23%*dAWL9K`s%ev>a9gs^Av58fWm-lz+ITRs|^aRuXL^m)O1?n*}P zmMmKnXnKlDn!(`6ZtJT>WgyZ7f6}Cy?oI+QBWkn)c&zNLKx=&wLJQK=rK}Z%YE6JHON?lzuV;g!7M#V2R`AnhU6hE?q11r^F zS)Q}!i#-#00^iDyWqapvbr2GttbUeR1QyPO zZW1yGHVg7vu@j$<+(3hZ(hj$%$4YbWVH1H@10{a16_#h$ga`|2QH!hb;Xb&TgROi2 z+(?_DzT`&+?5ET-)ZXjoCfy|kKD#lKc}gR094|fRqKW4nFas0!9eiiQ$yaXv{fNFY zEWEI`L?$vZBRxd3E%kQHW!S;Q)X*MP>5LWl9|$^{H*9fI}q6*nHhnMo|)x+yLT#6{|j^SK`hoC z@pzhj3q-_WfUP4Q)~z${|H43m_WOfH#r!tO>*{&mQ~$K11WEMi)aysryVo7y#b%=m zS#03nsrt$0Uj6L6%f?F}@eTgXSsV@dmU#3wiifyuOB2GjotE1^Ny$IR61jo+A(Rhu zX%tX!ZDni73K$!32xSqhl=psCsN?PG!dJub6DN{qa_rW>XQ2v)3pY%T51hu5-de!g z+BzXV@R$&>RTuuGKYKrxzjO99uw)6Zo_{hxOly|N6+U~~SyVPDcEamUNLU#z*&wj( z>Z3F7MC}O`Zm7;~=kSUY8x~;}|1MoDl)cwV67N?Rt`c-~Q)O{Pt?w6(U(w08Wbg5# z-qv9g;X*KM;#cy-49VcT?aRYOjrMmtp>lQP-72y~H|FOLq4St(rN_o=za59zAC>ilLe+b`j9oYO~PUtWE9w<%q)QC|M@7%q9)`uy@u9 zke+46kdy+;9Pd(VJ|Z<&sYlpUv|Lm0j4inS1HYi<|NDNg!rCO*`Ls=btSeda$5ubR z!nC{eXlD8f(#=qyHFy2imYAzlKV_OijJCRRY9q60&^$qY1p*zB{%P zihib0=`&z>)z|jRN}SBlPmGVn10%(jed~r_5BZKI-&a*90ez{hUR;d%tT9b&k#dmg zvhE>G$!Z<%dW9RoPAX?OQ1#K*wEWmL2ew=t-6Bzcn;I?a2rOPEdUN`X4aFK4Z={C} zqEUyxknH>V*I2#i)yh8zzYO=6T!{RpE<|<+A6bp(TFd*~iEQTtiSL~qj&7`u?hWDN z6F==}!2+*F+GCG~VwQpE;`H~A^UK(vx8@5O)9%twNsul^WY;gV!cQ+YPl9L4U!Ph20YAOe+~v|IW~R^c)5n+_ zNjES3hCgco*Nk&8k0bz`gL#V0>A0_{a==`(gH#rM_=lgWIby!)n)=E6q%!NX%n(1d zQ7?IvHCNJ*^uuXtCQWFK)`ZBa)J8_jA6NX^_Uev)DdXAt-?;+Hf&O)*1LRR*rH^WV z)KAw+OZo%q)fbQPXQygP<2?V0t0Y_v#E<=sqLt*uclnho^=UBc$lW%AzTi94wSTQP zSB_Hs6a4yBhWgKR3&rDFD26EgI6ob}VBr&Mo~!n6q$XTTzYBs0G4j+E{j3LN#&U<) z@0&dQRdhmZ;Oi*>&8*Kgg?wn4|NbnZgK+M5Sy-R9;)U1oo>%yq7a#cTlr2{4D;n*= z*H`47T5}=Tf_ARklN#)+gjOF}=3>{!qu(W!sl@)UpDG*+qGtWZ2P4q8nd4mM$?uWb zE`Y;rX7mXYaEs2mcl>&U-+h2D`mQlM|3{VNKGv0L>EBPUHSI1vnwh?WbTd@o1FeOl zbEQBM!?XMsgU@0M=G~U*d9e|UFPpd=ErLC}6$>`tE!xG|Z^s5U!Fu2Ax)*(fJFg6H zcPoW1O-Er4M_;avf>zh8wX0h*{ha>j0Ku#TuE=;ae+0+2#S+>epns*G)B6Goo%*-p zPAz!bWZR$B+pemnI7ey>C!B2m`Pfa3F)!|O2lMl!3l}sej{M5d$5w%H`inMe(O=+G za-%|jL7SXF4TDk=7|G~|@v+1Rd2RMdVL}6j;{$tlnFx?^IZlT4Y&L;FxjG=HH;Now zt1>TnOjj<{$llf2Z5ZNb6GeyENYsh`Xx$#1=ct6OpmbxzuFHxlWIuVtj`|TPteE#j zBoc^R|Ic)zK2Y&A7WGniBy8 zgfuUEzg0tU%+B7MJll-h+1aW4VOQ3lD7nEy4$3AvaxDMme-oFMUBm4!%JCdEVJ6FP zxQ zzYJclDC z5ekbBB&hu=!jR0x9%Od{ZOAKaNDUqyj*l2#9iPTE1P^6lR;kY37J6RxNw@j*W_8&r z4avPqW6wI*{Wwxl9{@ajj$Fow3{K7gTBNe@aH?X zFA*g;aTs$YZ_cSQb)(J8Mq)R|Q4m7AHdGf5-oa{<+NN9qRy28Pm^`(T5Zs;LIbZf- z4f1V}yZ+&L8XXh9WrR&WZ_QDl&TLkyn`z-SJq+pboIz%|MUVJC7ujeQQjK-4!wvoo ztq*XuZsx_=PbJTD(*Uy~{!tp9Imgp7bz{=#GAYWM2t2H36S6TP{ur80Tm->5tKd06 z<(|qceAvze>N8oVfps3pSnt;kUA%_MyMuUsD zk<}LtwQ|2*^?lwsQuY~NYhZi2<)gIl&|**xEKhxwDzcK_5eV10#&b7{y|yY=gIM_aVktIlo-m%SVcjN2J1`y>=N?-OlT71-^n zb=B^EB(Lnn`4hsjnMrDyLtqKXCQebQv_=pcLDG+@0;jKzc63*HT9SZkMWw{~;MQ6* zg9ORzQkRnuxK)pQIR{a62;toQPO=krT&N!$Wu=JBIdq7DZZ-?|G7|pzjS0eLn+nXe)zF^?~uLtbH8+pWEz#o>Cp?sjz8KiG3TRH;qZL_(_Ef7>#@(#!VPP3r>y~ zP18BO~FZ|0GZH8~o7vjElm%}Dud078GL?>9Mm!kdYs0HQjYFx6l5a`)T{o3og* z4e~5FYbYYgv6MGAAQm|CHb2|xCT(8g-meis@8HeBKO}7?&@DTOLIDD^u#Us?ISgw4s2qI^Yi!xGwPxc+)yXYp zVtD#Tu9z+A8yq-qcYF?o+)lJ&W>DB|_OrmG+>qML(Bo7!Ha18hpR?)R;IjmAz1AlU zfs}+N)KKg}+adHv?drtxKf^T$4e&$#AVAn<815APG^CBbJ(ZnpVha^0IU!jtSZ^tH z>&5~^hK;yxZ@TReuWVmn$tkv>%QogU+gOdU@~RuHBkRUI<{-OldpX4D74GKxw=LB= zuUELYT0xOMg8p?!-Q;)SoW}g*LGHOGuh&0nk+InXb&wY zXc~bg)bdu&#Mp=d6Jxgy$b*dov=?{u*11uqbLkB=L+enUdE}dd-y+0yMyJu;iE1{^ zGMX)GyX}fVq>M(@Ua4AU)5tYSCvzsmM&wP3RpqHs1c!q)N`8FHOli+XY0*Cg@1;~# zT8R%l9Q+ipNYCxZD!7`ngGquut!5GmSxqA#XU(S>)=sEJx>kAnG>1y|$(+u0rFQdi zH?c6~%oC1oHJ=leM2p3AtmUc7Sp|hX%L}r=e~Ks)^R1oBpEe6#c!(O%>f6n~f35`;M~8N^lt&%+Z;}2xj~6ZA z(YNm))l)PZ(6DI#L!V7_Tl?O_Ug>Kq(jVuZ+e3E*J;ON8RUjcdh*6$( z^Nh~dgkRn`TR?BD&`kV!Xb(=6QvOm}lHYn2a83K*fcBF=>{69z8C7v6D6)s2jO+PC~n=V30lmIDCp1t((i)-<%_w z30izOL$AsrihlxM-~B0~LavbX5l=SkNg4pBKgUVz2?;08*}s)z_?5(-$gZE{1)l%J zi|ofN!^UL;$l2-6_+gq36>bXcY6}zoh&wsLg%t%}$H!jbJ}>eXJ1B}ckY`mNZGZTH ztv2J-X8JX)bXc&F(^9B3&n3GfFfoypA`N{iehb&x2>xIpdD&~< zu45^SzL@(>uWaWWf`q^3b-XW2688Exo~r6<86|TBG)Rod|pF9=2X#rf?URFy`L}@ z!B2L}KJfmR%v}3zy(TZ8*E&YFYok{ z`x%JaaL`rK={E_7KTr5$4d4$!$s-MUSg^&lkd0L?E6o^fYN&D2HQdm(* zdO64YC3&!35v56$MmU=25e&CFx*cps_D|og72u5|{OySO!e74c)^)<*9XAp}+tkX^(hgmr9vx3~5utRLP%_=$8zI>$r z!KNO<3oIo?BI1wx26opC5+C?_Z)%EV=)coNAGM+njvjmeclMisNDe8xj5W$kw4y{+ z(F|E;wD2urm%=~e`ArlENQCi6PzW?Nl7J&{*J6|nqtX8G$gch2kD(9gr85|T*U+R8 zP~`8E_O}hkb504dd|RUeiRLg@e`Gi0@+%4h#!8qN5|H)Fg}}11b~7~xuS&d6`v~gW zCdx3Q^)-5rhRFsIV=;ifYoYJytEsk|1?gNt1PxUH(QZV4T!l0DtVzSwH|G?|9bPw! zmOWU8Mq$TqANvc=zVwc;;1Tno#q{Yme+2(Z0T_96B~~ZQKKUA`*i zOYP8p+rFTLwU`rlbQEq1wTTNvd5LfLAnFux^P9QqLDiVnI1kkgzx%-NI*Z>u*>%&w z7M}fcF%9bwJaNCuUgvy7WIvhyQ<+!<)~n>@kQ5y!S32k z)L~bQexo-DEpFih_I7K`NR>~gcx!XoY{haf{ABhHPTHSs{kPmsi6t7Z<1I8h+U%t5 z9bL7`mSJVRd`Tnl3cXnRH~Uy#Gev@K*m>zCDI8#BZBDCeyG5p#TR&W#%Jk3S&zeTD zZ*q&*LGZ^VVZz@}55V894PK#-!i&Eag<2}V5{rH<8Hl7QVtlQ_J_ag3`WjS9RUUCL zOs>}I>SNL@v%<*b2qBhIwV5 z&KZwFx=HqRzklnJY&2s1!sutNReQkl$#mDhg0B9_L_SRGggTjgER!;}c1_@YUgwM6 zNGPLQS6;-~Ji5vBqjp;jT|!vMfY+afi%mD;xtSNovbr=E^TIZAhzJUod7v*g7XNn%x1ex!MUtq}&#w&!{_sjDdlS-ZXDCqBhSMw7 zHBJovq0?KtRx>;tsCuP26u*RMS6h=$Ql6Z37lBYNe*6^LI%|&38D7xEALafhgPFh6 z#!ll`7|c>Tk}Yo?=k;SOcC7Xki@HK?)2pqQoB%(^0WMf8?fQZpuq715j@5!r5ssgi z9a^-zuFVQwq3Dk01RL)NJZqAF(4Xb{^Hkc1_x}JBAs%rT@uK^~(f5*<;(>=o5Q_eT zwnP2?5sKFp(f()kdC9v-;yV$wL%UuL1)l#0=-eZlM8`+y4g0&^LeOOVn(XkRck6$i z_%|@@t0L$j&m(_H6}eBoHFU1u8{znO$@xb8)xw~;!Q2clXMeYm|3 zedMNq`FG7jW`#GCLw^puzX0o7*7em=Q!(}hdJ+DjA`;JxE2x=@nZokz+chS#XjEAVV zV)n(Mz#n$_wC)9}(52Tv>aW|7njr$(hf3J@Zo@HbwYPSq!w8R7dkjZkk@on6hU~vX z8tRWjg?p+AK=DR$sme0haVzXduZ=>4`k(d-_1op(awoQtMtULE2{V6-rzXVX99%zl zch>hO`sm+$`IqCP^@Vb2-_=IvS5{g@mCh4i(MQebY?+TVNf_4p(R47y6X@XjW_H?b z$1t~JKgi~eXF3d#GtfGXVDIXIfY((nuK)@V1-<4BVncLpNc0J7pEHU&+d~c?WN5=` z)#lfEsI42Oh`L{4qCx+j#sTjhjJCUd z#)JHxE~P;>T8R@>f@hHGbsIo>0SD5)l%Qv zhH;oBT5Hf?pd0xoFsunSQeJmMKRo2GUcP(x5TvoAzW;r&AAMD~Rs9&e+x-nMnmd_X zI%iydE)Qm%C@xZ7rlQS(rt8%D@(sfBEE!vuiX^0;5nSAXBIoFJ$)m%u!R?5y z)!FNK%+KcR< z4&Y5nLNy8=EymCDUBEMr{k=cj&h}K$- zdYtTC9Xk{U$3TkZ zjt&-aacX!gduA__NHEtj;lumi@S%;TQu(h|$hI=W2EkUr3K5%A$ggQ0--P|(b>PB6 zB16p`cxyLvBC$Ble+87)?~rk8h?D09!W)@jkSrl*(GNbY!zw6-({&5n+V>oxqCi_j zCX@u)Y}CHcOb@z2UwKkfX#E|dQ@(}%a|zO|3c8@InR zmVY6y?7pvf?9oRb<-m*$OIj|I_}?#_~-UQZpCLo(TMFa@X_bB4(76&FnrWqlv_;H1SKH z!#Vzs54-peIF|qi4;>cEUq~g)GaSu^+|Fa7QF$=U6kzr+i#SX7tU3#o;dT8uqClcB zK9IRv!sDB{ka)Nt=w(BC;eujLBJlvz>>Vy(&hfz4F?=1yo^C;qiqY_^3W`$?rKyK8 z_JQ%H#FRYrF+~=cq6!=&HYA5SK=x>JB;UCHg~zJ+ zgkF`;3F*~=$J?DuU&sBXm8&q3p&JZ-8LnU@c*i+Zo z5w7J||JajdCkx>3F0x5%p*t+xT~wp2VsA=RelPB4iViL^SGFIpYv&_!!3)Cg>gR&g zi~la`H(0c@5KYotzoGkFZca=)=(a$5{OtTIfi}CZ?=dccj*ZK+^Y4LY95uMr-OL26 z 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

!KeL;T0`mHG(t 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 ?Mn&jw~`7a;9p;ANR&ixFRgK>3}7m{*7} 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ΠHcAY${9) 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%0AWsK%`mhSn9IG6Ky>s91hq-G0t}`}+z8ksK$fd-w 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 From 57ce0b3d514373a07a08dc8be3fdc436d068477f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 5 Feb 2026 22:28:54 +0000 Subject: [PATCH 006/226] Accept data flow consistency result --- .../dataflow/VarArgs/CONSISTENCY/DataFlowConsistency.expected | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/VarArgs/CONSISTENCY/DataFlowConsistency.expected diff --git a/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/CONSISTENCY/DataFlowConsistency.expected b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/CONSISTENCY/DataFlowConsistency.expected new file mode 100644 index 00000000000..95848ba942a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/VarArgs/CONSISTENCY/DataFlowConsistency.expected @@ -0,0 +1,2 @@ +reverseRead +| main.go:23:3:23:5 | out | Origin of readStep is missing a PostUpdateNode. | From c3bafacf812af60ab8caeeda352db6bbb00f032d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:15:15 +0000 Subject: [PATCH 007/226] Initial plan From f7cf24d1f930816e127ccdf15ece528ef8986fe8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:17:57 +0000 Subject: [PATCH 008/226] Add Go version update workflow Co-authored-by: mbg <278086+mbg@users.noreply.github.com> --- .github/workflows/go-version-update.yml | 176 ++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 .github/workflows/go-version-update.yml diff --git a/.github/workflows/go-version-update.yml b/.github/workflows/go-version-update.yml new file mode 100644 index 00000000000..74eb24e8ec3 --- /dev/null +++ b/.github/workflows/go-version-update.yml @@ -0,0 +1,176 @@ +name: Update Go version + +on: + workflow_dispatch: + schedule: + - cron: "0 3 * * 1" # Run weekly on Monday at 3 AM UTC + +permissions: + contents: write + pull-requests: write + +jobs: + update-go-version: + name: Check and update Go version + if: github.repository == 'github/codeql' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Set up Git + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Fetch latest Go version + id: fetch-version + run: | + LATEST_GO_VERSION=$(curl -s https://go.dev/dl/\?mode\=json | jq -r '.[0].version') + echo "Latest Go version from go.dev: $LATEST_GO_VERSION" + echo "version=$LATEST_GO_VERSION" >> $GITHUB_OUTPUT + + # Extract version numbers (e.g., go1.26.0 -> 1.26.0) + LATEST_VERSION_NUM=$(echo $LATEST_GO_VERSION | sed 's/^go//') + echo "version_num=$LATEST_VERSION_NUM" >> $GITHUB_OUTPUT + + # Extract major.minor version (e.g., 1.26.0 -> 1.26) + LATEST_MAJOR_MINOR=$(echo $LATEST_VERSION_NUM | grep -oP '^\d+\.\d+') + echo "major_minor=$LATEST_MAJOR_MINOR" >> $GITHUB_OUTPUT + + - name: Check current Go version + id: current-version + run: | + CURRENT_VERSION=$(grep -oP 'go_sdk.download\(version = "\K[^"]+' MODULE.bazel) + echo "Current Go version in MODULE.bazel: $CURRENT_VERSION" + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + + # Extract major.minor version + CURRENT_MAJOR_MINOR=$(echo $CURRENT_VERSION | grep -oP '^\d+\.\d+') + echo "major_minor=$CURRENT_MAJOR_MINOR" >> $GITHUB_OUTPUT + + - name: Compare versions + id: compare + run: | + LATEST="${{ steps.fetch-version.outputs.version_num }}" + CURRENT="${{ steps.current-version.outputs.version }}" + + echo "Latest: $LATEST" + echo "Current: $CURRENT" + + if [ "$LATEST" = "$CURRENT" ]; then + echo "Go version is up to date" + echo "needs_update=false" >> $GITHUB_OUTPUT + else + echo "Go version needs update from $CURRENT to $LATEST" + echo "needs_update=true" >> $GITHUB_OUTPUT + fi + + - name: Update Go version in files + if: steps.compare.outputs.needs_update == 'true' + run: | + LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}" + LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}" + CURRENT_VERSION="${{ steps.current-version.outputs.version }}" + CURRENT_MAJOR_MINOR="${{ steps.current-version.outputs.major_minor }}" + + echo "Updating from $CURRENT_VERSION to $LATEST_VERSION_NUM" + + # Update MODULE.bazel + sed -i "s/go_sdk.download(version = \"$CURRENT_VERSION\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel + + # Update go/extractor/go.mod + sed -i "s/^go $CURRENT_MAJOR_MINOR$/go $LATEST_MAJOR_MINOR/" go/extractor/go.mod + sed -i "s/^toolchain go$CURRENT_VERSION$/toolchain go$LATEST_VERSION_NUM/" go/extractor/go.mod + + # Update go/extractor/autobuilder/build-environment.go + sed -i "s/var maxGoVersion = util.NewSemVer(\"$CURRENT_MAJOR_MINOR\")/var maxGoVersion = util.NewSemVer(\"$LATEST_MAJOR_MINOR\")/" go/extractor/autobuilder/build-environment.go + + # Update go/actions/test/action.yml + sed -i "s/default: \"~$CURRENT_VERSION\"/default: \"~$LATEST_VERSION_NUM\"/" go/actions/test/action.yml + + # Show what changed + git diff + + - name: Check for changes + id: check-changes + if: steps.compare.outputs.needs_update == 'true' + run: | + if git diff --quiet; then + echo "No changes detected" + echo "has_changes=false" >> $GITHUB_OUTPUT + else + echo "Changes detected" + echo "has_changes=true" >> $GITHUB_OUTPUT + fi + + - name: Check for existing PR + if: steps.check-changes.outputs.has_changes == 'true' + id: check-pr + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + BRANCH_NAME="workflow/go-version-update" + PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number // ""') + + if [ -n "$PR_NUMBER" ]; then + echo "Existing PR found: #$PR_NUMBER" + echo "pr_exists=true" >> $GITHUB_OUTPUT + echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT + else + echo "No existing PR found" + echo "pr_exists=false" >> $GITHUB_OUTPUT + fi + + - name: Commit and push changes + if: steps.check-changes.outputs.has_changes == 'true' + run: | + BRANCH_NAME="workflow/go-version-update" + LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}" + LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}" + + # Create or switch to branch + git checkout -B "$BRANCH_NAME" + + # Stage and commit changes + git add MODULE.bazel go/extractor/go.mod go/extractor/autobuilder/build-environment.go go/actions/test/action.yml + git commit -m "Go: Update to $LATEST_MAJOR_MINOR" + + # Push changes + git push -f origin "$BRANCH_NAME" + + - name: Create or update PR + if: steps.check-changes.outputs.has_changes == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + BRANCH_NAME="workflow/go-version-update" + LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}" + CURRENT_MAJOR_MINOR="${{ steps.current-version.outputs.major_minor }}" + + PR_TITLE="Go: Update to $LATEST_MAJOR_MINOR" + PR_BODY="This PR updates Go from $CURRENT_MAJOR_MINOR to $LATEST_MAJOR_MINOR. + + Updated files: + - \`MODULE.bazel\` - go_sdk.download version + - \`go/extractor/go.mod\` - go directive and toolchain + - \`go/extractor/autobuilder/build-environment.go\` - maxGoVersion + - \`go/actions/test/action.yml\` - default go-test-version + + This PR was automatically created by the [Go version update workflow](.github/workflows/go-version-update.yml)." + + if [ "${{ steps.check-pr.outputs.pr_exists }}" = "true" ]; then + echo "Updating existing PR #${{ steps.check-pr.outputs.pr_number }}" + gh pr edit "${{ steps.check-pr.outputs.pr_number }}" --title "$PR_TITLE" --body "$PR_BODY" + else + echo "Creating new PR" + gh pr create \ + --title "$PR_TITLE" \ + --body "$PR_BODY" \ + --base main \ + --head "$BRANCH_NAME" \ + --label "Go" + fi From 437244fe902a4b38045b1605b922b3c8e3066d3b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:19:56 +0000 Subject: [PATCH 009/226] Fix portability issues in Go version update workflow Co-authored-by: mbg <278086+mbg@users.noreply.github.com> --- .github/workflows/go-version-update.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/go-version-update.yml b/.github/workflows/go-version-update.yml index 74eb24e8ec3..ffe41cb63ab 100644 --- a/.github/workflows/go-version-update.yml +++ b/.github/workflows/go-version-update.yml @@ -38,18 +38,18 @@ jobs: echo "version_num=$LATEST_VERSION_NUM" >> $GITHUB_OUTPUT # Extract major.minor version (e.g., 1.26.0 -> 1.26) - LATEST_MAJOR_MINOR=$(echo $LATEST_VERSION_NUM | grep -oP '^\d+\.\d+') + LATEST_MAJOR_MINOR=$(echo $LATEST_VERSION_NUM | sed -n 's/^\([0-9]\+\.[0-9]\+\).*/\1/p') echo "major_minor=$LATEST_MAJOR_MINOR" >> $GITHUB_OUTPUT - name: Check current Go version id: current-version run: | - CURRENT_VERSION=$(grep -oP 'go_sdk.download\(version = "\K[^"]+' MODULE.bazel) + CURRENT_VERSION=$(sed -n 's/.*go_sdk\.download(version = \"\([^\"]*\)\".*/\1/p' MODULE.bazel) echo "Current Go version in MODULE.bazel: $CURRENT_VERSION" echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT # Extract major.minor version - CURRENT_MAJOR_MINOR=$(echo $CURRENT_VERSION | grep -oP '^\d+\.\d+') + CURRENT_MAJOR_MINOR=$(echo $CURRENT_VERSION | sed -n 's/^\([0-9]\+\.[0-9]\+\).*/\1/p') echo "major_minor=$CURRENT_MAJOR_MINOR" >> $GITHUB_OUTPUT - name: Compare versions @@ -114,7 +114,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | BRANCH_NAME="workflow/go-version-update" - PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number // ""') + PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[]? | .number') if [ -n "$PR_NUMBER" ]; then echo "Existing PR found: #$PR_NUMBER" From 1cbd423251223ec47ea02896da8f10b4bbcd9d27 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:21:13 +0000 Subject: [PATCH 010/226] Improve portability and fix PR detection in Go version workflow Co-authored-by: mbg <278086+mbg@users.noreply.github.com> --- .github/workflows/go-version-update.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/go-version-update.yml b/.github/workflows/go-version-update.yml index ffe41cb63ab..ef55aa21ede 100644 --- a/.github/workflows/go-version-update.yml +++ b/.github/workflows/go-version-update.yml @@ -3,7 +3,7 @@ name: Update Go version on: workflow_dispatch: schedule: - - cron: "0 3 * * 1" # Run weekly on Monday at 3 AM UTC + - cron: "0 3 * * 1" # Run weekly on Mondays at 3 AM UTC (1 = Monday) permissions: contents: write @@ -38,7 +38,7 @@ jobs: echo "version_num=$LATEST_VERSION_NUM" >> $GITHUB_OUTPUT # Extract major.minor version (e.g., 1.26.0 -> 1.26) - LATEST_MAJOR_MINOR=$(echo $LATEST_VERSION_NUM | sed -n 's/^\([0-9]\+\.[0-9]\+\).*/\1/p') + LATEST_MAJOR_MINOR=$(echo $LATEST_VERSION_NUM | sed -E 's/^([0-9]+\.[0-9]+).*/\1/') echo "major_minor=$LATEST_MAJOR_MINOR" >> $GITHUB_OUTPUT - name: Check current Go version @@ -49,7 +49,7 @@ jobs: echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT # Extract major.minor version - CURRENT_MAJOR_MINOR=$(echo $CURRENT_VERSION | sed -n 's/^\([0-9]\+\.[0-9]\+\).*/\1/p') + CURRENT_MAJOR_MINOR=$(echo $CURRENT_VERSION | sed -E 's/^([0-9]+\.[0-9]+).*/\1/') echo "major_minor=$CURRENT_MAJOR_MINOR" >> $GITHUB_OUTPUT - name: Compare versions @@ -114,9 +114,9 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | BRANCH_NAME="workflow/go-version-update" - PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[]? | .number') + PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number') - if [ -n "$PR_NUMBER" ]; then + if [ "$PR_NUMBER" != "null" ] && [ -n "$PR_NUMBER" ]; then echo "Existing PR found: #$PR_NUMBER" echo "pr_exists=true" >> $GITHUB_OUTPUT echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT @@ -152,7 +152,9 @@ jobs: CURRENT_MAJOR_MINOR="${{ steps.current-version.outputs.major_minor }}" PR_TITLE="Go: Update to $LATEST_MAJOR_MINOR" - PR_BODY="This PR updates Go from $CURRENT_MAJOR_MINOR to $LATEST_MAJOR_MINOR. + + PR_BODY=$(cat < Date: Fri, 13 Feb 2026 11:22:36 +0000 Subject: [PATCH 011/226] Add error handling and validation to Go version workflow Co-authored-by: mbg <278086+mbg@users.noreply.github.com> --- .github/workflows/go-version-update.yml | 40 +++++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/.github/workflows/go-version-update.yml b/.github/workflows/go-version-update.yml index ef55aa21ede..95d1599d2a2 100644 --- a/.github/workflows/go-version-update.yml +++ b/.github/workflows/go-version-update.yml @@ -30,6 +30,12 @@ jobs: id: fetch-version run: | LATEST_GO_VERSION=$(curl -s https://go.dev/dl/\?mode\=json | jq -r '.[0].version') + + if [ -z "$LATEST_GO_VERSION" ] || [ "$LATEST_GO_VERSION" = "null" ]; then + echo "Error: Failed to fetch latest Go version from go.dev" + exit 1 + fi + echo "Latest Go version from go.dev: $LATEST_GO_VERSION" echo "version=$LATEST_GO_VERSION" >> $GITHUB_OUTPUT @@ -45,6 +51,12 @@ jobs: id: current-version run: | CURRENT_VERSION=$(sed -n 's/.*go_sdk\.download(version = \"\([^\"]*\)\".*/\1/p' MODULE.bazel) + + if [ -z "$CURRENT_VERSION" ]; then + echo "Error: Could not extract Go version from MODULE.bazel" + exit 1 + fi + echo "Current Go version in MODULE.bazel: $CURRENT_VERSION" echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT @@ -79,18 +91,34 @@ jobs: echo "Updating from $CURRENT_VERSION to $LATEST_VERSION_NUM" + # Escape dots in version strings for use in sed patterns + CURRENT_VERSION_ESCAPED=$(echo "$CURRENT_VERSION" | sed 's/\./\\./g') + LATEST_VERSION_NUM_ESCAPED=$(echo "$LATEST_VERSION_NUM" | sed 's/\./\\./g') + CURRENT_MAJOR_MINOR_ESCAPED=$(echo "$CURRENT_MAJOR_MINOR" | sed 's/\./\\./g') + LATEST_MAJOR_MINOR_ESCAPED=$(echo "$LATEST_MAJOR_MINOR" | sed 's/\./\\./g') + # Update MODULE.bazel - sed -i "s/go_sdk.download(version = \"$CURRENT_VERSION\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel + if ! sed -i "s/go_sdk\.download(version = \"$CURRENT_VERSION_ESCAPED\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel; then + echo "Warning: Failed to update MODULE.bazel" + fi # Update go/extractor/go.mod - sed -i "s/^go $CURRENT_MAJOR_MINOR$/go $LATEST_MAJOR_MINOR/" go/extractor/go.mod - sed -i "s/^toolchain go$CURRENT_VERSION$/toolchain go$LATEST_VERSION_NUM/" go/extractor/go.mod + if ! sed -i "s/^go $CURRENT_MAJOR_MINOR_ESCAPED\$/go $LATEST_MAJOR_MINOR/" go/extractor/go.mod; then + echo "Warning: Failed to update go directive in go.mod" + fi + if ! sed -i "s/^toolchain go$CURRENT_VERSION_ESCAPED\$/toolchain go$LATEST_VERSION_NUM/" go/extractor/go.mod; then + echo "Warning: Failed to update toolchain in go.mod" + fi # Update go/extractor/autobuilder/build-environment.go - sed -i "s/var maxGoVersion = util.NewSemVer(\"$CURRENT_MAJOR_MINOR\")/var maxGoVersion = util.NewSemVer(\"$LATEST_MAJOR_MINOR\")/" go/extractor/autobuilder/build-environment.go + if ! sed -i "s/var maxGoVersion = util\.NewSemVer(\"$CURRENT_MAJOR_MINOR_ESCAPED\")/var maxGoVersion = util.NewSemVer(\"$LATEST_MAJOR_MINOR\")/" go/extractor/autobuilder/build-environment.go; then + echo "Warning: Failed to update build-environment.go" + fi # Update go/actions/test/action.yml - sed -i "s/default: \"~$CURRENT_VERSION\"/default: \"~$LATEST_VERSION_NUM\"/" go/actions/test/action.yml + if ! sed -i "s/default: \"~$CURRENT_VERSION_ESCAPED\"/default: \"~$LATEST_VERSION_NUM\"/" go/actions/test/action.yml; then + echo "Warning: Failed to update action.yml" + fi # Show what changed git diff @@ -162,7 +190,7 @@ jobs: - \`go/extractor/autobuilder/build-environment.go\` - maxGoVersion - \`go/actions/test/action.yml\` - default go-test-version - This PR was automatically created by the [Go version update workflow](.github/workflows/go-version-update.yml). + This PR was automatically created by the [Go version update workflow](https://github.com/${{ github.repository }}/blob/main/.github/workflows/go-version-update.yml). EOF ) From b6004045bdd4a826a583fb849c973887059f6e9f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:23:44 +0000 Subject: [PATCH 012/226] Clean up Go version workflow - remove unnecessary escaping and checks Co-authored-by: mbg <278086+mbg@users.noreply.github.com> --- .github/workflows/go-version-update.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/go-version-update.yml b/.github/workflows/go-version-update.yml index 95d1599d2a2..3cd8f72690f 100644 --- a/.github/workflows/go-version-update.yml +++ b/.github/workflows/go-version-update.yml @@ -29,7 +29,7 @@ jobs: - name: Fetch latest Go version id: fetch-version run: | - LATEST_GO_VERSION=$(curl -s https://go.dev/dl/\?mode\=json | jq -r '.[0].version') + LATEST_GO_VERSION=$(curl -s https://go.dev/dl/?mode=json | jq -r '.[0].version') if [ -z "$LATEST_GO_VERSION" ] || [ "$LATEST_GO_VERSION" = "null" ]; then echo "Error: Failed to fetch latest Go version from go.dev" @@ -91,11 +91,9 @@ jobs: echo "Updating from $CURRENT_VERSION to $LATEST_VERSION_NUM" - # Escape dots in version strings for use in sed patterns + # Escape dots in current version strings for use in sed patterns CURRENT_VERSION_ESCAPED=$(echo "$CURRENT_VERSION" | sed 's/\./\\./g') - LATEST_VERSION_NUM_ESCAPED=$(echo "$LATEST_VERSION_NUM" | sed 's/\./\\./g') CURRENT_MAJOR_MINOR_ESCAPED=$(echo "$CURRENT_MAJOR_MINOR" | sed 's/\./\\./g') - LATEST_MAJOR_MINOR_ESCAPED=$(echo "$LATEST_MAJOR_MINOR" | sed 's/\./\\./g') # Update MODULE.bazel if ! sed -i "s/go_sdk\.download(version = \"$CURRENT_VERSION_ESCAPED\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel; then @@ -144,7 +142,7 @@ jobs: BRANCH_NAME="workflow/go-version-update" PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number') - if [ "$PR_NUMBER" != "null" ] && [ -n "$PR_NUMBER" ]; then + if [ -n "$PR_NUMBER" ]; then echo "Existing PR found: #$PR_NUMBER" echo "pr_exists=true" >> $GITHUB_OUTPUT echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT From 26dca558c764ed7f9f97542e689b0c80204bc668 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 6 May 2026 16:02:08 +0000 Subject: [PATCH 013/226] Initial plan From f5b17b0b48331dbf7b8ee7dc040cf85cd37dfeca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 6 May 2026 16:08:02 +0000 Subject: [PATCH 014/226] Add SSRF tests and stubs for Apache Http fluent Request models Agent-Logs-Url: https://github.com/github/codeql/sessions/bd4fa112-dbc3-47e8-9cef-9b1b13c7e549 Co-authored-by: owen-mc <62447351+owen-mc@users.noreply.github.com> --- .../CWE-918/ApacheHttpFluentSSRF.java | 40 +++++++++++++++++++ .../test/query-tests/security/CWE-918/options | 2 +- .../apache/http/client/fluent/Request.java | 26 ++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 java/ql/test/query-tests/security/CWE-918/ApacheHttpFluentSSRF.java create mode 100644 java/ql/test/stubs/apache-http-fluent-4.5.14/org/apache/http/client/fluent/Request.java diff --git a/java/ql/test/query-tests/security/CWE-918/ApacheHttpFluentSSRF.java b/java/ql/test/query-tests/security/CWE-918/ApacheHttpFluentSSRF.java new file mode 100644 index 00000000000..df765ea060b --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-918/ApacheHttpFluentSSRF.java @@ -0,0 +1,40 @@ +import java.io.IOException; +import java.net.URI; + +import org.apache.http.client.fluent.Request; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class ApacheHttpFluentSSRF extends HttpServlet { + + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + try { + + String sink = request.getParameter("uri"); // $ Source + URI uri = new URI(sink); + + Request.Delete(sink); // $ Alert + Request.Delete(uri); // $ Alert + Request.Get(sink); // $ Alert + Request.Get(uri); // $ Alert + Request.Head(sink); // $ Alert + Request.Head(uri); // $ Alert + Request.Options(sink); // $ Alert + Request.Options(uri); // $ Alert + Request.Patch(sink); // $ Alert + Request.Patch(uri); // $ Alert + Request.Post(sink); // $ Alert + Request.Post(uri); // $ Alert + Request.Put(sink); // $ Alert + Request.Put(uri); // $ Alert + Request.Trace(sink); // $ Alert + Request.Trace(uri); // $ Alert + + } catch (Exception e) { + // TODO: handle exception + } + } +} diff --git a/java/ql/test/query-tests/security/CWE-918/options b/java/ql/test/query-tests/security/CWE-918/options index 6b6efaeca54..04f8cec9345 100644 --- a/java/ql/test/query-tests/security/CWE-918/options +++ b/java/ql/test/query-tests/security/CWE-918/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/javax-validation-constraints:${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jaxws-api-2.0:${testdir}/../../../stubs/apache-cxf +//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/javax-validation-constraints:${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/apache-http-fluent-4.5.14:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jaxws-api-2.0:${testdir}/../../../stubs/apache-cxf diff --git a/java/ql/test/stubs/apache-http-fluent-4.5.14/org/apache/http/client/fluent/Request.java b/java/ql/test/stubs/apache-http-fluent-4.5.14/org/apache/http/client/fluent/Request.java new file mode 100644 index 00000000000..2722b480c0c --- /dev/null +++ b/java/ql/test/stubs/apache-http-fluent-4.5.14/org/apache/http/client/fluent/Request.java @@ -0,0 +1,26 @@ +// Generated automatically from org.apache.http.client.fluent.Request for testing purposes + +package org.apache.http.client.fluent; + +import java.net.URI; + +public class Request { + protected Request() {} + + public static Request Delete(String p0) { return null; } + public static Request Delete(URI p0) { return null; } + public static Request Get(String p0) { return null; } + public static Request Get(URI p0) { return null; } + public static Request Head(String p0) { return null; } + public static Request Head(URI p0) { return null; } + public static Request Options(String p0) { return null; } + public static Request Options(URI p0) { return null; } + public static Request Patch(String p0) { return null; } + public static Request Patch(URI p0) { return null; } + public static Request Post(String p0) { return null; } + public static Request Post(URI p0) { return null; } + public static Request Put(String p0) { return null; } + public static Request Put(URI p0) { return null; } + public static Request Trace(String p0) { return null; } + public static Request Trace(URI p0) { return null; } +} From 043ec857ab94007f495f93d5bfef5c520cc008ab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 6 May 2026 20:31:34 +0000 Subject: [PATCH 015/226] Replace fluent SSRF changes with Apache HttpClient execute model tests Agent-Logs-Url: https://github.com/github/codeql/sessions/3db201db-a1b5-4353-a94a-14a8d156dd3b Co-authored-by: owen-mc <62447351+owen-mc@users.noreply.github.com> --- .../lib/ext/org.apache.http.client.model.yml | 9 +++- .../CWE-918/ApacheHttpClientExecuteSSRF.java | 43 +++++++++++++++++++ .../CWE-918/ApacheHttpFluentSSRF.java | 40 ----------------- .../test/query-tests/security/CWE-918/options | 2 +- .../org/apache/http/client/HttpClient.java | 23 ++++++++++ .../apache/http/client/ResponseHandler.java | 9 ++++ .../apache/http/client/fluent/Request.java | 26 ----------- 7 files changed, 83 insertions(+), 69 deletions(-) create mode 100644 java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java delete mode 100644 java/ql/test/query-tests/security/CWE-918/ApacheHttpFluentSSRF.java create mode 100644 java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/client/HttpClient.java create mode 100644 java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/client/ResponseHandler.java delete mode 100644 java/ql/test/stubs/apache-http-fluent-4.5.14/org/apache/http/client/fluent/Request.java diff --git a/java/ql/lib/ext/org.apache.http.client.model.yml b/java/ql/lib/ext/org.apache.http.client.model.yml index 681efdf32e7..caba9bd718b 100644 --- a/java/ql/lib/ext/org.apache.http.client.model.yml +++ b/java/ql/lib/ext/org.apache.http.client.model.yml @@ -3,6 +3,11 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest,HttpContext)", "", "Argument[0]", "request-forgery", "ai-manual"] - - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest,ResponseHandler,HttpContext)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpHost,HttpRequest)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpHost,HttpRequest,HttpContext)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpHost,HttpRequest,ResponseHandler)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpHost,HttpRequest,ResponseHandler,HttpContext)", "", "Argument[0]", "request-forgery", "ai-manual"] - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest,HttpContext)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest,ResponseHandler)", "", "Argument[0]", "request-forgery", "ai-manual"] + - ["org.apache.http.client", "HttpClient", True, "execute", "(HttpUriRequest,ResponseHandler,HttpContext)", "", "Argument[0]", "request-forgery", "ai-manual"] diff --git a/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java b/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java new file mode 100644 index 00000000000..05d38b2b5dd --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java @@ -0,0 +1,43 @@ +import java.io.IOException; + +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.client.HttpClient; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.message.BasicHttpRequest; +import org.apache.http.protocol.HttpContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class ApacheHttpClientExecuteSSRF extends HttpServlet { + + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + try { + + String sink = request.getParameter("host"); // $ Source + + HttpHost host = new HttpHost(sink); + HttpRequest req = new BasicHttpRequest("GET", "/"); + HttpUriRequest uriReq = (HttpUriRequest) (Object) sink; + HttpContext context = null; + HttpClient client = null; + ResponseHandler handler = null; + + client.execute(host, req); // $ Alert + client.execute(host, req, context); // $ Alert + client.execute(host, req, handler); // $ Alert + client.execute(host, req, handler, context); // $ Alert + client.execute(uriReq); // $ Alert + client.execute(uriReq, context); // $ Alert + client.execute(uriReq, handler); // $ Alert + client.execute(uriReq, handler, context); // $ Alert + + } catch (Exception e) { + // TODO: handle exception + } + } +} diff --git a/java/ql/test/query-tests/security/CWE-918/ApacheHttpFluentSSRF.java b/java/ql/test/query-tests/security/CWE-918/ApacheHttpFluentSSRF.java deleted file mode 100644 index df765ea060b..00000000000 --- a/java/ql/test/query-tests/security/CWE-918/ApacheHttpFluentSSRF.java +++ /dev/null @@ -1,40 +0,0 @@ -import java.io.IOException; -import java.net.URI; - -import org.apache.http.client.fluent.Request; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class ApacheHttpFluentSSRF extends HttpServlet { - - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - try { - - String sink = request.getParameter("uri"); // $ Source - URI uri = new URI(sink); - - Request.Delete(sink); // $ Alert - Request.Delete(uri); // $ Alert - Request.Get(sink); // $ Alert - Request.Get(uri); // $ Alert - Request.Head(sink); // $ Alert - Request.Head(uri); // $ Alert - Request.Options(sink); // $ Alert - Request.Options(uri); // $ Alert - Request.Patch(sink); // $ Alert - Request.Patch(uri); // $ Alert - Request.Post(sink); // $ Alert - Request.Post(uri); // $ Alert - Request.Put(sink); // $ Alert - Request.Put(uri); // $ Alert - Request.Trace(sink); // $ Alert - Request.Trace(uri); // $ Alert - - } catch (Exception e) { - // TODO: handle exception - } - } -} diff --git a/java/ql/test/query-tests/security/CWE-918/options b/java/ql/test/query-tests/security/CWE-918/options index 04f8cec9345..a5b2bf58d43 100644 --- a/java/ql/test/query-tests/security/CWE-918/options +++ b/java/ql/test/query-tests/security/CWE-918/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/javax-validation-constraints:${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/apache-http-fluent-4.5.14:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jaxws-api-2.0:${testdir}/../../../stubs/apache-cxf +//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/javax-validation-constraints:${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/apache-http-client-4.4.13:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jaxws-api-2.0:${testdir}/../../../stubs/apache-cxf diff --git a/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/client/HttpClient.java b/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/client/HttpClient.java new file mode 100644 index 00000000000..3cd8e33ab5c --- /dev/null +++ b/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/client/HttpClient.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.http.client.HttpClient for testing purposes + +package org.apache.http.client; + +import java.io.IOException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.protocol.HttpContext; + +public interface HttpClient { + HttpResponse execute(HttpHost target, HttpRequest request) throws IOException; + HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException; + T execute(HttpHost target, HttpRequest request, ResponseHandler responseHandler) throws IOException; + T execute(HttpHost target, HttpRequest request, ResponseHandler responseHandler, HttpContext context) + throws IOException; + HttpResponse execute(HttpUriRequest request) throws IOException; + HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException; + T execute(HttpUriRequest request, ResponseHandler responseHandler) throws IOException; + T execute(HttpUriRequest request, ResponseHandler responseHandler, HttpContext context) + throws IOException; +} diff --git a/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/client/ResponseHandler.java b/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/client/ResponseHandler.java new file mode 100644 index 00000000000..0733cae3baf --- /dev/null +++ b/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/client/ResponseHandler.java @@ -0,0 +1,9 @@ +// Generated automatically from org.apache.http.client.ResponseHandler for testing purposes + +package org.apache.http.client; + +import org.apache.http.HttpResponse; + +public interface ResponseHandler { + T handleResponse(HttpResponse response); +} diff --git a/java/ql/test/stubs/apache-http-fluent-4.5.14/org/apache/http/client/fluent/Request.java b/java/ql/test/stubs/apache-http-fluent-4.5.14/org/apache/http/client/fluent/Request.java deleted file mode 100644 index 2722b480c0c..00000000000 --- a/java/ql/test/stubs/apache-http-fluent-4.5.14/org/apache/http/client/fluent/Request.java +++ /dev/null @@ -1,26 +0,0 @@ -// Generated automatically from org.apache.http.client.fluent.Request for testing purposes - -package org.apache.http.client.fluent; - -import java.net.URI; - -public class Request { - protected Request() {} - - public static Request Delete(String p0) { return null; } - public static Request Delete(URI p0) { return null; } - public static Request Get(String p0) { return null; } - public static Request Get(URI p0) { return null; } - public static Request Head(String p0) { return null; } - public static Request Head(URI p0) { return null; } - public static Request Options(String p0) { return null; } - public static Request Options(URI p0) { return null; } - public static Request Patch(String p0) { return null; } - public static Request Patch(URI p0) { return null; } - public static Request Post(String p0) { return null; } - public static Request Post(URI p0) { return null; } - public static Request Put(String p0) { return null; } - public static Request Put(URI p0) { return null; } - public static Request Trace(String p0) { return null; } - public static Request Trace(URI p0) { return null; } -} From dd35bc0722d74ca4d75ca40841c702ffba4a72e8 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 7 May 2026 10:17:47 +0100 Subject: [PATCH 016/226] Update test output --- .../security/CWE-918/RequestForgery.expected | 842 +++++++++--------- 1 file changed, 442 insertions(+), 400 deletions(-) diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected index a84c752b02d..eed7d3ee527 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected @@ -1,4 +1,12 @@ #select +| ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:30:43:30:45 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:30:43:30:45 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:32:29:32:31 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:32:29:32:31 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:34:26:34:28 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:34:26:34:28 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | @@ -377,7 +385,19 @@ | mad/Test.java:107:15:107:31 | (...)... | mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:107:15:107:31 | (...)... | Potential server-side request forgery due to a $@. | mad/Test.java:26:16:26:41 | getParameter(...) | user-provided value | | mad/Test.java:112:15:112:31 | (...)... | mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:112:15:112:31 | (...)... | Potential server-side request forgery due to a $@. | mad/Test.java:26:16:26:41 | getParameter(...) | user-provided value | edges -| ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:28:31:28:34 | sink : String | provenance | Src:MaD:277 | +| ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:23:42:23:45 | sink : String | provenance | Src:MaD:285 | +| ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:25:54:25:66 | (...)... : String | provenance | Src:MaD:285 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | provenance | Sink:MaD:228 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | provenance | Sink:MaD:229 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | provenance | Sink:MaD:230 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | provenance | Sink:MaD:231 | +| ApacheHttpClientExecuteSSRF.java:23:42:23:45 | sink : String | ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | provenance | MaD:305 | +| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | provenance | Sink:MaD:232 | +| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | provenance | Sink:MaD:233 | +| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | provenance | Sink:MaD:234 | +| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | provenance | Sink:MaD:235 | +| ApacheHttpClientExecuteSSRF.java:25:54:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | provenance | | +| ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:28:31:28:34 | sink : String | provenance | Src:MaD:285 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:30:43:30:45 | uri | provenance | Sink:MaD:211 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:32:29:32:31 | uri | provenance | Sink:MaD:217 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:34:26:34:28 | uri | provenance | Sink:MaD:212 | @@ -403,16 +423,16 @@ edges | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:57:34:57:36 | uri | provenance | Sink:MaD:223 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:58:43:58:45 | uri | provenance | Sink:MaD:226 | | ApacheHttpSSRF.java:28:31:28:34 | sink : String | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | provenance | Config | -| ApacheHttpSSRF.java:28:31:28:34 | sink : String | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | provenance | MaD:285 | -| ApacheHttpSSRF.java:42:62:42:64 | uri : URI | ApacheHttpSSRF.java:42:62:42:75 | toString(...) : String | provenance | MaD:287 | -| ApacheHttpSSRF.java:42:62:42:75 | toString(...) : String | ApacheHttpSSRF.java:42:34:42:82 | new BasicRequestLine(...) | provenance | MaD:296 Sink:MaD:231 | -| ApacheHttpSSRF.java:43:41:43:43 | uri : URI | ApacheHttpSSRF.java:43:41:43:54 | toString(...) | provenance | MaD:287 Sink:MaD:232 | -| ApacheHttpSSRF.java:44:41:44:43 | uri : URI | ApacheHttpSSRF.java:44:41:44:54 | toString(...) | provenance | MaD:287 Sink:MaD:233 | -| ApacheHttpSSRF.java:46:77:46:79 | uri : URI | ApacheHttpSSRF.java:46:77:46:90 | toString(...) : String | provenance | MaD:287 | -| ApacheHttpSSRF.java:46:77:46:90 | toString(...) : String | ApacheHttpSSRF.java:46:49:46:97 | new BasicRequestLine(...) | provenance | MaD:296 Sink:MaD:228 | -| ApacheHttpSSRF.java:47:56:47:58 | uri : URI | ApacheHttpSSRF.java:47:56:47:69 | toString(...) | provenance | MaD:287 Sink:MaD:229 | -| ApacheHttpSSRF.java:48:56:48:58 | uri : URI | ApacheHttpSSRF.java:48:56:48:69 | toString(...) | provenance | MaD:287 Sink:MaD:230 | -| ApacheHttpSSRFVersion5.java:41:30:41:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:42:31:42:37 | uriSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRF.java:28:31:28:34 | sink : String | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | provenance | MaD:293 | +| ApacheHttpSSRF.java:42:62:42:64 | uri : URI | ApacheHttpSSRF.java:42:62:42:75 | toString(...) : String | provenance | MaD:295 | +| ApacheHttpSSRF.java:42:62:42:75 | toString(...) : String | ApacheHttpSSRF.java:42:34:42:82 | new BasicRequestLine(...) | provenance | MaD:304 Sink:MaD:239 | +| ApacheHttpSSRF.java:43:41:43:43 | uri : URI | ApacheHttpSSRF.java:43:41:43:54 | toString(...) | provenance | MaD:295 Sink:MaD:240 | +| ApacheHttpSSRF.java:44:41:44:43 | uri : URI | ApacheHttpSSRF.java:44:41:44:54 | toString(...) | provenance | MaD:295 Sink:MaD:241 | +| ApacheHttpSSRF.java:46:77:46:79 | uri : URI | ApacheHttpSSRF.java:46:77:46:90 | toString(...) : String | provenance | MaD:295 | +| ApacheHttpSSRF.java:46:77:46:90 | toString(...) : String | ApacheHttpSSRF.java:46:49:46:97 | new BasicRequestLine(...) | provenance | MaD:304 Sink:MaD:236 | +| ApacheHttpSSRF.java:47:56:47:58 | uri : URI | ApacheHttpSSRF.java:47:56:47:69 | toString(...) | provenance | MaD:295 Sink:MaD:237 | +| ApacheHttpSSRF.java:48:56:48:58 | uri : URI | ApacheHttpSSRF.java:48:56:48:69 | toString(...) | provenance | MaD:295 Sink:MaD:238 | +| ApacheHttpSSRFVersion5.java:41:30:41:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:42:31:42:37 | uriSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:42:23:42:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:49:54:49:56 | uri : URI | provenance | | | ApacheHttpSSRFVersion5.java:42:23:42:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:50:54:50:56 | uri | provenance | Sink:MaD:40 | | ApacheHttpSSRFVersion5.java:42:23:42:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:51:48:51:50 | uri : URI | provenance | | @@ -478,8 +498,8 @@ edges | ApacheHttpSSRFVersion5.java:42:23:42:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:167:40:167:42 | uri : URI | provenance | | | ApacheHttpSSRFVersion5.java:42:23:42:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:168:40:168:42 | uri | provenance | Sink:MaD:121 | | ApacheHttpSSRFVersion5.java:42:31:42:37 | uriSink : String | ApacheHttpSSRFVersion5.java:42:23:42:38 | new URI(...) : URI | provenance | Config | -| ApacheHttpSSRFVersion5.java:42:31:42:37 | uriSink : String | ApacheHttpSSRFVersion5.java:42:23:42:38 | new URI(...) : URI | provenance | MaD:285 | -| ApacheHttpSSRFVersion5.java:44:31:44:58 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:45:42:45:49 | hostSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:42:31:42:37 | uriSink : String | ApacheHttpSSRFVersion5.java:42:23:42:38 | new URI(...) : URI | provenance | MaD:293 | +| ApacheHttpSSRFVersion5.java:44:31:44:58 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:45:42:45:49 | hostSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:45:29:45:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:48:54:48:57 | host | provenance | Sink:MaD:38 | | ApacheHttpSSRFVersion5.java:45:29:45:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:54:38:54:41 | host | provenance | Sink:MaD:43 | | ApacheHttpSSRFVersion5.java:45:29:45:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:58:35:58:38 | host | provenance | Sink:MaD:46 | @@ -503,38 +523,38 @@ edges | ApacheHttpSSRFVersion5.java:45:29:45:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:132:36:132:39 | host | provenance | Sink:MaD:100 | | ApacheHttpSSRFVersion5.java:45:29:45:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:136:38:136:41 | host | provenance | Sink:MaD:103 | | ApacheHttpSSRFVersion5.java:45:29:45:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:162:52:162:55 | host | provenance | Sink:MaD:204 | -| ApacheHttpSSRFVersion5.java:45:42:45:49 | hostSink : String | ApacheHttpSSRFVersion5.java:45:29:45:50 | new HttpHost(...) : HttpHost | provenance | MaD:295 | -| ApacheHttpSSRFVersion5.java:49:54:49:56 | uri : URI | ApacheHttpSSRFVersion5.java:49:54:49:67 | toString(...) | provenance | MaD:287 Sink:MaD:39 | -| ApacheHttpSSRFVersion5.java:51:48:51:50 | uri : URI | ApacheHttpSSRFVersion5.java:51:48:51:61 | toString(...) | provenance | MaD:287 Sink:MaD:41 | -| ApacheHttpSSRFVersion5.java:55:38:55:40 | uri : URI | ApacheHttpSSRFVersion5.java:55:38:55:51 | toString(...) | provenance | MaD:287 Sink:MaD:44 | -| ApacheHttpSSRFVersion5.java:59:35:59:37 | uri : URI | ApacheHttpSSRFVersion5.java:59:35:59:48 | toString(...) | provenance | MaD:287 Sink:MaD:47 | -| ApacheHttpSSRFVersion5.java:63:36:63:38 | uri : URI | ApacheHttpSSRFVersion5.java:63:36:63:49 | toString(...) | provenance | MaD:287 Sink:MaD:50 | -| ApacheHttpSSRFVersion5.java:67:39:67:41 | uri : URI | ApacheHttpSSRFVersion5.java:67:39:67:52 | toString(...) | provenance | MaD:287 Sink:MaD:53 | -| ApacheHttpSSRFVersion5.java:71:37:71:39 | uri : URI | ApacheHttpSSRFVersion5.java:71:37:71:50 | toString(...) | provenance | MaD:287 Sink:MaD:56 | -| ApacheHttpSSRFVersion5.java:75:36:75:38 | uri : URI | ApacheHttpSSRFVersion5.java:75:36:75:49 | toString(...) | provenance | MaD:287 Sink:MaD:59 | -| ApacheHttpSSRFVersion5.java:79:35:79:37 | uri : URI | ApacheHttpSSRFVersion5.java:79:35:79:48 | toString(...) | provenance | MaD:287 Sink:MaD:62 | -| ApacheHttpSSRFVersion5.java:83:37:83:39 | uri : URI | ApacheHttpSSRFVersion5.java:83:37:83:50 | toString(...) | provenance | MaD:287 Sink:MaD:65 | -| ApacheHttpSSRFVersion5.java:98:48:98:50 | uri : URI | ApacheHttpSSRFVersion5.java:98:48:98:61 | toString(...) | provenance | MaD:287 Sink:MaD:75 | -| ApacheHttpSSRFVersion5.java:103:55:103:57 | uri : URI | ApacheHttpSSRFVersion5.java:103:55:103:68 | toString(...) | provenance | MaD:287 Sink:MaD:78 | -| ApacheHttpSSRFVersion5.java:105:49:105:51 | uri : URI | ApacheHttpSSRFVersion5.java:105:49:105:62 | toString(...) | provenance | MaD:287 Sink:MaD:80 | -| ApacheHttpSSRFVersion5.java:109:39:109:41 | uri : URI | ApacheHttpSSRFVersion5.java:109:39:109:52 | toString(...) | provenance | MaD:287 Sink:MaD:83 | -| ApacheHttpSSRFVersion5.java:113:36:113:38 | uri : URI | ApacheHttpSSRFVersion5.java:113:36:113:49 | toString(...) | provenance | MaD:287 Sink:MaD:86 | -| ApacheHttpSSRFVersion5.java:117:37:117:39 | uri : URI | ApacheHttpSSRFVersion5.java:117:37:117:50 | toString(...) | provenance | MaD:287 Sink:MaD:89 | -| ApacheHttpSSRFVersion5.java:121:40:121:42 | uri : URI | ApacheHttpSSRFVersion5.java:121:40:121:53 | toString(...) | provenance | MaD:287 Sink:MaD:92 | -| ApacheHttpSSRFVersion5.java:125:38:125:40 | uri : URI | ApacheHttpSSRFVersion5.java:125:38:125:51 | toString(...) | provenance | MaD:287 Sink:MaD:95 | -| ApacheHttpSSRFVersion5.java:129:37:129:39 | uri : URI | ApacheHttpSSRFVersion5.java:129:37:129:50 | toString(...) | provenance | MaD:287 Sink:MaD:98 | -| ApacheHttpSSRFVersion5.java:133:36:133:38 | uri : URI | ApacheHttpSSRFVersion5.java:133:36:133:49 | toString(...) | provenance | MaD:287 Sink:MaD:101 | -| ApacheHttpSSRFVersion5.java:137:38:137:40 | uri : URI | ApacheHttpSSRFVersion5.java:137:38:137:51 | toString(...) | provenance | MaD:287 Sink:MaD:104 | -| ApacheHttpSSRFVersion5.java:141:41:141:43 | uri : URI | ApacheHttpSSRFVersion5.java:141:41:141:54 | toString(...) | provenance | MaD:287 Sink:MaD:106 | -| ApacheHttpSSRFVersion5.java:144:38:144:40 | uri : URI | ApacheHttpSSRFVersion5.java:144:38:144:51 | toString(...) | provenance | MaD:287 Sink:MaD:108 | -| ApacheHttpSSRFVersion5.java:147:39:147:41 | uri : URI | ApacheHttpSSRFVersion5.java:147:39:147:52 | toString(...) | provenance | MaD:287 Sink:MaD:110 | -| ApacheHttpSSRFVersion5.java:150:42:150:44 | uri : URI | ApacheHttpSSRFVersion5.java:150:42:150:55 | toString(...) | provenance | MaD:287 Sink:MaD:112 | -| ApacheHttpSSRFVersion5.java:153:40:153:42 | uri : URI | ApacheHttpSSRFVersion5.java:153:40:153:53 | toString(...) | provenance | MaD:287 Sink:MaD:114 | -| ApacheHttpSSRFVersion5.java:156:39:156:41 | uri : URI | ApacheHttpSSRFVersion5.java:156:39:156:52 | toString(...) | provenance | MaD:287 Sink:MaD:116 | -| ApacheHttpSSRFVersion5.java:159:38:159:40 | uri : URI | ApacheHttpSSRFVersion5.java:159:38:159:51 | toString(...) | provenance | MaD:287 Sink:MaD:118 | -| ApacheHttpSSRFVersion5.java:164:47:164:49 | uri : URI | ApacheHttpSSRFVersion5.java:164:47:164:60 | toString(...) | provenance | MaD:287 Sink:MaD:205 | -| ApacheHttpSSRFVersion5.java:167:40:167:42 | uri : URI | ApacheHttpSSRFVersion5.java:167:40:167:53 | toString(...) | provenance | MaD:287 Sink:MaD:120 | -| ApacheHttpSSRFVersion5.java:180:30:180:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:181:31:181:37 | uriSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:45:42:45:49 | hostSink : String | ApacheHttpSSRFVersion5.java:45:29:45:50 | new HttpHost(...) : HttpHost | provenance | MaD:303 | +| ApacheHttpSSRFVersion5.java:49:54:49:56 | uri : URI | ApacheHttpSSRFVersion5.java:49:54:49:67 | toString(...) | provenance | MaD:295 Sink:MaD:39 | +| ApacheHttpSSRFVersion5.java:51:48:51:50 | uri : URI | ApacheHttpSSRFVersion5.java:51:48:51:61 | toString(...) | provenance | MaD:295 Sink:MaD:41 | +| ApacheHttpSSRFVersion5.java:55:38:55:40 | uri : URI | ApacheHttpSSRFVersion5.java:55:38:55:51 | toString(...) | provenance | MaD:295 Sink:MaD:44 | +| ApacheHttpSSRFVersion5.java:59:35:59:37 | uri : URI | ApacheHttpSSRFVersion5.java:59:35:59:48 | toString(...) | provenance | MaD:295 Sink:MaD:47 | +| ApacheHttpSSRFVersion5.java:63:36:63:38 | uri : URI | ApacheHttpSSRFVersion5.java:63:36:63:49 | toString(...) | provenance | MaD:295 Sink:MaD:50 | +| ApacheHttpSSRFVersion5.java:67:39:67:41 | uri : URI | ApacheHttpSSRFVersion5.java:67:39:67:52 | toString(...) | provenance | MaD:295 Sink:MaD:53 | +| ApacheHttpSSRFVersion5.java:71:37:71:39 | uri : URI | ApacheHttpSSRFVersion5.java:71:37:71:50 | toString(...) | provenance | MaD:295 Sink:MaD:56 | +| ApacheHttpSSRFVersion5.java:75:36:75:38 | uri : URI | ApacheHttpSSRFVersion5.java:75:36:75:49 | toString(...) | provenance | MaD:295 Sink:MaD:59 | +| ApacheHttpSSRFVersion5.java:79:35:79:37 | uri : URI | ApacheHttpSSRFVersion5.java:79:35:79:48 | toString(...) | provenance | MaD:295 Sink:MaD:62 | +| ApacheHttpSSRFVersion5.java:83:37:83:39 | uri : URI | ApacheHttpSSRFVersion5.java:83:37:83:50 | toString(...) | provenance | MaD:295 Sink:MaD:65 | +| ApacheHttpSSRFVersion5.java:98:48:98:50 | uri : URI | ApacheHttpSSRFVersion5.java:98:48:98:61 | toString(...) | provenance | MaD:295 Sink:MaD:75 | +| ApacheHttpSSRFVersion5.java:103:55:103:57 | uri : URI | ApacheHttpSSRFVersion5.java:103:55:103:68 | toString(...) | provenance | MaD:295 Sink:MaD:78 | +| ApacheHttpSSRFVersion5.java:105:49:105:51 | uri : URI | ApacheHttpSSRFVersion5.java:105:49:105:62 | toString(...) | provenance | MaD:295 Sink:MaD:80 | +| ApacheHttpSSRFVersion5.java:109:39:109:41 | uri : URI | ApacheHttpSSRFVersion5.java:109:39:109:52 | toString(...) | provenance | MaD:295 Sink:MaD:83 | +| ApacheHttpSSRFVersion5.java:113:36:113:38 | uri : URI | ApacheHttpSSRFVersion5.java:113:36:113:49 | toString(...) | provenance | MaD:295 Sink:MaD:86 | +| ApacheHttpSSRFVersion5.java:117:37:117:39 | uri : URI | ApacheHttpSSRFVersion5.java:117:37:117:50 | toString(...) | provenance | MaD:295 Sink:MaD:89 | +| ApacheHttpSSRFVersion5.java:121:40:121:42 | uri : URI | ApacheHttpSSRFVersion5.java:121:40:121:53 | toString(...) | provenance | MaD:295 Sink:MaD:92 | +| ApacheHttpSSRFVersion5.java:125:38:125:40 | uri : URI | ApacheHttpSSRFVersion5.java:125:38:125:51 | toString(...) | provenance | MaD:295 Sink:MaD:95 | +| ApacheHttpSSRFVersion5.java:129:37:129:39 | uri : URI | ApacheHttpSSRFVersion5.java:129:37:129:50 | toString(...) | provenance | MaD:295 Sink:MaD:98 | +| ApacheHttpSSRFVersion5.java:133:36:133:38 | uri : URI | ApacheHttpSSRFVersion5.java:133:36:133:49 | toString(...) | provenance | MaD:295 Sink:MaD:101 | +| ApacheHttpSSRFVersion5.java:137:38:137:40 | uri : URI | ApacheHttpSSRFVersion5.java:137:38:137:51 | toString(...) | provenance | MaD:295 Sink:MaD:104 | +| ApacheHttpSSRFVersion5.java:141:41:141:43 | uri : URI | ApacheHttpSSRFVersion5.java:141:41:141:54 | toString(...) | provenance | MaD:295 Sink:MaD:106 | +| ApacheHttpSSRFVersion5.java:144:38:144:40 | uri : URI | ApacheHttpSSRFVersion5.java:144:38:144:51 | toString(...) | provenance | MaD:295 Sink:MaD:108 | +| ApacheHttpSSRFVersion5.java:147:39:147:41 | uri : URI | ApacheHttpSSRFVersion5.java:147:39:147:52 | toString(...) | provenance | MaD:295 Sink:MaD:110 | +| ApacheHttpSSRFVersion5.java:150:42:150:44 | uri : URI | ApacheHttpSSRFVersion5.java:150:42:150:55 | toString(...) | provenance | MaD:295 Sink:MaD:112 | +| ApacheHttpSSRFVersion5.java:153:40:153:42 | uri : URI | ApacheHttpSSRFVersion5.java:153:40:153:53 | toString(...) | provenance | MaD:295 Sink:MaD:114 | +| ApacheHttpSSRFVersion5.java:156:39:156:41 | uri : URI | ApacheHttpSSRFVersion5.java:156:39:156:52 | toString(...) | provenance | MaD:295 Sink:MaD:116 | +| ApacheHttpSSRFVersion5.java:159:38:159:40 | uri : URI | ApacheHttpSSRFVersion5.java:159:38:159:51 | toString(...) | provenance | MaD:295 Sink:MaD:118 | +| ApacheHttpSSRFVersion5.java:164:47:164:49 | uri : URI | ApacheHttpSSRFVersion5.java:164:47:164:60 | toString(...) | provenance | MaD:295 Sink:MaD:205 | +| ApacheHttpSSRFVersion5.java:167:40:167:42 | uri : URI | ApacheHttpSSRFVersion5.java:167:40:167:53 | toString(...) | provenance | MaD:295 Sink:MaD:120 | +| ApacheHttpSSRFVersion5.java:180:30:180:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:181:31:181:37 | uriSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:181:23:181:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:184:56:184:58 | uri : URI | provenance | | | ApacheHttpSSRFVersion5.java:181:23:181:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:185:56:185:58 | uri | provenance | Sink:MaD:123 | | ApacheHttpSSRFVersion5.java:181:23:181:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:186:50:186:52 | uri : URI | provenance | | @@ -573,26 +593,26 @@ edges | ApacheHttpSSRFVersion5.java:181:23:181:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:236:27:236:29 | uri | provenance | Sink:MaD:157 | | ApacheHttpSSRFVersion5.java:181:23:181:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:239:46:239:48 | uri | provenance | Sink:MaD:158 | | ApacheHttpSSRFVersion5.java:181:31:181:37 | uriSink : String | ApacheHttpSSRFVersion5.java:181:23:181:38 | new URI(...) : URI | provenance | Config | -| ApacheHttpSSRFVersion5.java:181:31:181:37 | uriSink : String | ApacheHttpSSRFVersion5.java:181:23:181:38 | new URI(...) : URI | provenance | MaD:285 | -| ApacheHttpSSRFVersion5.java:184:56:184:58 | uri : URI | ApacheHttpSSRFVersion5.java:184:56:184:69 | toString(...) | provenance | MaD:287 Sink:MaD:122 | -| ApacheHttpSSRFVersion5.java:186:50:186:52 | uri : URI | ApacheHttpSSRFVersion5.java:186:50:186:63 | toString(...) | provenance | MaD:287 Sink:MaD:124 | -| ApacheHttpSSRFVersion5.java:189:40:189:42 | uri : URI | ApacheHttpSSRFVersion5.java:189:40:189:53 | toString(...) | provenance | MaD:287 Sink:MaD:126 | -| ApacheHttpSSRFVersion5.java:192:37:192:39 | uri : URI | ApacheHttpSSRFVersion5.java:192:37:192:50 | toString(...) | provenance | MaD:287 Sink:MaD:128 | -| ApacheHttpSSRFVersion5.java:195:38:195:40 | uri : URI | ApacheHttpSSRFVersion5.java:195:38:195:51 | toString(...) | provenance | MaD:287 Sink:MaD:130 | -| ApacheHttpSSRFVersion5.java:198:41:198:43 | uri : URI | ApacheHttpSSRFVersion5.java:198:41:198:54 | toString(...) | provenance | MaD:287 Sink:MaD:132 | -| ApacheHttpSSRFVersion5.java:201:39:201:41 | uri : URI | ApacheHttpSSRFVersion5.java:201:39:201:52 | toString(...) | provenance | MaD:287 Sink:MaD:134 | -| ApacheHttpSSRFVersion5.java:204:38:204:40 | uri : URI | ApacheHttpSSRFVersion5.java:204:38:204:51 | toString(...) | provenance | MaD:287 Sink:MaD:136 | -| ApacheHttpSSRFVersion5.java:207:37:207:39 | uri : URI | ApacheHttpSSRFVersion5.java:207:37:207:50 | toString(...) | provenance | MaD:287 Sink:MaD:138 | -| ApacheHttpSSRFVersion5.java:210:39:210:41 | uri : URI | ApacheHttpSSRFVersion5.java:210:39:210:52 | toString(...) | provenance | MaD:287 Sink:MaD:140 | -| ApacheHttpSSRFVersion5.java:214:28:214:30 | uri : URI | ApacheHttpSSRFVersion5.java:214:28:214:41 | toString(...) | provenance | MaD:287 Sink:MaD:142 | -| ApacheHttpSSRFVersion5.java:217:25:217:27 | uri : URI | ApacheHttpSSRFVersion5.java:217:25:217:38 | toString(...) | provenance | MaD:287 Sink:MaD:144 | -| ApacheHttpSSRFVersion5.java:220:26:220:28 | uri : URI | ApacheHttpSSRFVersion5.java:220:26:220:39 | toString(...) | provenance | MaD:287 Sink:MaD:146 | -| ApacheHttpSSRFVersion5.java:223:29:223:31 | uri : URI | ApacheHttpSSRFVersion5.java:223:29:223:42 | toString(...) | provenance | MaD:287 Sink:MaD:148 | -| ApacheHttpSSRFVersion5.java:226:27:226:29 | uri : URI | ApacheHttpSSRFVersion5.java:226:27:226:40 | toString(...) | provenance | MaD:287 Sink:MaD:150 | -| ApacheHttpSSRFVersion5.java:229:26:229:28 | uri : URI | ApacheHttpSSRFVersion5.java:229:26:229:39 | toString(...) | provenance | MaD:287 Sink:MaD:152 | -| ApacheHttpSSRFVersion5.java:232:25:232:27 | uri : URI | ApacheHttpSSRFVersion5.java:232:25:232:38 | toString(...) | provenance | MaD:287 Sink:MaD:154 | -| ApacheHttpSSRFVersion5.java:235:27:235:29 | uri : URI | ApacheHttpSSRFVersion5.java:235:27:235:40 | toString(...) | provenance | MaD:287 Sink:MaD:156 | -| ApacheHttpSSRFVersion5.java:251:30:251:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:252:31:252:37 | uriSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:181:31:181:37 | uriSink : String | ApacheHttpSSRFVersion5.java:181:23:181:38 | new URI(...) : URI | provenance | MaD:293 | +| ApacheHttpSSRFVersion5.java:184:56:184:58 | uri : URI | ApacheHttpSSRFVersion5.java:184:56:184:69 | toString(...) | provenance | MaD:295 Sink:MaD:122 | +| ApacheHttpSSRFVersion5.java:186:50:186:52 | uri : URI | ApacheHttpSSRFVersion5.java:186:50:186:63 | toString(...) | provenance | MaD:295 Sink:MaD:124 | +| ApacheHttpSSRFVersion5.java:189:40:189:42 | uri : URI | ApacheHttpSSRFVersion5.java:189:40:189:53 | toString(...) | provenance | MaD:295 Sink:MaD:126 | +| ApacheHttpSSRFVersion5.java:192:37:192:39 | uri : URI | ApacheHttpSSRFVersion5.java:192:37:192:50 | toString(...) | provenance | MaD:295 Sink:MaD:128 | +| ApacheHttpSSRFVersion5.java:195:38:195:40 | uri : URI | ApacheHttpSSRFVersion5.java:195:38:195:51 | toString(...) | provenance | MaD:295 Sink:MaD:130 | +| ApacheHttpSSRFVersion5.java:198:41:198:43 | uri : URI | ApacheHttpSSRFVersion5.java:198:41:198:54 | toString(...) | provenance | MaD:295 Sink:MaD:132 | +| ApacheHttpSSRFVersion5.java:201:39:201:41 | uri : URI | ApacheHttpSSRFVersion5.java:201:39:201:52 | toString(...) | provenance | MaD:295 Sink:MaD:134 | +| ApacheHttpSSRFVersion5.java:204:38:204:40 | uri : URI | ApacheHttpSSRFVersion5.java:204:38:204:51 | toString(...) | provenance | MaD:295 Sink:MaD:136 | +| ApacheHttpSSRFVersion5.java:207:37:207:39 | uri : URI | ApacheHttpSSRFVersion5.java:207:37:207:50 | toString(...) | provenance | MaD:295 Sink:MaD:138 | +| ApacheHttpSSRFVersion5.java:210:39:210:41 | uri : URI | ApacheHttpSSRFVersion5.java:210:39:210:52 | toString(...) | provenance | MaD:295 Sink:MaD:140 | +| ApacheHttpSSRFVersion5.java:214:28:214:30 | uri : URI | ApacheHttpSSRFVersion5.java:214:28:214:41 | toString(...) | provenance | MaD:295 Sink:MaD:142 | +| ApacheHttpSSRFVersion5.java:217:25:217:27 | uri : URI | ApacheHttpSSRFVersion5.java:217:25:217:38 | toString(...) | provenance | MaD:295 Sink:MaD:144 | +| ApacheHttpSSRFVersion5.java:220:26:220:28 | uri : URI | ApacheHttpSSRFVersion5.java:220:26:220:39 | toString(...) | provenance | MaD:295 Sink:MaD:146 | +| ApacheHttpSSRFVersion5.java:223:29:223:31 | uri : URI | ApacheHttpSSRFVersion5.java:223:29:223:42 | toString(...) | provenance | MaD:295 Sink:MaD:148 | +| ApacheHttpSSRFVersion5.java:226:27:226:29 | uri : URI | ApacheHttpSSRFVersion5.java:226:27:226:40 | toString(...) | provenance | MaD:295 Sink:MaD:150 | +| ApacheHttpSSRFVersion5.java:229:26:229:28 | uri : URI | ApacheHttpSSRFVersion5.java:229:26:229:39 | toString(...) | provenance | MaD:295 Sink:MaD:152 | +| ApacheHttpSSRFVersion5.java:232:25:232:27 | uri : URI | ApacheHttpSSRFVersion5.java:232:25:232:38 | toString(...) | provenance | MaD:295 Sink:MaD:154 | +| ApacheHttpSSRFVersion5.java:235:27:235:29 | uri : URI | ApacheHttpSSRFVersion5.java:235:27:235:40 | toString(...) | provenance | MaD:295 Sink:MaD:156 | +| ApacheHttpSSRFVersion5.java:251:30:251:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:252:31:252:37 | uriSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:252:23:252:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:255:44:255:46 | uri | provenance | Sink:MaD:159 | | ApacheHttpSSRFVersion5.java:252:23:252:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:256:38:256:40 | uri : URI | provenance | | | ApacheHttpSSRFVersion5.java:252:23:252:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:257:38:257:40 | uri | provenance | Sink:MaD:161 | @@ -613,30 +633,30 @@ edges | ApacheHttpSSRFVersion5.java:252:23:252:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:280:27:280:29 | uri : URI | provenance | | | ApacheHttpSSRFVersion5.java:252:23:252:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:281:27:281:29 | uri | provenance | Sink:MaD:177 | | ApacheHttpSSRFVersion5.java:252:31:252:37 | uriSink : String | ApacheHttpSSRFVersion5.java:252:23:252:38 | new URI(...) : URI | provenance | Config | -| ApacheHttpSSRFVersion5.java:252:31:252:37 | uriSink : String | ApacheHttpSSRFVersion5.java:252:23:252:38 | new URI(...) : URI | provenance | MaD:285 | -| ApacheHttpSSRFVersion5.java:256:38:256:40 | uri : URI | ApacheHttpSSRFVersion5.java:256:38:256:51 | toString(...) | provenance | MaD:287 Sink:MaD:160 | -| ApacheHttpSSRFVersion5.java:259:28:259:30 | uri : URI | ApacheHttpSSRFVersion5.java:259:28:259:41 | toString(...) | provenance | MaD:287 Sink:MaD:162 | -| ApacheHttpSSRFVersion5.java:262:25:262:27 | uri : URI | ApacheHttpSSRFVersion5.java:262:25:262:38 | toString(...) | provenance | MaD:287 Sink:MaD:164 | -| ApacheHttpSSRFVersion5.java:265:26:265:28 | uri : URI | ApacheHttpSSRFVersion5.java:265:26:265:39 | toString(...) | provenance | MaD:287 Sink:MaD:166 | -| ApacheHttpSSRFVersion5.java:268:29:268:31 | uri : URI | ApacheHttpSSRFVersion5.java:268:29:268:42 | toString(...) | provenance | MaD:287 Sink:MaD:168 | -| ApacheHttpSSRFVersion5.java:271:27:271:29 | uri : URI | ApacheHttpSSRFVersion5.java:271:27:271:40 | toString(...) | provenance | MaD:287 Sink:MaD:170 | -| ApacheHttpSSRFVersion5.java:274:26:274:28 | uri : URI | ApacheHttpSSRFVersion5.java:274:26:274:39 | toString(...) | provenance | MaD:287 Sink:MaD:172 | -| ApacheHttpSSRFVersion5.java:277:25:277:27 | uri : URI | ApacheHttpSSRFVersion5.java:277:25:277:38 | toString(...) | provenance | MaD:287 Sink:MaD:174 | -| ApacheHttpSSRFVersion5.java:280:27:280:29 | uri : URI | ApacheHttpSSRFVersion5.java:280:27:280:40 | toString(...) | provenance | MaD:287 Sink:MaD:176 | -| ApacheHttpSSRFVersion5.java:295:30:295:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:296:31:296:37 | uriSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:252:31:252:37 | uriSink : String | ApacheHttpSSRFVersion5.java:252:23:252:38 | new URI(...) : URI | provenance | MaD:293 | +| ApacheHttpSSRFVersion5.java:256:38:256:40 | uri : URI | ApacheHttpSSRFVersion5.java:256:38:256:51 | toString(...) | provenance | MaD:295 Sink:MaD:160 | +| ApacheHttpSSRFVersion5.java:259:28:259:30 | uri : URI | ApacheHttpSSRFVersion5.java:259:28:259:41 | toString(...) | provenance | MaD:295 Sink:MaD:162 | +| ApacheHttpSSRFVersion5.java:262:25:262:27 | uri : URI | ApacheHttpSSRFVersion5.java:262:25:262:38 | toString(...) | provenance | MaD:295 Sink:MaD:164 | +| ApacheHttpSSRFVersion5.java:265:26:265:28 | uri : URI | ApacheHttpSSRFVersion5.java:265:26:265:39 | toString(...) | provenance | MaD:295 Sink:MaD:166 | +| ApacheHttpSSRFVersion5.java:268:29:268:31 | uri : URI | ApacheHttpSSRFVersion5.java:268:29:268:42 | toString(...) | provenance | MaD:295 Sink:MaD:168 | +| ApacheHttpSSRFVersion5.java:271:27:271:29 | uri : URI | ApacheHttpSSRFVersion5.java:271:27:271:40 | toString(...) | provenance | MaD:295 Sink:MaD:170 | +| ApacheHttpSSRFVersion5.java:274:26:274:28 | uri : URI | ApacheHttpSSRFVersion5.java:274:26:274:39 | toString(...) | provenance | MaD:295 Sink:MaD:172 | +| ApacheHttpSSRFVersion5.java:277:25:277:27 | uri : URI | ApacheHttpSSRFVersion5.java:277:25:277:38 | toString(...) | provenance | MaD:295 Sink:MaD:174 | +| ApacheHttpSSRFVersion5.java:280:27:280:29 | uri : URI | ApacheHttpSSRFVersion5.java:280:27:280:40 | toString(...) | provenance | MaD:295 Sink:MaD:176 | +| ApacheHttpSSRFVersion5.java:295:30:295:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:296:31:296:37 | uriSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:296:23:296:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:308:60:308:62 | uri : URI | provenance | | | ApacheHttpSSRFVersion5.java:296:23:296:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:309:60:309:62 | uri | provenance | Sink:MaD:209 | | ApacheHttpSSRFVersion5.java:296:23:296:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:313:53:313:55 | uri : URI | provenance | | | ApacheHttpSSRFVersion5.java:296:23:296:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:314:53:314:55 | uri | provenance | Sink:MaD:209 | | ApacheHttpSSRFVersion5.java:296:31:296:37 | uriSink : String | ApacheHttpSSRFVersion5.java:296:23:296:38 | new URI(...) : URI | provenance | Config | -| ApacheHttpSSRFVersion5.java:296:31:296:37 | uriSink : String | ApacheHttpSSRFVersion5.java:296:23:296:38 | new URI(...) : URI | provenance | MaD:285 | -| ApacheHttpSSRFVersion5.java:298:31:298:58 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:299:42:299:49 | hostSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:296:31:296:37 | uriSink : String | ApacheHttpSSRFVersion5.java:296:23:296:38 | new URI(...) : URI | provenance | MaD:293 | +| ApacheHttpSSRFVersion5.java:298:31:298:58 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:299:42:299:49 | hostSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:299:29:299:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:303:34:303:37 | host | provenance | Sink:MaD:178 | | ApacheHttpSSRFVersion5.java:299:29:299:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:304:34:304:37 | host | provenance | Sink:MaD:179 | -| ApacheHttpSSRFVersion5.java:299:42:299:49 | hostSink : String | ApacheHttpSSRFVersion5.java:299:29:299:50 | new HttpHost(...) : HttpHost | provenance | MaD:295 | -| ApacheHttpSSRFVersion5.java:308:60:308:62 | uri : URI | ApacheHttpSSRFVersion5.java:308:60:308:73 | toString(...) | provenance | MaD:287 Sink:MaD:208 | -| ApacheHttpSSRFVersion5.java:313:53:313:55 | uri : URI | ApacheHttpSSRFVersion5.java:313:53:313:66 | toString(...) | provenance | MaD:287 Sink:MaD:208 | -| ApacheHttpSSRFVersion5.java:326:30:326:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:327:31:327:37 | uriSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:299:42:299:49 | hostSink : String | ApacheHttpSSRFVersion5.java:299:29:299:50 | new HttpHost(...) : HttpHost | provenance | MaD:303 | +| ApacheHttpSSRFVersion5.java:308:60:308:62 | uri : URI | ApacheHttpSSRFVersion5.java:308:60:308:73 | toString(...) | provenance | MaD:295 Sink:MaD:208 | +| ApacheHttpSSRFVersion5.java:313:53:313:55 | uri : URI | ApacheHttpSSRFVersion5.java:313:53:313:66 | toString(...) | provenance | MaD:295 Sink:MaD:208 | +| ApacheHttpSSRFVersion5.java:326:30:326:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:327:31:327:37 | uriSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:327:23:327:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:333:42:333:44 | uri : URI | provenance | | | ApacheHttpSSRFVersion5.java:327:23:327:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:334:42:334:44 | uri | provenance | Sink:MaD:181 | | ApacheHttpSSRFVersion5.java:327:23:327:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:336:39:336:41 | uri : URI | provenance | | @@ -656,20 +676,20 @@ edges | ApacheHttpSSRFVersion5.java:327:23:327:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:359:41:359:43 | uri : URI | provenance | | | ApacheHttpSSRFVersion5.java:327:23:327:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:360:41:360:43 | uri | provenance | Sink:MaD:195 | | ApacheHttpSSRFVersion5.java:327:31:327:37 | uriSink : String | ApacheHttpSSRFVersion5.java:327:23:327:38 | new URI(...) : URI | provenance | Config | -| ApacheHttpSSRFVersion5.java:327:31:327:37 | uriSink : String | ApacheHttpSSRFVersion5.java:327:23:327:38 | new URI(...) : URI | provenance | MaD:285 | -| ApacheHttpSSRFVersion5.java:329:31:329:58 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:330:42:330:49 | hostSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:327:31:327:37 | uriSink : String | ApacheHttpSSRFVersion5.java:327:23:327:38 | new URI(...) : URI | provenance | MaD:293 | +| ApacheHttpSSRFVersion5.java:329:31:329:58 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:330:42:330:49 | hostSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:330:29:330:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:354:53:354:56 | host | provenance | Sink:MaD:204 | -| ApacheHttpSSRFVersion5.java:330:42:330:49 | hostSink : String | ApacheHttpSSRFVersion5.java:330:29:330:50 | new HttpHost(...) : HttpHost | provenance | MaD:295 | -| ApacheHttpSSRFVersion5.java:333:42:333:44 | uri : URI | ApacheHttpSSRFVersion5.java:333:42:333:55 | toString(...) | provenance | MaD:287 Sink:MaD:180 | -| ApacheHttpSSRFVersion5.java:336:39:336:41 | uri : URI | ApacheHttpSSRFVersion5.java:336:39:336:52 | toString(...) | provenance | MaD:287 Sink:MaD:182 | -| ApacheHttpSSRFVersion5.java:339:40:339:42 | uri : URI | ApacheHttpSSRFVersion5.java:339:40:339:53 | toString(...) | provenance | MaD:287 Sink:MaD:184 | -| ApacheHttpSSRFVersion5.java:342:43:342:45 | uri : URI | ApacheHttpSSRFVersion5.java:342:43:342:56 | toString(...) | provenance | MaD:287 Sink:MaD:186 | -| ApacheHttpSSRFVersion5.java:345:41:345:43 | uri : URI | ApacheHttpSSRFVersion5.java:345:41:345:54 | toString(...) | provenance | MaD:287 Sink:MaD:188 | -| ApacheHttpSSRFVersion5.java:348:40:348:42 | uri : URI | ApacheHttpSSRFVersion5.java:348:40:348:53 | toString(...) | provenance | MaD:287 Sink:MaD:190 | -| ApacheHttpSSRFVersion5.java:351:39:351:41 | uri : URI | ApacheHttpSSRFVersion5.java:351:39:351:52 | toString(...) | provenance | MaD:287 Sink:MaD:192 | -| ApacheHttpSSRFVersion5.java:356:48:356:50 | uri : URI | ApacheHttpSSRFVersion5.java:356:48:356:61 | toString(...) | provenance | MaD:287 Sink:MaD:205 | -| ApacheHttpSSRFVersion5.java:359:41:359:43 | uri : URI | ApacheHttpSSRFVersion5.java:359:41:359:54 | toString(...) | provenance | MaD:287 Sink:MaD:194 | -| ApacheHttpSSRFVersion5.java:372:30:372:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:373:31:373:37 | uriSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:330:42:330:49 | hostSink : String | ApacheHttpSSRFVersion5.java:330:29:330:50 | new HttpHost(...) : HttpHost | provenance | MaD:303 | +| ApacheHttpSSRFVersion5.java:333:42:333:44 | uri : URI | ApacheHttpSSRFVersion5.java:333:42:333:55 | toString(...) | provenance | MaD:295 Sink:MaD:180 | +| ApacheHttpSSRFVersion5.java:336:39:336:41 | uri : URI | ApacheHttpSSRFVersion5.java:336:39:336:52 | toString(...) | provenance | MaD:295 Sink:MaD:182 | +| ApacheHttpSSRFVersion5.java:339:40:339:42 | uri : URI | ApacheHttpSSRFVersion5.java:339:40:339:53 | toString(...) | provenance | MaD:295 Sink:MaD:184 | +| ApacheHttpSSRFVersion5.java:342:43:342:45 | uri : URI | ApacheHttpSSRFVersion5.java:342:43:342:56 | toString(...) | provenance | MaD:295 Sink:MaD:186 | +| ApacheHttpSSRFVersion5.java:345:41:345:43 | uri : URI | ApacheHttpSSRFVersion5.java:345:41:345:54 | toString(...) | provenance | MaD:295 Sink:MaD:188 | +| ApacheHttpSSRFVersion5.java:348:40:348:42 | uri : URI | ApacheHttpSSRFVersion5.java:348:40:348:53 | toString(...) | provenance | MaD:295 Sink:MaD:190 | +| ApacheHttpSSRFVersion5.java:351:39:351:41 | uri : URI | ApacheHttpSSRFVersion5.java:351:39:351:52 | toString(...) | provenance | MaD:295 Sink:MaD:192 | +| ApacheHttpSSRFVersion5.java:356:48:356:50 | uri : URI | ApacheHttpSSRFVersion5.java:356:48:356:61 | toString(...) | provenance | MaD:295 Sink:MaD:205 | +| ApacheHttpSSRFVersion5.java:359:41:359:43 | uri : URI | ApacheHttpSSRFVersion5.java:359:41:359:54 | toString(...) | provenance | MaD:295 Sink:MaD:194 | +| ApacheHttpSSRFVersion5.java:372:30:372:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:373:31:373:37 | uriSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:373:23:373:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:380:57:380:59 | uri | provenance | Sink:MaD:197 | | ApacheHttpSSRFVersion5.java:373:23:373:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:382:51:382:53 | uri | provenance | Sink:MaD:199 | | ApacheHttpSSRFVersion5.java:373:23:373:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:386:50:386:52 | uri | provenance | Sink:MaD:201 | @@ -677,372 +697,372 @@ edges | ApacheHttpSSRFVersion5.java:373:23:373:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:390:24:390:26 | uri | provenance | Sink:MaD:207 | | ApacheHttpSSRFVersion5.java:373:23:373:38 | new URI(...) : URI | ApacheHttpSSRFVersion5.java:394:24:394:26 | uri | provenance | Sink:MaD:207 | | ApacheHttpSSRFVersion5.java:373:31:373:37 | uriSink : String | ApacheHttpSSRFVersion5.java:373:23:373:38 | new URI(...) : URI | provenance | Config | -| ApacheHttpSSRFVersion5.java:373:31:373:37 | uriSink : String | ApacheHttpSSRFVersion5.java:373:23:373:38 | new URI(...) : URI | provenance | MaD:285 | -| ApacheHttpSSRFVersion5.java:375:31:375:58 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:376:42:376:49 | hostSink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:373:31:373:37 | uriSink : String | ApacheHttpSSRFVersion5.java:373:23:373:38 | new URI(...) : URI | provenance | MaD:293 | +| ApacheHttpSSRFVersion5.java:375:31:375:58 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:376:42:376:49 | hostSink : String | provenance | Src:MaD:285 | | ApacheHttpSSRFVersion5.java:376:29:376:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:379:57:379:60 | host | provenance | Sink:MaD:196 | | ApacheHttpSSRFVersion5.java:376:29:376:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:381:51:381:54 | host | provenance | Sink:MaD:198 | | ApacheHttpSSRFVersion5.java:376:29:376:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:385:50:385:53 | host | provenance | Sink:MaD:200 | | ApacheHttpSSRFVersion5.java:376:29:376:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:387:44:387:47 | host | provenance | Sink:MaD:202 | -| ApacheHttpSSRFVersion5.java:376:42:376:49 | hostSink : String | ApacheHttpSSRFVersion5.java:376:29:376:50 | new HttpHost(...) : HttpHost | provenance | MaD:295 | -| JakartaWsSSRF.java:14:22:14:48 | getParameter(...) : String | JakartaWsSSRF.java:15:23:15:25 | url | provenance | Src:MaD:277 Sink:MaD:3 | -| JavaNetHttpSSRF.java:25:27:25:53 | getParameter(...) : String | JavaNetHttpSSRF.java:26:31:26:34 | sink : String | provenance | Src:MaD:277 | +| ApacheHttpSSRFVersion5.java:376:42:376:49 | hostSink : String | ApacheHttpSSRFVersion5.java:376:29:376:50 | new HttpHost(...) : HttpHost | provenance | MaD:303 | +| JakartaWsSSRF.java:14:22:14:48 | getParameter(...) : String | JakartaWsSSRF.java:15:23:15:25 | url | provenance | Src:MaD:285 Sink:MaD:3 | +| JavaNetHttpSSRF.java:25:27:25:53 | getParameter(...) : String | JavaNetHttpSSRF.java:26:31:26:34 | sink : String | provenance | Src:MaD:285 | | JavaNetHttpSSRF.java:26:23:26:35 | new URI(...) : URI | JavaNetHttpSSRF.java:39:59:39:61 | uri | provenance | Sink:MaD:6 | | JavaNetHttpSSRF.java:26:31:26:34 | sink : String | JavaNetHttpSSRF.java:26:23:26:35 | new URI(...) : URI | provenance | Config | -| JavaNetHttpSSRF.java:26:31:26:34 | sink : String | JavaNetHttpSSRF.java:26:23:26:35 | new URI(...) : URI | provenance | MaD:285 | +| JavaNetHttpSSRF.java:26:31:26:34 | sink : String | JavaNetHttpSSRF.java:26:23:26:35 | new URI(...) : URI | provenance | MaD:293 | | JavaNetHttpSSRF.java:26:31:26:34 | sink : String | JavaNetHttpSSRF.java:27:40:27:43 | sink : String | provenance | | | JavaNetHttpSSRF.java:27:24:27:57 | new URI(...) : URI | JavaNetHttpSSRF.java:38:65:38:68 | uri2 | provenance | Sink:MaD:5 | | JavaNetHttpSSRF.java:27:40:27:43 | sink : String | JavaNetHttpSSRF.java:27:24:27:57 | new URI(...) : URI | provenance | Config | -| JavaNetHttpSSRF.java:27:40:27:43 | sink : String | JavaNetHttpSSRF.java:27:24:27:57 | new URI(...) : URI | provenance | MaD:286 | +| JavaNetHttpSSRF.java:27:40:27:43 | sink : String | JavaNetHttpSSRF.java:27:24:27:57 | new URI(...) : URI | provenance | MaD:294 | | JavaNetHttpSSRF.java:27:40:27:43 | sink : String | JavaNetHttpSSRF.java:28:32:28:35 | sink : String | provenance | | | JavaNetHttpSSRF.java:28:24:28:36 | new URL(...) : URL | JavaNetHttpSSRF.java:30:32:30:35 | url1 | provenance | Sink:MaD:9 | | JavaNetHttpSSRF.java:28:24:28:36 | new URL(...) : URL | JavaNetHttpSSRF.java:33:32:33:35 | url1 | provenance | Sink:MaD:9 | | JavaNetHttpSSRF.java:28:24:28:36 | new URL(...) : URL | JavaNetHttpSSRF.java:34:30:34:33 | url1 | provenance | Sink:MaD:10 | | JavaNetHttpSSRF.java:28:32:28:35 | sink : String | JavaNetHttpSSRF.java:28:24:28:36 | new URL(...) : URL | provenance | Config | -| JavaNetHttpSSRF.java:28:32:28:35 | sink : String | JavaNetHttpSSRF.java:28:24:28:36 | new URL(...) : URL | provenance | MaD:289 | -| JaxWsSSRF.java:14:22:14:48 | getParameter(...) : String | JaxWsSSRF.java:15:23:15:25 | url | provenance | Src:MaD:277 Sink:MaD:23 | -| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:26:28:26:34 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:17 | -| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:28:41:28:47 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:18 | -| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:29:41:29:47 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:20 | -| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:30:41:30:47 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:19 | -| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:32:27:32:33 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:242 | -| JdbcUrlSSRF.java:40:26:40:56 | getParameter(...) : String | JdbcUrlSSRF.java:43:27:43:33 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:2 | -| JdbcUrlSSRF.java:40:26:40:56 | getParameter(...) : String | JdbcUrlSSRF.java:48:23:48:29 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:2 | -| JdbcUrlSSRF.java:40:26:40:56 | getParameter(...) : String | JdbcUrlSSRF.java:52:38:52:44 | jdbcUrl : String | provenance | Src:MaD:277 | +| JavaNetHttpSSRF.java:28:32:28:35 | sink : String | JavaNetHttpSSRF.java:28:24:28:36 | new URL(...) : URL | provenance | MaD:297 | +| JaxWsSSRF.java:14:22:14:48 | getParameter(...) : String | JaxWsSSRF.java:15:23:15:25 | url | provenance | Src:MaD:285 Sink:MaD:23 | +| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:26:28:26:34 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:17 | +| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:28:41:28:47 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:18 | +| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:29:41:29:47 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:20 | +| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:30:41:30:47 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:19 | +| JdbcUrlSSRF.java:21:26:21:56 | getParameter(...) : String | JdbcUrlSSRF.java:32:27:32:33 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:250 | +| JdbcUrlSSRF.java:40:26:40:56 | getParameter(...) : String | JdbcUrlSSRF.java:43:27:43:33 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:2 | +| JdbcUrlSSRF.java:40:26:40:56 | getParameter(...) : String | JdbcUrlSSRF.java:48:23:48:29 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:2 | +| JdbcUrlSSRF.java:40:26:40:56 | getParameter(...) : String | JdbcUrlSSRF.java:52:38:52:44 | jdbcUrl : String | provenance | Src:MaD:285 | | JdbcUrlSSRF.java:52:9:52:13 | props : Properties | JdbcUrlSSRF.java:54:49:54:53 | props | provenance | Sink:MaD:1 | | JdbcUrlSSRF.java:52:9:52:13 | props [post update] : Properties [] : String | JdbcUrlSSRF.java:54:49:54:53 | props | provenance | Sink:MaD:1 | | JdbcUrlSSRF.java:52:38:52:44 | jdbcUrl : String | JdbcUrlSSRF.java:52:9:52:13 | props : Properties | provenance | Config | -| JdbcUrlSSRF.java:52:38:52:44 | jdbcUrl : String | JdbcUrlSSRF.java:52:9:52:13 | props [post update] : Properties [] : String | provenance | MaD:294 | -| JdbcUrlSSRF.java:60:26:60:56 | getParameter(...) : String | JdbcUrlSSRF.java:65:27:65:33 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:257 | -| JdbcUrlSSRF.java:60:26:60:56 | getParameter(...) : String | JdbcUrlSSRF.java:67:75:67:81 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:258 | -| JdbcUrlSSRF.java:60:26:60:56 | getParameter(...) : String | JdbcUrlSSRF.java:70:75:70:81 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:260 | -| JdbcUrlSSRF.java:60:26:60:56 | getParameter(...) : String | JdbcUrlSSRF.java:73:75:73:81 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:259 | -| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:82:21:82:27 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:235 | -| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:83:21:83:27 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:236 | -| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:84:21:84:27 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:237 | -| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:86:19:86:25 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:238 | -| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:87:19:87:25 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:239 | -| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:88:19:88:25 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:240 | -| ReactiveWebClientSSRF.java:15:26:15:52 | getParameter(...) : String | ReactiveWebClientSSRF.java:16:52:16:54 | url | provenance | Src:MaD:277 Sink:MaD:274 | -| ReactiveWebClientSSRF.java:32:26:32:52 | getParameter(...) : String | ReactiveWebClientSSRF.java:35:30:35:32 | url | provenance | Src:MaD:277 Sink:MaD:273 | +| JdbcUrlSSRF.java:52:38:52:44 | jdbcUrl : String | JdbcUrlSSRF.java:52:9:52:13 | props [post update] : Properties [] : String | provenance | MaD:302 | +| JdbcUrlSSRF.java:60:26:60:56 | getParameter(...) : String | JdbcUrlSSRF.java:65:27:65:33 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:265 | +| JdbcUrlSSRF.java:60:26:60:56 | getParameter(...) : String | JdbcUrlSSRF.java:67:75:67:81 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:266 | +| JdbcUrlSSRF.java:60:26:60:56 | getParameter(...) : String | JdbcUrlSSRF.java:70:75:70:81 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:268 | +| JdbcUrlSSRF.java:60:26:60:56 | getParameter(...) : String | JdbcUrlSSRF.java:73:75:73:81 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:267 | +| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:82:21:82:27 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:243 | +| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:83:21:83:27 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:244 | +| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:84:21:84:27 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:245 | +| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:86:19:86:25 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:246 | +| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:87:19:87:25 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:247 | +| JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:88:19:88:25 | jdbcUrl | provenance | Src:MaD:285 Sink:MaD:248 | +| ReactiveWebClientSSRF.java:15:26:15:52 | getParameter(...) : String | ReactiveWebClientSSRF.java:16:52:16:54 | url | provenance | Src:MaD:285 Sink:MaD:282 | +| ReactiveWebClientSSRF.java:32:26:32:52 | getParameter(...) : String | ReactiveWebClientSSRF.java:35:30:35:32 | url | provenance | Src:MaD:285 Sink:MaD:281 | | SanitizationTests.java:22:23:22:58 | new URI(...) : URI | SanitizationTests.java:25:52:25:54 | uri | provenance | Sink:MaD:6 | | SanitizationTests.java:22:23:22:58 | new URI(...) : URI | SanitizationTests.java:25:52:25:54 | uri : URI | provenance | | -| SanitizationTests.java:22:31:22:57 | getParameter(...) : String | SanitizationTests.java:22:23:22:58 | new URI(...) : URI | provenance | Src:MaD:277 Config | -| SanitizationTests.java:22:31:22:57 | getParameter(...) : String | SanitizationTests.java:22:23:22:58 | new URI(...) : URI | provenance | Src:MaD:277 MaD:285 | -| SanitizationTests.java:25:29:25:55 | newBuilder(...) : Builder | SanitizationTests.java:25:29:25:63 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:22:31:22:57 | getParameter(...) : String | SanitizationTests.java:22:23:22:58 | new URI(...) : URI | provenance | Src:MaD:285 Config | +| SanitizationTests.java:22:31:22:57 | getParameter(...) : String | SanitizationTests.java:22:23:22:58 | new URI(...) : URI | provenance | Src:MaD:285 MaD:293 | +| SanitizationTests.java:25:29:25:55 | newBuilder(...) : Builder | SanitizationTests.java:25:29:25:63 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:25:29:25:63 | build(...) : HttpRequest | SanitizationTests.java:26:25:26:25 | r | provenance | Sink:MaD:4 | -| SanitizationTests.java:25:52:25:54 | uri : URI | SanitizationTests.java:25:29:25:55 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:78:33:78:63 | getParameter(...) : String | SanitizationTests.java:79:67:79:76 | unsafeUri3 : String | provenance | Src:MaD:277 | -| SanitizationTests.java:79:36:79:78 | newBuilder(...) : Builder | SanitizationTests.java:79:36:79:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:25:52:25:54 | uri : URI | SanitizationTests.java:25:29:25:55 | newBuilder(...) : Builder | provenance | MaD:292 | +| SanitizationTests.java:78:33:78:63 | getParameter(...) : String | SanitizationTests.java:79:67:79:76 | unsafeUri3 : String | provenance | Src:MaD:285 | +| SanitizationTests.java:79:36:79:78 | newBuilder(...) : Builder | SanitizationTests.java:79:36:79:86 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:79:36:79:86 | build(...) : HttpRequest | SanitizationTests.java:80:25:80:32 | unsafer3 | provenance | Sink:MaD:4 | -| SanitizationTests.java:79:59:79:77 | new URI(...) : URI | SanitizationTests.java:79:36:79:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:79:59:79:77 | new URI(...) : URI | SanitizationTests.java:79:36:79:78 | newBuilder(...) : Builder | provenance | MaD:292 | | SanitizationTests.java:79:67:79:76 | unsafeUri3 : String | SanitizationTests.java:79:59:79:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:79:67:79:76 | unsafeUri3 : String | SanitizationTests.java:79:59:79:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:79:67:79:76 | unsafeUri3 : String | SanitizationTests.java:79:59:79:77 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:79:67:79:76 | unsafeUri3 : String | SanitizationTests.java:79:59:79:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:79:67:79:76 | unsafeUri3 : String | SanitizationTests.java:79:59:79:77 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:82:49:82:79 | getParameter(...) : String | SanitizationTests.java:83:67:83:76 | unsafeUri4 : String | provenance | Src:MaD:277 | -| SanitizationTests.java:83:36:83:78 | newBuilder(...) : Builder | SanitizationTests.java:83:36:83:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:79:67:79:76 | unsafeUri3 : String | SanitizationTests.java:79:59:79:77 | new URI(...) : URI | provenance | MaD:293 | +| SanitizationTests.java:82:49:82:79 | getParameter(...) : String | SanitizationTests.java:83:67:83:76 | unsafeUri4 : String | provenance | Src:MaD:285 | +| SanitizationTests.java:83:36:83:78 | newBuilder(...) : Builder | SanitizationTests.java:83:36:83:86 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:83:36:83:86 | build(...) : HttpRequest | SanitizationTests.java:84:25:84:32 | unsafer4 | provenance | Sink:MaD:4 | -| SanitizationTests.java:83:59:83:77 | new URI(...) : URI | SanitizationTests.java:83:36:83:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:83:59:83:77 | new URI(...) : URI | SanitizationTests.java:83:36:83:78 | newBuilder(...) : Builder | provenance | MaD:292 | | SanitizationTests.java:83:67:83:76 | unsafeUri4 : String | SanitizationTests.java:83:59:83:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:83:67:83:76 | unsafeUri4 : String | SanitizationTests.java:83:59:83:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:83:67:83:76 | unsafeUri4 : String | SanitizationTests.java:83:59:83:77 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:83:67:83:76 | unsafeUri4 : String | SanitizationTests.java:83:59:83:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:83:67:83:76 | unsafeUri4 : String | SanitizationTests.java:83:59:83:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:83:67:83:76 | unsafeUri4 : String | SanitizationTests.java:83:59:83:77 | new URI(...) : URI | provenance | MaD:293 | | SanitizationTests.java:87:13:87:22 | unsafeUri5 [post update] : StringBuilder | SanitizationTests.java:88:67:88:76 | unsafeUri5 : StringBuilder | provenance | | -| SanitizationTests.java:87:31:87:61 | getParameter(...) : String | SanitizationTests.java:87:13:87:22 | unsafeUri5 [post update] : StringBuilder | provenance | Src:MaD:277 MaD:278 | -| SanitizationTests.java:88:36:88:89 | newBuilder(...) : Builder | SanitizationTests.java:88:36:88:97 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:87:31:87:61 | getParameter(...) : String | SanitizationTests.java:87:13:87:22 | unsafeUri5 [post update] : StringBuilder | provenance | Src:MaD:285 MaD:286 | +| SanitizationTests.java:88:36:88:89 | newBuilder(...) : Builder | SanitizationTests.java:88:36:88:97 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:88:36:88:97 | build(...) : HttpRequest | SanitizationTests.java:89:25:89:32 | unsafer5 | provenance | Sink:MaD:4 | -| SanitizationTests.java:88:59:88:88 | new URI(...) : URI | SanitizationTests.java:88:36:88:89 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:88:67:88:76 | unsafeUri5 : StringBuilder | SanitizationTests.java:88:67:88:87 | toString(...) : String | provenance | MaD:280 | +| SanitizationTests.java:88:59:88:88 | new URI(...) : URI | SanitizationTests.java:88:36:88:89 | newBuilder(...) : Builder | provenance | MaD:292 | +| SanitizationTests.java:88:67:88:76 | unsafeUri5 : StringBuilder | SanitizationTests.java:88:67:88:87 | toString(...) : String | provenance | MaD:288 | | SanitizationTests.java:88:67:88:87 | toString(...) : String | SanitizationTests.java:88:59:88:88 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:88:67:88:87 | toString(...) : String | SanitizationTests.java:88:59:88:88 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:88:67:88:87 | toString(...) : String | SanitizationTests.java:88:59:88:88 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:88:67:88:87 | toString(...) : String | SanitizationTests.java:88:59:88:88 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:88:67:88:87 | toString(...) : String | SanitizationTests.java:88:59:88:88 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:88:67:88:87 | toString(...) : String | SanitizationTests.java:88:59:88:88 | new URI(...) : URI | provenance | MaD:293 | | SanitizationTests.java:91:40:91:87 | new StringBuilder(...) : StringBuilder | SanitizationTests.java:93:68:93:77 | unafeUri5a : StringBuilder | provenance | | -| SanitizationTests.java:91:58:91:86 | getParameter(...) : String | SanitizationTests.java:91:40:91:87 | new StringBuilder(...) : StringBuilder | provenance | Src:MaD:277 MaD:282 | -| SanitizationTests.java:93:37:93:90 | newBuilder(...) : Builder | SanitizationTests.java:93:37:93:98 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:91:58:91:86 | getParameter(...) : String | SanitizationTests.java:91:40:91:87 | new StringBuilder(...) : StringBuilder | provenance | Src:MaD:285 MaD:290 | +| SanitizationTests.java:93:37:93:90 | newBuilder(...) : Builder | SanitizationTests.java:93:37:93:98 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:93:37:93:98 | build(...) : HttpRequest | SanitizationTests.java:94:25:94:33 | unsafer5a | provenance | Sink:MaD:4 | -| SanitizationTests.java:93:60:93:89 | new URI(...) : URI | SanitizationTests.java:93:37:93:90 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:93:68:93:77 | unafeUri5a : StringBuilder | SanitizationTests.java:93:68:93:88 | toString(...) : String | provenance | MaD:280 | +| SanitizationTests.java:93:60:93:89 | new URI(...) : URI | SanitizationTests.java:93:37:93:90 | newBuilder(...) : Builder | provenance | MaD:292 | +| SanitizationTests.java:93:68:93:77 | unafeUri5a : StringBuilder | SanitizationTests.java:93:68:93:88 | toString(...) : String | provenance | MaD:288 | | SanitizationTests.java:93:68:93:88 | toString(...) : String | SanitizationTests.java:93:60:93:89 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:93:68:93:88 | toString(...) : String | SanitizationTests.java:93:60:93:89 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:93:68:93:88 | toString(...) : String | SanitizationTests.java:93:60:93:89 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:93:68:93:88 | toString(...) : String | SanitizationTests.java:93:60:93:89 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:93:68:93:88 | toString(...) : String | SanitizationTests.java:93:60:93:89 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:93:68:93:88 | toString(...) : String | SanitizationTests.java:93:60:93:89 | new URI(...) : URI | provenance | MaD:293 | | SanitizationTests.java:96:41:96:105 | append(...) : StringBuilder | SanitizationTests.java:98:68:98:78 | unsafeUri5b : StringBuilder | provenance | | -| SanitizationTests.java:96:42:96:89 | new StringBuilder(...) : StringBuilder | SanitizationTests.java:96:41:96:105 | append(...) : StringBuilder | provenance | MaD:279 | -| SanitizationTests.java:96:60:96:88 | getParameter(...) : String | SanitizationTests.java:96:42:96:89 | new StringBuilder(...) : StringBuilder | provenance | Src:MaD:277 MaD:282 | -| SanitizationTests.java:98:37:98:91 | newBuilder(...) : Builder | SanitizationTests.java:98:37:98:99 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:96:42:96:89 | new StringBuilder(...) : StringBuilder | SanitizationTests.java:96:41:96:105 | append(...) : StringBuilder | provenance | MaD:287 | +| SanitizationTests.java:96:60:96:88 | getParameter(...) : String | SanitizationTests.java:96:42:96:89 | new StringBuilder(...) : StringBuilder | provenance | Src:MaD:285 MaD:290 | +| SanitizationTests.java:98:37:98:91 | newBuilder(...) : Builder | SanitizationTests.java:98:37:98:99 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:98:37:98:99 | build(...) : HttpRequest | SanitizationTests.java:99:25:99:33 | unsafer5b | provenance | Sink:MaD:4 | -| SanitizationTests.java:98:60:98:90 | new URI(...) : URI | SanitizationTests.java:98:37:98:91 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:98:68:98:78 | unsafeUri5b : StringBuilder | SanitizationTests.java:98:68:98:89 | toString(...) : String | provenance | MaD:280 | +| SanitizationTests.java:98:60:98:90 | new URI(...) : URI | SanitizationTests.java:98:37:98:91 | newBuilder(...) : Builder | provenance | MaD:292 | +| SanitizationTests.java:98:68:98:78 | unsafeUri5b : StringBuilder | SanitizationTests.java:98:68:98:89 | toString(...) : String | provenance | MaD:288 | | SanitizationTests.java:98:68:98:89 | toString(...) : String | SanitizationTests.java:98:60:98:90 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:98:68:98:89 | toString(...) : String | SanitizationTests.java:98:60:98:90 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:98:68:98:89 | toString(...) : String | SanitizationTests.java:98:60:98:90 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:98:68:98:89 | toString(...) : String | SanitizationTests.java:98:60:98:90 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:98:68:98:89 | toString(...) : String | SanitizationTests.java:98:60:98:90 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:98:68:98:89 | toString(...) : String | SanitizationTests.java:98:60:98:90 | new URI(...) : URI | provenance | MaD:293 | | SanitizationTests.java:101:41:101:106 | append(...) : StringBuilder | SanitizationTests.java:103:68:103:78 | unsafeUri5c : StringBuilder | provenance | | -| SanitizationTests.java:101:77:101:105 | getParameter(...) : String | SanitizationTests.java:101:41:101:106 | append(...) : StringBuilder | provenance | Src:MaD:277 MaD:278+MaD:279 | -| SanitizationTests.java:103:37:103:91 | newBuilder(...) : Builder | SanitizationTests.java:103:37:103:99 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:101:77:101:105 | getParameter(...) : String | SanitizationTests.java:101:41:101:106 | append(...) : StringBuilder | provenance | Src:MaD:285 MaD:286+MaD:287 | +| SanitizationTests.java:103:37:103:91 | newBuilder(...) : Builder | SanitizationTests.java:103:37:103:99 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:103:37:103:99 | build(...) : HttpRequest | SanitizationTests.java:104:25:104:33 | unsafer5c | provenance | Sink:MaD:4 | -| SanitizationTests.java:103:60:103:90 | new URI(...) : URI | SanitizationTests.java:103:37:103:91 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:103:68:103:78 | unsafeUri5c : StringBuilder | SanitizationTests.java:103:68:103:89 | toString(...) : String | provenance | MaD:280 | +| SanitizationTests.java:103:60:103:90 | new URI(...) : URI | SanitizationTests.java:103:37:103:91 | newBuilder(...) : Builder | provenance | MaD:292 | +| SanitizationTests.java:103:68:103:78 | unsafeUri5c : StringBuilder | SanitizationTests.java:103:68:103:89 | toString(...) : String | provenance | MaD:288 | | SanitizationTests.java:103:68:103:89 | toString(...) : String | SanitizationTests.java:103:60:103:90 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:103:68:103:89 | toString(...) : String | SanitizationTests.java:103:60:103:90 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:103:68:103:89 | toString(...) : String | SanitizationTests.java:103:60:103:90 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:103:68:103:89 | toString(...) : String | SanitizationTests.java:103:60:103:90 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:103:68:103:89 | toString(...) : String | SanitizationTests.java:103:60:103:90 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:103:68:103:89 | toString(...) : String | SanitizationTests.java:103:60:103:90 | new URI(...) : URI | provenance | MaD:293 | | SanitizationTests.java:106:33:106:104 | format(...) : String | SanitizationTests.java:107:67:107:76 | unsafeUri6 : String | provenance | | -| SanitizationTests.java:106:33:106:104 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:106:33:106:104 | format(...) : String | provenance | MaD:281 | -| SanitizationTests.java:106:73:106:103 | getParameter(...) : String | SanitizationTests.java:106:33:106:104 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | -| SanitizationTests.java:107:36:107:78 | newBuilder(...) : Builder | SanitizationTests.java:107:36:107:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:106:33:106:104 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:106:33:106:104 | format(...) : String | provenance | MaD:289 | +| SanitizationTests.java:106:73:106:103 | getParameter(...) : String | SanitizationTests.java:106:33:106:104 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:285 | +| SanitizationTests.java:107:36:107:78 | newBuilder(...) : Builder | SanitizationTests.java:107:36:107:86 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:107:36:107:86 | build(...) : HttpRequest | SanitizationTests.java:108:25:108:32 | unsafer6 | provenance | Sink:MaD:4 | -| SanitizationTests.java:107:59:107:77 | new URI(...) : URI | SanitizationTests.java:107:36:107:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:107:59:107:77 | new URI(...) : URI | SanitizationTests.java:107:36:107:78 | newBuilder(...) : Builder | provenance | MaD:292 | | SanitizationTests.java:107:67:107:76 | unsafeUri6 : String | SanitizationTests.java:107:59:107:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:107:67:107:76 | unsafeUri6 : String | SanitizationTests.java:107:59:107:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:107:67:107:76 | unsafeUri6 : String | SanitizationTests.java:107:59:107:77 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:107:67:107:76 | unsafeUri6 : String | SanitizationTests.java:107:59:107:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:107:67:107:76 | unsafeUri6 : String | SanitizationTests.java:107:59:107:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:107:67:107:76 | unsafeUri6 : String | SanitizationTests.java:107:59:107:77 | new URI(...) : URI | provenance | MaD:293 | | SanitizationTests.java:110:33:110:110 | format(...) : String | SanitizationTests.java:111:67:111:76 | unsafeUri7 : String | provenance | | -| SanitizationTests.java:110:33:110:110 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:110:33:110:110 | format(...) : String | provenance | MaD:281 | -| SanitizationTests.java:110:56:110:86 | getParameter(...) : String | SanitizationTests.java:110:33:110:110 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | -| SanitizationTests.java:111:36:111:78 | newBuilder(...) : Builder | SanitizationTests.java:111:36:111:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:110:33:110:110 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:110:33:110:110 | format(...) : String | provenance | MaD:289 | +| SanitizationTests.java:110:56:110:86 | getParameter(...) : String | SanitizationTests.java:110:33:110:110 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:285 | +| SanitizationTests.java:111:36:111:78 | newBuilder(...) : Builder | SanitizationTests.java:111:36:111:86 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:111:36:111:86 | build(...) : HttpRequest | SanitizationTests.java:112:25:112:32 | unsafer7 | provenance | Sink:MaD:4 | -| SanitizationTests.java:111:59:111:77 | new URI(...) : URI | SanitizationTests.java:111:36:111:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:111:59:111:77 | new URI(...) : URI | SanitizationTests.java:111:36:111:78 | newBuilder(...) : Builder | provenance | MaD:292 | | SanitizationTests.java:111:67:111:76 | unsafeUri7 : String | SanitizationTests.java:111:59:111:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:111:67:111:76 | unsafeUri7 : String | SanitizationTests.java:111:59:111:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:111:67:111:76 | unsafeUri7 : String | SanitizationTests.java:111:59:111:77 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:111:67:111:76 | unsafeUri7 : String | SanitizationTests.java:111:59:111:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:111:67:111:76 | unsafeUri7 : String | SanitizationTests.java:111:59:111:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:111:67:111:76 | unsafeUri7 : String | SanitizationTests.java:111:59:111:77 | new URI(...) : URI | provenance | MaD:293 | | SanitizationTests.java:114:33:114:110 | format(...) : String | SanitizationTests.java:115:67:115:76 | unsafeUri8 : String | provenance | | -| SanitizationTests.java:114:33:114:110 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:114:33:114:110 | format(...) : String | provenance | MaD:281 | -| SanitizationTests.java:114:55:114:85 | getParameter(...) : String | SanitizationTests.java:114:33:114:110 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | -| SanitizationTests.java:115:36:115:78 | newBuilder(...) : Builder | SanitizationTests.java:115:36:115:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:114:33:114:110 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:114:33:114:110 | format(...) : String | provenance | MaD:289 | +| SanitizationTests.java:114:55:114:85 | getParameter(...) : String | SanitizationTests.java:114:33:114:110 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:285 | +| SanitizationTests.java:115:36:115:78 | newBuilder(...) : Builder | SanitizationTests.java:115:36:115:86 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:115:36:115:86 | build(...) : HttpRequest | SanitizationTests.java:116:25:116:32 | unsafer8 | provenance | Sink:MaD:4 | -| SanitizationTests.java:115:59:115:77 | new URI(...) : URI | SanitizationTests.java:115:36:115:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:115:59:115:77 | new URI(...) : URI | SanitizationTests.java:115:36:115:78 | newBuilder(...) : Builder | provenance | MaD:292 | | SanitizationTests.java:115:67:115:76 | unsafeUri8 : String | SanitizationTests.java:115:59:115:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:115:67:115:76 | unsafeUri8 : String | SanitizationTests.java:115:59:115:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:115:67:115:76 | unsafeUri8 : String | SanitizationTests.java:115:59:115:77 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:115:67:115:76 | unsafeUri8 : String | SanitizationTests.java:115:59:115:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:115:67:115:76 | unsafeUri8 : String | SanitizationTests.java:115:59:115:77 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:118:33:118:63 | getParameter(...) : String | SanitizationTests.java:119:67:119:76 | unsafeUri9 : String | provenance | Src:MaD:277 | -| SanitizationTests.java:119:36:119:78 | newBuilder(...) : Builder | SanitizationTests.java:119:36:119:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:115:67:115:76 | unsafeUri8 : String | SanitizationTests.java:115:59:115:77 | new URI(...) : URI | provenance | MaD:293 | +| SanitizationTests.java:118:33:118:63 | getParameter(...) : String | SanitizationTests.java:119:67:119:76 | unsafeUri9 : String | provenance | Src:MaD:285 | +| SanitizationTests.java:119:36:119:78 | newBuilder(...) : Builder | SanitizationTests.java:119:36:119:86 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:119:36:119:86 | build(...) : HttpRequest | SanitizationTests.java:120:25:120:32 | unsafer9 | provenance | Sink:MaD:4 | -| SanitizationTests.java:119:59:119:77 | new URI(...) : URI | SanitizationTests.java:119:36:119:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:119:59:119:77 | new URI(...) : URI | SanitizationTests.java:119:36:119:78 | newBuilder(...) : Builder | provenance | MaD:292 | | SanitizationTests.java:119:67:119:76 | unsafeUri9 : String | SanitizationTests.java:119:59:119:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:119:67:119:76 | unsafeUri9 : String | SanitizationTests.java:119:59:119:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:119:67:119:76 | unsafeUri9 : String | SanitizationTests.java:119:59:119:77 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:119:67:119:76 | unsafeUri9 : String | SanitizationTests.java:119:59:119:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:119:67:119:76 | unsafeUri9 : String | SanitizationTests.java:119:59:119:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:119:67:119:76 | unsafeUri9 : String | SanitizationTests.java:119:59:119:77 | new URI(...) : URI | provenance | MaD:293 | | SanitizationTests.java:122:34:122:126 | format(...) : String | SanitizationTests.java:123:68:123:78 | unsafeUri10 : String | provenance | | -| SanitizationTests.java:122:34:122:126 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:122:34:122:126 | format(...) : String | provenance | MaD:281 | -| SanitizationTests.java:122:94:122:125 | getParameter(...) : String | SanitizationTests.java:122:34:122:126 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | -| SanitizationTests.java:123:37:123:80 | newBuilder(...) : Builder | SanitizationTests.java:123:37:123:88 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:122:34:122:126 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:122:34:122:126 | format(...) : String | provenance | MaD:289 | +| SanitizationTests.java:122:94:122:125 | getParameter(...) : String | SanitizationTests.java:122:34:122:126 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:285 | +| SanitizationTests.java:123:37:123:80 | newBuilder(...) : Builder | SanitizationTests.java:123:37:123:88 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:123:37:123:88 | build(...) : HttpRequest | SanitizationTests.java:124:25:124:33 | unsafer10 | provenance | Sink:MaD:4 | -| SanitizationTests.java:123:60:123:79 | new URI(...) : URI | SanitizationTests.java:123:37:123:80 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:123:60:123:79 | new URI(...) : URI | SanitizationTests.java:123:37:123:80 | newBuilder(...) : Builder | provenance | MaD:292 | | SanitizationTests.java:123:68:123:78 | unsafeUri10 : String | SanitizationTests.java:123:60:123:79 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:123:68:123:78 | unsafeUri10 : String | SanitizationTests.java:123:60:123:79 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:123:68:123:78 | unsafeUri10 : String | SanitizationTests.java:123:60:123:79 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:123:68:123:78 | unsafeUri10 : String | SanitizationTests.java:123:60:123:79 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:123:68:123:78 | unsafeUri10 : String | SanitizationTests.java:123:60:123:79 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:177:31:177:114 | newBuilder(...) : Builder | SanitizationTests.java:177:31:177:122 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:123:68:123:78 | unsafeUri10 : String | SanitizationTests.java:123:60:123:79 | new URI(...) : URI | provenance | MaD:293 | +| SanitizationTests.java:177:31:177:114 | newBuilder(...) : Builder | SanitizationTests.java:177:31:177:122 | build(...) : HttpRequest | provenance | MaD:291 | | SanitizationTests.java:177:31:177:122 | build(...) : HttpRequest | SanitizationTests.java:178:25:178:27 | r18 | provenance | Sink:MaD:4 | -| SanitizationTests.java:177:54:177:113 | new URI(...) : URI | SanitizationTests.java:177:31:177:114 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:177:54:177:113 | new URI(...) : URI | SanitizationTests.java:177:31:177:114 | newBuilder(...) : Builder | provenance | MaD:292 | | SanitizationTests.java:177:62:177:112 | getFromList(...) : String | SanitizationTests.java:177:54:177:113 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:177:62:177:112 | getFromList(...) : String | SanitizationTests.java:177:54:177:113 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:177:62:177:112 | getFromList(...) : String | SanitizationTests.java:177:54:177:113 | new URI(...) | provenance | MaD:293 Sink:MaD:6 | | SanitizationTests.java:177:62:177:112 | getFromList(...) : String | SanitizationTests.java:177:54:177:113 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:177:62:177:112 | getFromList(...) : String | SanitizationTests.java:177:54:177:113 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:177:74:177:111 | of(...) : List [] : String | SanitizationTests.java:177:62:177:112 | getFromList(...) : String | provenance | MaD:291 | +| SanitizationTests.java:177:62:177:112 | getFromList(...) : String | SanitizationTests.java:177:54:177:113 | new URI(...) : URI | provenance | MaD:293 | +| SanitizationTests.java:177:74:177:111 | of(...) : List [] : String | SanitizationTests.java:177:62:177:112 | getFromList(...) : String | provenance | MaD:299 | | SanitizationTests.java:177:74:177:111 | of(...) : List [] : String | SanitizationTests.java:199:31:199:112 | list : List [] : String | provenance | | -| SanitizationTests.java:177:82:177:110 | getParameter(...) : String | SanitizationTests.java:177:74:177:111 | of(...) : List [] : String | provenance | Src:MaD:277 MaD:290 | +| SanitizationTests.java:177:82:177:110 | getParameter(...) : String | SanitizationTests.java:177:74:177:111 | of(...) : List [] : String | provenance | Src:MaD:285 MaD:298 | | SanitizationTests.java:199:31:199:112 | list : List [] : String | SanitizationTests.java:200:16:200:19 | list : List [] : String | provenance | | -| SanitizationTests.java:200:16:200:19 | list : List [] : String | SanitizationTests.java:200:16:200:26 | get(...) : String | provenance | MaD:291 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:32:39:32:59 | ... + ... | provenance | Src:MaD:277 Sink:MaD:264 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:33:69:33:82 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:34:73:34:86 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:35:87:35:100 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:38:83:38:96 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:40:105:40:118 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:43:35:43:48 | fooResourceUrl | provenance | Src:MaD:277 Sink:MaD:262 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:44:91:44:104 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:45:95:45:108 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:46:109:46:122 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:49:105:49:118 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:51:127:51:140 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:54:34:54:47 | fooResourceUrl | provenance | Src:MaD:277 Sink:MaD:263 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:55:79:55:92 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:56:83:56:96 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:57:97:57:110 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:60:93:60:106 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:62:115:62:128 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:65:39:65:52 | fooResourceUrl | provenance | Src:MaD:277 Sink:MaD:265 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:66:69:66:82 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:67:73:67:86 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:68:87:68:100 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:71:83:71:96 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:73:105:73:118 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:76:41:76:54 | fooResourceUrl | provenance | Src:MaD:277 Sink:MaD:268 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:77:93:77:106 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:78:97:78:110 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:79:111:79:124 | fooResourceUrl | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:82:107:82:120 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:84:129:84:142 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | provenance | Src:MaD:277 | -| SpringSSRF.java:38:83:38:96 | fooResourceUrl : String | SpringSSRF.java:38:69:38:97 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:40:105:40:118 | fooResourceUrl : String | SpringSSRF.java:40:69:40:119 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:49:105:49:118 | fooResourceUrl : String | SpringSSRF.java:49:91:49:119 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:51:127:51:140 | fooResourceUrl : String | SpringSSRF.java:51:91:51:141 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:60:93:60:106 | fooResourceUrl : String | SpringSSRF.java:60:79:60:107 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:62:115:62:128 | fooResourceUrl : String | SpringSSRF.java:62:79:62:129 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:71:83:71:96 | fooResourceUrl : String | SpringSSRF.java:71:69:71:97 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:73:105:73:118 | fooResourceUrl : String | SpringSSRF.java:73:69:73:119 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:82:107:82:120 | fooResourceUrl : String | SpringSSRF.java:82:93:82:121 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:84:129:84:142 | fooResourceUrl : String | SpringSSRF.java:84:93:84:143 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:87:40:87:62 | new URI(...) | provenance | Config Sink:MaD:269 | -| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:87:40:87:62 | new URI(...) | provenance | MaD:285 Sink:MaD:269 | +| SanitizationTests.java:200:16:200:19 | list : List [] : String | SanitizationTests.java:200:16:200:26 | get(...) : String | provenance | MaD:299 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:32:39:32:59 | ... + ... | provenance | Src:MaD:285 Sink:MaD:272 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:33:69:33:82 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:34:73:34:86 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:35:87:35:100 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:38:83:38:96 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:40:105:40:118 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:43:35:43:48 | fooResourceUrl | provenance | Src:MaD:285 Sink:MaD:270 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:44:91:44:104 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:45:95:45:108 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:46:109:46:122 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:49:105:49:118 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:51:127:51:140 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:54:34:54:47 | fooResourceUrl | provenance | Src:MaD:285 Sink:MaD:271 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:55:79:55:92 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:56:83:56:96 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:57:97:57:110 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:60:93:60:106 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:62:115:62:128 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:65:39:65:52 | fooResourceUrl | provenance | Src:MaD:285 Sink:MaD:273 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:66:69:66:82 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:67:73:67:86 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:68:87:68:100 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:71:83:71:96 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:73:105:73:118 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:76:41:76:54 | fooResourceUrl | provenance | Src:MaD:285 Sink:MaD:276 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:77:93:77:106 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:78:97:78:110 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:79:111:79:124 | fooResourceUrl | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:82:107:82:120 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:84:129:84:142 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | provenance | Src:MaD:285 | +| SpringSSRF.java:38:83:38:96 | fooResourceUrl : String | SpringSSRF.java:38:69:38:97 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:40:105:40:118 | fooResourceUrl : String | SpringSSRF.java:40:69:40:119 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:49:105:49:118 | fooResourceUrl : String | SpringSSRF.java:49:91:49:119 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:51:127:51:140 | fooResourceUrl : String | SpringSSRF.java:51:91:51:141 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:60:93:60:106 | fooResourceUrl : String | SpringSSRF.java:60:79:60:107 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:62:115:62:128 | fooResourceUrl : String | SpringSSRF.java:62:79:62:129 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:71:83:71:96 | fooResourceUrl : String | SpringSSRF.java:71:69:71:97 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:73:105:73:118 | fooResourceUrl : String | SpringSSRF.java:73:69:73:119 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:82:107:82:120 | fooResourceUrl : String | SpringSSRF.java:82:93:82:121 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:84:129:84:142 | fooResourceUrl : String | SpringSSRF.java:84:93:84:143 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:87:40:87:62 | new URI(...) | provenance | Config Sink:MaD:277 | +| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:87:40:87:62 | new URI(...) | provenance | MaD:293 Sink:MaD:277 | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:88:92:88:105 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:89:96:89:109 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:90:110:90:123 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:93:106:93:119 | fooResourceUrl : String | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:95:128:95:141 | fooResourceUrl : String | provenance | | -| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:98:42:98:55 | fooResourceUrl | provenance | Sink:MaD:270 | +| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:98:42:98:55 | fooResourceUrl | provenance | Sink:MaD:278 | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:99:80:99:93 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:100:84:100:97 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:101:98:101:111 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:104:94:104:107 | fooResourceUrl : String | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:106:116:106:129 | fooResourceUrl : String | provenance | | -| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:109:40:109:53 | fooResourceUrl | provenance | Sink:MaD:271 | +| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:109:40:109:53 | fooResourceUrl | provenance | Sink:MaD:279 | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:110:92:110:105 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:111:96:111:109 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:112:110:112:123 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:115:106:115:119 | fooResourceUrl : String | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:117:128:117:141 | fooResourceUrl : String | provenance | | -| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:120:30:120:43 | fooResourceUrl | provenance | Sink:MaD:272 | +| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:120:30:120:43 | fooResourceUrl | provenance | Sink:MaD:280 | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:121:68:121:81 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:122:72:122:85 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:123:86:123:99 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:126:82:126:95 | fooResourceUrl : String | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:128:104:128:117 | fooResourceUrl : String | provenance | | -| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:131:33:131:46 | fooResourceUrl | provenance | Sink:MaD:261 | +| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:131:33:131:46 | fooResourceUrl | provenance | Sink:MaD:269 | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:132:49:132:62 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:133:53:133:66 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:134:67:134:80 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:137:63:137:76 | fooResourceUrl : String | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:139:85:139:98 | fooResourceUrl : String | provenance | | -| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:142:41:142:54 | fooResourceUrl | provenance | Sink:MaD:266 | +| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:142:41:142:54 | fooResourceUrl | provenance | Sink:MaD:274 | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:143:57:143:70 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:144:61:144:74 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:145:75:145:88 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:148:71:148:84 | fooResourceUrl : String | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:150:93:150:106 | fooResourceUrl : String | provenance | | -| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:153:42:153:55 | fooResourceUrl | provenance | Sink:MaD:267 | +| SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:153:42:153:55 | fooResourceUrl | provenance | Sink:MaD:275 | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:154:58:154:71 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:155:62:155:75 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:156:76:156:89 | fooResourceUrl | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:159:72:159:85 | fooResourceUrl : String | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:161:94:161:107 | fooResourceUrl : String | provenance | | | SpringSSRF.java:87:48:87:61 | fooResourceUrl : String | SpringSSRF.java:166:35:166:48 | fooResourceUrl : String | provenance | | -| SpringSSRF.java:93:106:93:119 | fooResourceUrl : String | SpringSSRF.java:93:92:93:120 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:95:128:95:141 | fooResourceUrl : String | SpringSSRF.java:95:92:95:142 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:104:94:104:107 | fooResourceUrl : String | SpringSSRF.java:104:80:104:108 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:106:116:106:129 | fooResourceUrl : String | SpringSSRF.java:106:80:106:130 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:115:106:115:119 | fooResourceUrl : String | SpringSSRF.java:115:92:115:120 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:117:128:117:141 | fooResourceUrl : String | SpringSSRF.java:117:92:117:142 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:126:82:126:95 | fooResourceUrl : String | SpringSSRF.java:126:68:126:96 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:128:104:128:117 | fooResourceUrl : String | SpringSSRF.java:128:68:128:118 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:137:63:137:76 | fooResourceUrl : String | SpringSSRF.java:137:49:137:77 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:139:85:139:98 | fooResourceUrl : String | SpringSSRF.java:139:49:139:99 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:148:71:148:84 | fooResourceUrl : String | SpringSSRF.java:148:57:148:85 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:150:93:150:106 | fooResourceUrl : String | SpringSSRF.java:150:57:150:107 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:159:72:159:85 | fooResourceUrl : String | SpringSSRF.java:159:58:159:86 | of(...) | provenance | MaD:292 | -| SpringSSRF.java:161:94:161:107 | fooResourceUrl : String | SpringSSRF.java:161:58:161:108 | of(...) | provenance | MaD:293 | -| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:168:44:168:46 | uri | provenance | Sink:MaD:255 | -| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:170:35:170:37 | uri | provenance | Sink:MaD:250 | -| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:171:35:171:37 | uri | provenance | Sink:MaD:256 | -| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:172:38:172:40 | uri | provenance | Sink:MaD:249 | -| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:173:39:173:41 | uri | provenance | Sink:MaD:253 | -| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:174:37:174:39 | uri | provenance | Sink:MaD:254 | -| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:175:36:175:38 | uri | provenance | Sink:MaD:251 | -| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:176:44:176:46 | uri | provenance | Sink:MaD:252 | +| SpringSSRF.java:93:106:93:119 | fooResourceUrl : String | SpringSSRF.java:93:92:93:120 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:95:128:95:141 | fooResourceUrl : String | SpringSSRF.java:95:92:95:142 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:104:94:104:107 | fooResourceUrl : String | SpringSSRF.java:104:80:104:108 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:106:116:106:129 | fooResourceUrl : String | SpringSSRF.java:106:80:106:130 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:115:106:115:119 | fooResourceUrl : String | SpringSSRF.java:115:92:115:120 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:117:128:117:141 | fooResourceUrl : String | SpringSSRF.java:117:92:117:142 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:126:82:126:95 | fooResourceUrl : String | SpringSSRF.java:126:68:126:96 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:128:104:128:117 | fooResourceUrl : String | SpringSSRF.java:128:68:128:118 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:137:63:137:76 | fooResourceUrl : String | SpringSSRF.java:137:49:137:77 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:139:85:139:98 | fooResourceUrl : String | SpringSSRF.java:139:49:139:99 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:148:71:148:84 | fooResourceUrl : String | SpringSSRF.java:148:57:148:85 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:150:93:150:106 | fooResourceUrl : String | SpringSSRF.java:150:57:150:107 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:159:72:159:85 | fooResourceUrl : String | SpringSSRF.java:159:58:159:86 | of(...) | provenance | MaD:300 | +| SpringSSRF.java:161:94:161:107 | fooResourceUrl : String | SpringSSRF.java:161:58:161:108 | of(...) | provenance | MaD:301 | +| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:168:44:168:46 | uri | provenance | Sink:MaD:263 | +| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:170:35:170:37 | uri | provenance | Sink:MaD:258 | +| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:171:35:171:37 | uri | provenance | Sink:MaD:264 | +| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:172:38:172:40 | uri | provenance | Sink:MaD:257 | +| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:173:39:173:41 | uri | provenance | Sink:MaD:261 | +| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:174:37:174:39 | uri | provenance | Sink:MaD:262 | +| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:175:36:175:38 | uri | provenance | Sink:MaD:259 | +| SpringSSRF.java:166:27:166:49 | new URI(...) : URI | SpringSSRF.java:176:44:176:46 | uri | provenance | Sink:MaD:260 | | SpringSSRF.java:166:35:166:48 | fooResourceUrl : String | SpringSSRF.java:166:27:166:49 | new URI(...) : URI | provenance | Config | -| SpringSSRF.java:166:35:166:48 | fooResourceUrl : String | SpringSSRF.java:166:27:166:49 | new URI(...) : URI | provenance | MaD:285 | +| SpringSSRF.java:166:35:166:48 | fooResourceUrl : String | SpringSSRF.java:166:27:166:49 | new URI(...) : URI | provenance | MaD:293 | | SpringSSRF.java:166:35:166:48 | fooResourceUrl : String | SpringSSRF.java:179:35:179:48 | fooResourceUrl : String | provenance | | -| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:182:49:182:51 | uri | provenance | Sink:MaD:243 | -| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:183:58:183:60 | uri | provenance | Sink:MaD:244 | -| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:184:57:184:59 | uri | provenance | Sink:MaD:245 | -| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:185:66:185:68 | uri | provenance | Sink:MaD:247 | -| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:186:57:186:59 | uri | provenance | Sink:MaD:246 | -| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:187:66:187:68 | uri | provenance | Sink:MaD:248 | +| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:182:49:182:51 | uri | provenance | Sink:MaD:251 | +| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:183:58:183:60 | uri | provenance | Sink:MaD:252 | +| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:184:57:184:59 | uri | provenance | Sink:MaD:253 | +| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:185:66:185:68 | uri | provenance | Sink:MaD:255 | +| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:186:57:186:59 | uri | provenance | Sink:MaD:254 | +| SpringSSRF.java:179:27:179:49 | new URI(...) : URI | SpringSSRF.java:187:66:187:68 | uri | provenance | Sink:MaD:256 | | SpringSSRF.java:179:35:179:48 | fooResourceUrl : String | SpringSSRF.java:179:27:179:49 | new URI(...) : URI | provenance | Config | -| SpringSSRF.java:179:35:179:48 | fooResourceUrl : String | SpringSSRF.java:179:27:179:49 | new URI(...) : URI | provenance | MaD:285 | -| URLClassLoaderSSRF.java:16:26:16:52 | getParameter(...) : String | URLClassLoaderSSRF.java:17:31:17:33 | url : String | provenance | Src:MaD:277 | +| SpringSSRF.java:179:35:179:48 | fooResourceUrl : String | SpringSSRF.java:179:27:179:49 | new URI(...) : URI | provenance | MaD:293 | +| URLClassLoaderSSRF.java:16:26:16:52 | getParameter(...) : String | URLClassLoaderSSRF.java:17:31:17:33 | url : String | provenance | Src:MaD:285 | | URLClassLoaderSSRF.java:17:23:17:34 | new URI(...) : URI | URLClassLoaderSSRF.java:18:74:18:76 | uri : URI | provenance | | | URLClassLoaderSSRF.java:17:31:17:33 | url : String | URLClassLoaderSSRF.java:17:23:17:34 | new URI(...) : URI | provenance | Config | -| URLClassLoaderSSRF.java:17:31:17:33 | url : String | URLClassLoaderSSRF.java:17:23:17:34 | new URI(...) : URI | provenance | MaD:285 | +| URLClassLoaderSSRF.java:17:31:17:33 | url : String | URLClassLoaderSSRF.java:17:23:17:34 | new URI(...) : URI | provenance | MaD:293 | | URLClassLoaderSSRF.java:18:64:18:85 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:18:64:18:85 | new URL[] | provenance | Sink:MaD:13 | | URLClassLoaderSSRF.java:18:64:18:85 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:18:64:18:85 | new URL[] | provenance | Sink:MaD:13 | -| URLClassLoaderSSRF.java:18:74:18:76 | uri : URI | URLClassLoaderSSRF.java:18:74:18:84 | toURL(...) : URL | provenance | MaD:288 | +| URLClassLoaderSSRF.java:18:74:18:76 | uri : URI | URLClassLoaderSSRF.java:18:74:18:84 | toURL(...) : URL | provenance | MaD:296 | | URLClassLoaderSSRF.java:18:74:18:84 | toURL(...) : URL | URLClassLoaderSSRF.java:18:64:18:85 | {...} : URL[] [[]] : URL | provenance | | -| URLClassLoaderSSRF.java:28:26:28:52 | getParameter(...) : String | URLClassLoaderSSRF.java:29:31:29:33 | url : String | provenance | Src:MaD:277 | +| URLClassLoaderSSRF.java:28:26:28:52 | getParameter(...) : String | URLClassLoaderSSRF.java:29:31:29:33 | url : String | provenance | Src:MaD:285 | | URLClassLoaderSSRF.java:29:23:29:34 | new URI(...) : URI | URLClassLoaderSSRF.java:30:74:30:76 | uri : URI | provenance | | | URLClassLoaderSSRF.java:29:31:29:33 | url : String | URLClassLoaderSSRF.java:29:23:29:34 | new URI(...) : URI | provenance | Config | -| URLClassLoaderSSRF.java:29:31:29:33 | url : String | URLClassLoaderSSRF.java:29:23:29:34 | new URI(...) : URI | provenance | MaD:285 | +| URLClassLoaderSSRF.java:29:31:29:33 | url : String | URLClassLoaderSSRF.java:29:23:29:34 | new URI(...) : URI | provenance | MaD:293 | | URLClassLoaderSSRF.java:30:64:30:85 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:30:64:30:85 | new URL[] | provenance | Sink:MaD:14 | | URLClassLoaderSSRF.java:30:64:30:85 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:30:64:30:85 | new URL[] | provenance | Sink:MaD:14 | -| URLClassLoaderSSRF.java:30:74:30:76 | uri : URI | URLClassLoaderSSRF.java:30:74:30:84 | toURL(...) : URL | provenance | MaD:288 | +| URLClassLoaderSSRF.java:30:74:30:76 | uri : URI | URLClassLoaderSSRF.java:30:74:30:84 | toURL(...) : URL | provenance | MaD:296 | | URLClassLoaderSSRF.java:30:74:30:84 | toURL(...) : URL | URLClassLoaderSSRF.java:30:64:30:85 | {...} : URL[] [[]] : URL | provenance | | -| URLClassLoaderSSRF.java:40:26:40:52 | getParameter(...) : String | URLClassLoaderSSRF.java:41:31:41:33 | url : String | provenance | Src:MaD:277 | +| URLClassLoaderSSRF.java:40:26:40:52 | getParameter(...) : String | URLClassLoaderSSRF.java:41:31:41:33 | url : String | provenance | Src:MaD:285 | | URLClassLoaderSSRF.java:41:23:41:34 | new URI(...) : URI | URLClassLoaderSSRF.java:44:74:44:76 | uri : URI | provenance | | | URLClassLoaderSSRF.java:41:31:41:33 | url : String | URLClassLoaderSSRF.java:41:23:41:34 | new URI(...) : URI | provenance | Config | -| URLClassLoaderSSRF.java:41:31:41:33 | url : String | URLClassLoaderSSRF.java:41:23:41:34 | new URI(...) : URI | provenance | MaD:285 | +| URLClassLoaderSSRF.java:41:31:41:33 | url : String | URLClassLoaderSSRF.java:41:23:41:34 | new URI(...) : URI | provenance | MaD:293 | | URLClassLoaderSSRF.java:44:64:44:85 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:44:64:44:85 | new URL[] | provenance | Sink:MaD:15 | | URLClassLoaderSSRF.java:44:64:44:85 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:44:64:44:85 | new URL[] | provenance | Sink:MaD:15 | -| URLClassLoaderSSRF.java:44:74:44:76 | uri : URI | URLClassLoaderSSRF.java:44:74:44:84 | toURL(...) : URL | provenance | MaD:288 | +| URLClassLoaderSSRF.java:44:74:44:76 | uri : URI | URLClassLoaderSSRF.java:44:74:44:84 | toURL(...) : URL | provenance | MaD:296 | | URLClassLoaderSSRF.java:44:74:44:84 | toURL(...) : URL | URLClassLoaderSSRF.java:44:64:44:85 | {...} : URL[] [[]] : URL | provenance | | -| URLClassLoaderSSRF.java:54:26:54:52 | getParameter(...) : String | URLClassLoaderSSRF.java:55:31:55:33 | url : String | provenance | Src:MaD:277 | +| URLClassLoaderSSRF.java:54:26:54:52 | getParameter(...) : String | URLClassLoaderSSRF.java:55:31:55:33 | url : String | provenance | Src:MaD:285 | | URLClassLoaderSSRF.java:55:23:55:34 | new URI(...) : URI | URLClassLoaderSSRF.java:56:82:56:84 | uri : URI | provenance | | | URLClassLoaderSSRF.java:55:31:55:33 | url : String | URLClassLoaderSSRF.java:55:23:55:34 | new URI(...) : URI | provenance | Config | -| URLClassLoaderSSRF.java:55:31:55:33 | url : String | URLClassLoaderSSRF.java:55:23:55:34 | new URI(...) : URI | provenance | MaD:285 | +| URLClassLoaderSSRF.java:55:31:55:33 | url : String | URLClassLoaderSSRF.java:55:23:55:34 | new URI(...) : URI | provenance | MaD:293 | | URLClassLoaderSSRF.java:56:72:56:93 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:56:72:56:93 | new URL[] | provenance | Sink:MaD:16 | -| URLClassLoaderSSRF.java:56:82:56:84 | uri : URI | URLClassLoaderSSRF.java:56:82:56:92 | toURL(...) : URL | provenance | MaD:288 | +| URLClassLoaderSSRF.java:56:82:56:84 | uri : URI | URLClassLoaderSSRF.java:56:82:56:92 | toURL(...) : URL | provenance | MaD:296 | | URLClassLoaderSSRF.java:56:82:56:92 | toURL(...) : URL | URLClassLoaderSSRF.java:56:72:56:93 | {...} : URL[] [[]] : URL | provenance | | -| URLClassLoaderSSRF.java:66:26:66:52 | getParameter(...) : String | URLClassLoaderSSRF.java:67:31:67:33 | url : String | provenance | Src:MaD:277 | +| URLClassLoaderSSRF.java:66:26:66:52 | getParameter(...) : String | URLClassLoaderSSRF.java:67:31:67:33 | url : String | provenance | Src:MaD:285 | | URLClassLoaderSSRF.java:67:23:67:34 | new URI(...) : URI | URLClassLoaderSSRF.java:70:31:70:33 | uri : URI | provenance | | | URLClassLoaderSSRF.java:67:31:67:33 | url : String | URLClassLoaderSSRF.java:67:23:67:34 | new URI(...) : URI | provenance | Config | -| URLClassLoaderSSRF.java:67:31:67:33 | url : String | URLClassLoaderSSRF.java:67:23:67:34 | new URI(...) : URI | provenance | MaD:285 | +| URLClassLoaderSSRF.java:67:31:67:33 | url : String | URLClassLoaderSSRF.java:67:23:67:34 | new URI(...) : URI | provenance | MaD:293 | | URLClassLoaderSSRF.java:70:21:70:42 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:70:21:70:42 | new URL[] | provenance | Sink:MaD:11 | | URLClassLoaderSSRF.java:70:21:70:42 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:70:21:70:42 | new URL[] | provenance | Sink:MaD:11 | -| URLClassLoaderSSRF.java:70:31:70:33 | uri : URI | URLClassLoaderSSRF.java:70:31:70:41 | toURL(...) : URL | provenance | MaD:288 | +| URLClassLoaderSSRF.java:70:31:70:33 | uri : URI | URLClassLoaderSSRF.java:70:31:70:41 | toURL(...) : URL | provenance | MaD:296 | | URLClassLoaderSSRF.java:70:31:70:41 | toURL(...) : URL | URLClassLoaderSSRF.java:70:21:70:42 | {...} : URL[] [[]] : URL | provenance | | -| URLClassLoaderSSRF.java:83:26:83:52 | getParameter(...) : String | URLClassLoaderSSRF.java:84:31:84:33 | url : String | provenance | Src:MaD:277 | +| URLClassLoaderSSRF.java:83:26:83:52 | getParameter(...) : String | URLClassLoaderSSRF.java:84:31:84:33 | url : String | provenance | Src:MaD:285 | | URLClassLoaderSSRF.java:84:23:84:34 | new URI(...) : URI | URLClassLoaderSSRF.java:89:31:89:33 | uri : URI | provenance | | | URLClassLoaderSSRF.java:84:31:84:33 | url : String | URLClassLoaderSSRF.java:84:23:84:34 | new URI(...) : URI | provenance | Config | -| URLClassLoaderSSRF.java:84:31:84:33 | url : String | URLClassLoaderSSRF.java:84:23:84:34 | new URI(...) : URI | provenance | MaD:285 | +| URLClassLoaderSSRF.java:84:31:84:33 | url : String | URLClassLoaderSSRF.java:84:23:84:34 | new URI(...) : URI | provenance | MaD:293 | | URLClassLoaderSSRF.java:89:21:89:42 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:89:21:89:42 | new URL[] | provenance | Sink:MaD:12 | | URLClassLoaderSSRF.java:89:21:89:42 | {...} : URL[] [[]] : URL | URLClassLoaderSSRF.java:89:21:89:42 | new URL[] | provenance | Sink:MaD:12 | -| URLClassLoaderSSRF.java:89:31:89:33 | uri : URI | URLClassLoaderSSRF.java:89:31:89:41 | toURL(...) : URL | provenance | MaD:288 | +| URLClassLoaderSSRF.java:89:31:89:33 | uri : URI | URLClassLoaderSSRF.java:89:31:89:41 | toURL(...) : URL | provenance | MaD:296 | | URLClassLoaderSSRF.java:89:31:89:41 | toURL(...) : URL | URLClassLoaderSSRF.java:89:21:89:42 | {...} : URL[] [[]] : URL | provenance | | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:31:40:31:47 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:36:16:36:23 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:38:36:38:43 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:40:16:40:23 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:45:40:45:47 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:47:40:47:47 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:49:36:49:43 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:51:36:51:43 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:53:36:53:43 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:55:44:55:51 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:57:38:57:45 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:59:44:59:51 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:61:53:61:60 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:63:32:63:39 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:65:44:65:51 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:67:32:67:39 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:69:33:69:40 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:71:53:71:60 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:74:58:74:65 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:76:62:76:69 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:78:52:78:59 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:80:34:80:41 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:82:40:82:47 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:84:40:84:47 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:86:50:86:57 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:92:33:92:40 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:97:35:97:42 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:102:32:102:39 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:107:24:107:31 | source(...) : String | provenance | Src:MaD:277 | -| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:112:24:112:31 | source(...) : String | provenance | Src:MaD:277 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:31:40:31:47 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:36:16:36:23 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:38:36:38:43 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:40:16:40:23 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:45:40:45:47 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:47:40:47:47 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:49:36:49:43 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:51:36:51:43 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:53:36:53:43 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:55:44:55:51 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:57:38:57:45 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:59:44:59:51 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:61:53:61:60 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:63:32:63:39 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:65:44:65:51 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:67:32:67:39 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:69:33:69:40 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:71:53:71:60 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:74:58:74:65 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:76:62:76:69 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:78:52:78:59 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:80:34:80:41 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:82:40:82:47 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:84:40:84:47 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:86:50:86:57 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:92:33:92:40 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:97:35:97:42 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:102:32:102:39 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:107:24:107:31 | source(...) : String | provenance | Src:MaD:285 | +| mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:112:24:112:31 | source(...) : String | provenance | Src:MaD:285 | | mad/Test.java:31:40:31:47 | source(...) : String | mad/Test.java:31:24:31:47 | (...)... | provenance | Sink:MaD:7 | | mad/Test.java:36:16:36:23 | source(...) : String | mad/Test.java:36:10:36:23 | (...)... | provenance | Sink:MaD:9 | | mad/Test.java:38:36:38:43 | source(...) : String | mad/Test.java:38:28:38:43 | (...)... | provenance | Sink:MaD:8 | @@ -1074,10 +1094,10 @@ edges | mad/Test.java:84:40:84:47 | source(...) : String | mad/Test.java:84:31:84:47 | (...)... | provenance | Sink:MaD:36 | | mad/Test.java:86:50:86:57 | source(...) : String | mad/Test.java:86:41:86:57 | (...)... | provenance | Sink:MaD:37 | | mad/Test.java:92:33:92:40 | source(...) : String | mad/Test.java:92:24:92:40 | (...)... | provenance | Sink:MaD:21 | -| mad/Test.java:97:35:97:42 | source(...) : String | mad/Test.java:97:29:97:42 | (...)... | provenance | Sink:MaD:234 | -| mad/Test.java:102:32:102:39 | source(...) : String | mad/Test.java:102:26:102:39 | (...)... | provenance | Sink:MaD:241 | -| mad/Test.java:107:24:107:31 | source(...) : String | mad/Test.java:107:15:107:31 | (...)... | provenance | Sink:MaD:276 | -| mad/Test.java:112:24:112:31 | source(...) : String | mad/Test.java:112:15:112:31 | (...)... | provenance | Sink:MaD:275 | +| mad/Test.java:97:35:97:42 | source(...) : String | mad/Test.java:97:29:97:42 | (...)... | provenance | Sink:MaD:242 | +| mad/Test.java:102:32:102:39 | source(...) : String | mad/Test.java:102:26:102:39 | (...)... | provenance | Sink:MaD:249 | +| mad/Test.java:107:24:107:31 | source(...) : String | mad/Test.java:107:15:107:31 | (...)... | provenance | Sink:MaD:284 | +| mad/Test.java:112:24:112:31 | source(...) : String | mad/Test.java:112:15:112:31 | (...)... | provenance | Sink:MaD:283 | models | 1 | Sink: com.zaxxer.hikari; HikariConfig; false; HikariConfig; (Properties); ; Argument[0]; request-forgery; manual | | 2 | Sink: com.zaxxer.hikari; HikariConfig; false; setJdbcUrl; (String); ; Argument[0]; request-forgery; manual | @@ -1306,76 +1326,98 @@ models | 225 | Sink: org.apache.http.client.methods; RequestBuilder; false; put; ; ; Argument[0]; request-forgery; manual | | 226 | Sink: org.apache.http.client.methods; RequestBuilder; false; setUri; ; ; Argument[0]; request-forgery; manual | | 227 | Sink: org.apache.http.client.methods; RequestBuilder; false; trace; ; ; Argument[0]; request-forgery; manual | -| 228 | Sink: org.apache.http.message; BasicHttpEntityEnclosingRequest; false; BasicHttpEntityEnclosingRequest; (RequestLine); ; Argument[0]; request-forgery; manual | -| 229 | Sink: org.apache.http.message; BasicHttpEntityEnclosingRequest; false; BasicHttpEntityEnclosingRequest; (String,String); ; Argument[1]; request-forgery; manual | -| 230 | Sink: org.apache.http.message; BasicHttpEntityEnclosingRequest; false; BasicHttpEntityEnclosingRequest; (String,String,ProtocolVersion); ; Argument[1]; request-forgery; manual | -| 231 | Sink: org.apache.http.message; BasicHttpRequest; false; BasicHttpRequest; (RequestLine); ; Argument[0]; request-forgery; manual | -| 232 | Sink: org.apache.http.message; BasicHttpRequest; false; BasicHttpRequest; (String,String); ; Argument[1]; request-forgery; manual | -| 233 | Sink: org.apache.http.message; BasicHttpRequest; false; BasicHttpRequest; (String,String,ProtocolVersion); ; Argument[1]; request-forgery; manual | -| 234 | Sink: org.codehaus.cargo.container.installer; ZipURLInstaller; true; ZipURLInstaller; (URL,String,String); ; Argument[0]; request-forgery; ai-manual | -| 235 | Sink: org.jdbi.v3.core; Jdbi; false; create; (String); ; Argument[0]; request-forgery; manual | -| 236 | Sink: org.jdbi.v3.core; Jdbi; false; create; (String,Properties); ; Argument[0]; request-forgery; manual | -| 237 | Sink: org.jdbi.v3.core; Jdbi; false; create; (String,String,String); ; Argument[0]; request-forgery; manual | -| 238 | Sink: org.jdbi.v3.core; Jdbi; false; open; (String); ; Argument[0]; request-forgery; manual | -| 239 | Sink: org.jdbi.v3.core; Jdbi; false; open; (String,Properties); ; Argument[0]; request-forgery; manual | -| 240 | Sink: org.jdbi.v3.core; Jdbi; false; open; (String,String,String); ; Argument[0]; request-forgery; manual | -| 241 | Sink: org.kohsuke.stapler; HttpResponses; true; staticResource; (URL); ; Argument[0]; request-forgery; ai-manual | -| 242 | Sink: org.springframework.boot.jdbc; DataSourceBuilder; false; url; (String); ; Argument[0]; request-forgery; manual | -| 243 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (HttpMethod,URI); ; Argument[1]; request-forgery; manual | -| 244 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (MultiValueMap,HttpMethod,URI); ; Argument[2]; request-forgery; manual | -| 245 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (Object,HttpMethod,URI); ; Argument[2]; request-forgery; manual | -| 246 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (Object,HttpMethod,URI,Type); ; Argument[2]; request-forgery; manual | -| 247 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (Object,MultiValueMap,HttpMethod,URI); ; Argument[3]; request-forgery; manual | -| 248 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (Object,MultiValueMap,HttpMethod,URI,Type); ; Argument[3]; request-forgery; manual | -| 249 | Sink: org.springframework.http; RequestEntity; false; delete; ; ; Argument[0]; request-forgery; manual | -| 250 | Sink: org.springframework.http; RequestEntity; false; get; ; ; Argument[0]; request-forgery; manual | -| 251 | Sink: org.springframework.http; RequestEntity; false; head; ; ; Argument[0]; request-forgery; manual | -| 252 | Sink: org.springframework.http; RequestEntity; false; method; ; ; Argument[1]; request-forgery; manual | -| 253 | Sink: org.springframework.http; RequestEntity; false; options; ; ; Argument[0]; request-forgery; manual | -| 254 | Sink: org.springframework.http; RequestEntity; false; patch; ; ; Argument[0]; request-forgery; manual | -| 255 | Sink: org.springframework.http; RequestEntity; false; post; ; ; Argument[0]; request-forgery; manual | -| 256 | Sink: org.springframework.http; RequestEntity; false; put; ; ; Argument[0]; request-forgery; manual | -| 257 | Sink: org.springframework.jdbc.datasource; AbstractDriverBasedDataSource; false; setUrl; (String); ; Argument[0]; request-forgery; manual | -| 258 | Sink: org.springframework.jdbc.datasource; DriverManagerDataSource; false; DriverManagerDataSource; (String); ; Argument[0]; request-forgery; manual | -| 259 | Sink: org.springframework.jdbc.datasource; DriverManagerDataSource; false; DriverManagerDataSource; (String,Properties); ; Argument[0]; request-forgery; manual | -| 260 | Sink: org.springframework.jdbc.datasource; DriverManagerDataSource; false; DriverManagerDataSource; (String,String,String); ; Argument[0]; request-forgery; manual | -| 261 | Sink: org.springframework.web.client; RestTemplate; false; delete; ; ; Argument[0]; request-forgery; manual | -| 262 | Sink: org.springframework.web.client; RestTemplate; false; exchange; ; ; Argument[0]; request-forgery; manual | -| 263 | Sink: org.springframework.web.client; RestTemplate; false; execute; ; ; Argument[0]; request-forgery; manual | -| 264 | Sink: org.springframework.web.client; RestTemplate; false; getForEntity; ; ; Argument[0]; request-forgery; manual | -| 265 | Sink: org.springframework.web.client; RestTemplate; false; getForObject; ; ; Argument[0]; request-forgery; manual | -| 266 | Sink: org.springframework.web.client; RestTemplate; false; headForHeaders; ; ; Argument[0]; request-forgery; manual | -| 267 | Sink: org.springframework.web.client; RestTemplate; false; optionsForAllow; ; ; Argument[0]; request-forgery; manual | -| 268 | Sink: org.springframework.web.client; RestTemplate; false; patchForObject; ; ; Argument[0]; request-forgery; manual | -| 269 | Sink: org.springframework.web.client; RestTemplate; false; postForEntity; ; ; Argument[0]; request-forgery; manual | -| 270 | Sink: org.springframework.web.client; RestTemplate; false; postForLocation; ; ; Argument[0]; request-forgery; manual | -| 271 | Sink: org.springframework.web.client; RestTemplate; false; postForObject; ; ; Argument[0]; request-forgery; manual | -| 272 | Sink: org.springframework.web.client; RestTemplate; false; put; ; ; Argument[0]; request-forgery; manual | -| 273 | Sink: org.springframework.web.reactive.function.client; WebClient$Builder; false; baseUrl; ; ; Argument[0]; request-forgery; manual | -| 274 | Sink: org.springframework.web.reactive.function.client; WebClient; false; create; ; ; Argument[0]; request-forgery; manual | -| 275 | Sink: play.libs.ws; StandaloneWSClient; true; url; ; ; Argument[0]; request-forgery; manual | -| 276 | Sink: play.libs.ws; WSClient; true; url; ; ; Argument[0]; request-forgery; manual | -| 277 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual | -| 278 | Summary: java.lang; AbstractStringBuilder; true; append; ; ; Argument[0]; Argument[this]; taint; manual | -| 279 | Summary: java.lang; AbstractStringBuilder; true; append; ; ; Argument[this]; ReturnValue; value; manual | -| 280 | Summary: java.lang; CharSequence; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | -| 281 | Summary: java.lang; String; false; format; (String,Object[]); ; Argument[1].ArrayElement; ReturnValue; taint; manual | -| 282 | Summary: java.lang; StringBuilder; true; StringBuilder; ; ; Argument[0]; Argument[this]; taint; manual | -| 283 | Summary: java.net.http; HttpRequest$Builder; true; build; (); ; Argument[this]; ReturnValue; taint; df-generated | -| 284 | Summary: java.net.http; HttpRequest; true; newBuilder; (URI); ; Argument[0]; ReturnValue; taint; df-generated | -| 285 | Summary: java.net; URI; false; URI; (String); ; Argument[0]; Argument[this]; taint; manual | -| 286 | Summary: java.net; URI; false; URI; (String,String,String); ; Argument[1]; Argument[this]; taint; ai-manual | -| 287 | Summary: java.net; URI; false; toString; ; ; Argument[this]; ReturnValue; taint; manual | -| 288 | Summary: java.net; URI; false; toURL; ; ; Argument[this]; ReturnValue; taint; manual | -| 289 | Summary: java.net; URL; false; URL; (String); ; Argument[0]; Argument[this]; taint; manual | -| 290 | Summary: java.util; List; false; of; (Object); ; Argument[0]; ReturnValue.Element; value; manual | -| 291 | Summary: java.util; List; true; get; (int); ; Argument[this].Element; ReturnValue; value; manual | -| 292 | Summary: java.util; Map; false; of; ; ; Argument[1]; ReturnValue.MapValue; value; manual | -| 293 | Summary: java.util; Map; false; of; ; ; Argument[3]; ReturnValue.MapValue; value; manual | -| 294 | Summary: java.util; Properties; true; setProperty; (String,String); ; Argument[1]; Argument[this].MapValue; value; manual | -| 295 | Summary: org.apache.hc.core5.http; HttpHost; true; HttpHost; (String); ; Argument[0]; Argument[this]; taint; hq-manual | -| 296 | Summary: org.apache.http.message; BasicRequestLine; false; BasicRequestLine; ; ; Argument[1]; Argument[this]; taint; manual | +| 228 | Sink: org.apache.http.client; HttpClient; true; execute; (HttpHost,HttpRequest); ; Argument[0]; request-forgery; ai-manual | +| 229 | Sink: org.apache.http.client; HttpClient; true; execute; (HttpHost,HttpRequest,HttpContext); ; Argument[0]; request-forgery; ai-manual | +| 230 | Sink: org.apache.http.client; HttpClient; true; execute; (HttpHost,HttpRequest,ResponseHandler); ; Argument[0]; request-forgery; ai-manual | +| 231 | Sink: org.apache.http.client; HttpClient; true; execute; (HttpHost,HttpRequest,ResponseHandler,HttpContext); ; Argument[0]; request-forgery; ai-manual | +| 232 | Sink: org.apache.http.client; HttpClient; true; execute; (HttpUriRequest); ; Argument[0]; request-forgery; ai-manual | +| 233 | Sink: org.apache.http.client; HttpClient; true; execute; (HttpUriRequest,HttpContext); ; Argument[0]; request-forgery; ai-manual | +| 234 | Sink: org.apache.http.client; HttpClient; true; execute; (HttpUriRequest,ResponseHandler); ; Argument[0]; request-forgery; ai-manual | +| 235 | Sink: org.apache.http.client; HttpClient; true; execute; (HttpUriRequest,ResponseHandler,HttpContext); ; Argument[0]; request-forgery; ai-manual | +| 236 | Sink: org.apache.http.message; BasicHttpEntityEnclosingRequest; false; BasicHttpEntityEnclosingRequest; (RequestLine); ; Argument[0]; request-forgery; manual | +| 237 | Sink: org.apache.http.message; BasicHttpEntityEnclosingRequest; false; BasicHttpEntityEnclosingRequest; (String,String); ; Argument[1]; request-forgery; manual | +| 238 | Sink: org.apache.http.message; BasicHttpEntityEnclosingRequest; false; BasicHttpEntityEnclosingRequest; (String,String,ProtocolVersion); ; Argument[1]; request-forgery; manual | +| 239 | Sink: org.apache.http.message; BasicHttpRequest; false; BasicHttpRequest; (RequestLine); ; Argument[0]; request-forgery; manual | +| 240 | Sink: org.apache.http.message; BasicHttpRequest; false; BasicHttpRequest; (String,String); ; Argument[1]; request-forgery; manual | +| 241 | Sink: org.apache.http.message; BasicHttpRequest; false; BasicHttpRequest; (String,String,ProtocolVersion); ; Argument[1]; request-forgery; manual | +| 242 | Sink: org.codehaus.cargo.container.installer; ZipURLInstaller; true; ZipURLInstaller; (URL,String,String); ; Argument[0]; request-forgery; ai-manual | +| 243 | Sink: org.jdbi.v3.core; Jdbi; false; create; (String); ; Argument[0]; request-forgery; manual | +| 244 | Sink: org.jdbi.v3.core; Jdbi; false; create; (String,Properties); ; Argument[0]; request-forgery; manual | +| 245 | Sink: org.jdbi.v3.core; Jdbi; false; create; (String,String,String); ; Argument[0]; request-forgery; manual | +| 246 | Sink: org.jdbi.v3.core; Jdbi; false; open; (String); ; Argument[0]; request-forgery; manual | +| 247 | Sink: org.jdbi.v3.core; Jdbi; false; open; (String,Properties); ; Argument[0]; request-forgery; manual | +| 248 | Sink: org.jdbi.v3.core; Jdbi; false; open; (String,String,String); ; Argument[0]; request-forgery; manual | +| 249 | Sink: org.kohsuke.stapler; HttpResponses; true; staticResource; (URL); ; Argument[0]; request-forgery; ai-manual | +| 250 | Sink: org.springframework.boot.jdbc; DataSourceBuilder; false; url; (String); ; Argument[0]; request-forgery; manual | +| 251 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (HttpMethod,URI); ; Argument[1]; request-forgery; manual | +| 252 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (MultiValueMap,HttpMethod,URI); ; Argument[2]; request-forgery; manual | +| 253 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (Object,HttpMethod,URI); ; Argument[2]; request-forgery; manual | +| 254 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (Object,HttpMethod,URI,Type); ; Argument[2]; request-forgery; manual | +| 255 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (Object,MultiValueMap,HttpMethod,URI); ; Argument[3]; request-forgery; manual | +| 256 | Sink: org.springframework.http; RequestEntity; false; RequestEntity; (Object,MultiValueMap,HttpMethod,URI,Type); ; Argument[3]; request-forgery; manual | +| 257 | Sink: org.springframework.http; RequestEntity; false; delete; ; ; Argument[0]; request-forgery; manual | +| 258 | Sink: org.springframework.http; RequestEntity; false; get; ; ; Argument[0]; request-forgery; manual | +| 259 | Sink: org.springframework.http; RequestEntity; false; head; ; ; Argument[0]; request-forgery; manual | +| 260 | Sink: org.springframework.http; RequestEntity; false; method; ; ; Argument[1]; request-forgery; manual | +| 261 | Sink: org.springframework.http; RequestEntity; false; options; ; ; Argument[0]; request-forgery; manual | +| 262 | Sink: org.springframework.http; RequestEntity; false; patch; ; ; Argument[0]; request-forgery; manual | +| 263 | Sink: org.springframework.http; RequestEntity; false; post; ; ; Argument[0]; request-forgery; manual | +| 264 | Sink: org.springframework.http; RequestEntity; false; put; ; ; Argument[0]; request-forgery; manual | +| 265 | Sink: org.springframework.jdbc.datasource; AbstractDriverBasedDataSource; false; setUrl; (String); ; Argument[0]; request-forgery; manual | +| 266 | Sink: org.springframework.jdbc.datasource; DriverManagerDataSource; false; DriverManagerDataSource; (String); ; Argument[0]; request-forgery; manual | +| 267 | Sink: org.springframework.jdbc.datasource; DriverManagerDataSource; false; DriverManagerDataSource; (String,Properties); ; Argument[0]; request-forgery; manual | +| 268 | Sink: org.springframework.jdbc.datasource; DriverManagerDataSource; false; DriverManagerDataSource; (String,String,String); ; Argument[0]; request-forgery; manual | +| 269 | Sink: org.springframework.web.client; RestTemplate; false; delete; ; ; Argument[0]; request-forgery; manual | +| 270 | Sink: org.springframework.web.client; RestTemplate; false; exchange; ; ; Argument[0]; request-forgery; manual | +| 271 | Sink: org.springframework.web.client; RestTemplate; false; execute; ; ; Argument[0]; request-forgery; manual | +| 272 | Sink: org.springframework.web.client; RestTemplate; false; getForEntity; ; ; Argument[0]; request-forgery; manual | +| 273 | Sink: org.springframework.web.client; RestTemplate; false; getForObject; ; ; Argument[0]; request-forgery; manual | +| 274 | Sink: org.springframework.web.client; RestTemplate; false; headForHeaders; ; ; Argument[0]; request-forgery; manual | +| 275 | Sink: org.springframework.web.client; RestTemplate; false; optionsForAllow; ; ; Argument[0]; request-forgery; manual | +| 276 | Sink: org.springframework.web.client; RestTemplate; false; patchForObject; ; ; Argument[0]; request-forgery; manual | +| 277 | Sink: org.springframework.web.client; RestTemplate; false; postForEntity; ; ; Argument[0]; request-forgery; manual | +| 278 | Sink: org.springframework.web.client; RestTemplate; false; postForLocation; ; ; Argument[0]; request-forgery; manual | +| 279 | Sink: org.springframework.web.client; RestTemplate; false; postForObject; ; ; Argument[0]; request-forgery; manual | +| 280 | Sink: org.springframework.web.client; RestTemplate; false; put; ; ; Argument[0]; request-forgery; manual | +| 281 | Sink: org.springframework.web.reactive.function.client; WebClient$Builder; false; baseUrl; ; ; Argument[0]; request-forgery; manual | +| 282 | Sink: org.springframework.web.reactive.function.client; WebClient; false; create; ; ; Argument[0]; request-forgery; manual | +| 283 | Sink: play.libs.ws; StandaloneWSClient; true; url; ; ; Argument[0]; request-forgery; manual | +| 284 | Sink: play.libs.ws; WSClient; true; url; ; ; Argument[0]; request-forgery; manual | +| 285 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual | +| 286 | Summary: java.lang; AbstractStringBuilder; true; append; ; ; Argument[0]; Argument[this]; taint; manual | +| 287 | Summary: java.lang; AbstractStringBuilder; true; append; ; ; Argument[this]; ReturnValue; value; manual | +| 288 | Summary: java.lang; CharSequence; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | +| 289 | Summary: java.lang; String; false; format; (String,Object[]); ; Argument[1].ArrayElement; ReturnValue; taint; manual | +| 290 | Summary: java.lang; StringBuilder; true; StringBuilder; ; ; Argument[0]; Argument[this]; taint; manual | +| 291 | Summary: java.net.http; HttpRequest$Builder; true; build; (); ; Argument[this]; ReturnValue; taint; df-generated | +| 292 | Summary: java.net.http; HttpRequest; true; newBuilder; (URI); ; Argument[0]; ReturnValue; taint; df-generated | +| 293 | Summary: java.net; URI; false; URI; (String); ; Argument[0]; Argument[this]; taint; manual | +| 294 | Summary: java.net; URI; false; URI; (String,String,String); ; Argument[1]; Argument[this]; taint; ai-manual | +| 295 | Summary: java.net; URI; false; toString; ; ; Argument[this]; ReturnValue; taint; manual | +| 296 | Summary: java.net; URI; false; toURL; ; ; Argument[this]; ReturnValue; taint; manual | +| 297 | Summary: java.net; URL; false; URL; (String); ; Argument[0]; Argument[this]; taint; manual | +| 298 | Summary: java.util; List; false; of; (Object); ; Argument[0]; ReturnValue.Element; value; manual | +| 299 | Summary: java.util; List; true; get; (int); ; Argument[this].Element; ReturnValue; value; manual | +| 300 | Summary: java.util; Map; false; of; ; ; Argument[1]; ReturnValue.MapValue; value; manual | +| 301 | Summary: java.util; Map; false; of; ; ; Argument[3]; ReturnValue.MapValue; value; manual | +| 302 | Summary: java.util; Properties; true; setProperty; (String,String); ; Argument[1]; Argument[this].MapValue; value; manual | +| 303 | Summary: org.apache.hc.core5.http; HttpHost; true; HttpHost; (String); ; Argument[0]; Argument[this]; taint; hq-manual | +| 304 | Summary: org.apache.http.message; BasicRequestLine; false; BasicRequestLine; ; ; Argument[1]; Argument[this]; taint; manual | +| 305 | Summary: org.apache.http; HttpHost; true; HttpHost; (String); ; Argument[0]; Argument[this]; taint; hq-manual | nodes +| ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | semmle.label | new HttpHost(...) : HttpHost | +| ApacheHttpClientExecuteSSRF.java:23:42:23:45 | sink : String | semmle.label | sink : String | +| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | semmle.label | (...)... : String | +| ApacheHttpClientExecuteSSRF.java:25:54:25:66 | (...)... : String | semmle.label | (...)... : String | +| ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | semmle.label | host | +| ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | semmle.label | host | +| ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | semmle.label | host | +| ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | semmle.label | host | +| ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | semmle.label | uriReq | +| ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | semmle.label | uriReq | +| ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | semmle.label | uriReq | +| ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | semmle.label | uriReq | | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | semmle.label | new URI(...) : URI | | ApacheHttpSSRF.java:28:31:28:34 | sink : String | semmle.label | sink : String | From dc864762c301a0dd0ee2acb364af5c36dbeb21d2 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 7 May 2026 10:23:50 +0100 Subject: [PATCH 017/226] Add change note --- .../change-notes/2026-05-07-apache-httpclient-ssrf-sinks.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2026-05-07-apache-httpclient-ssrf-sinks.md diff --git a/java/ql/lib/change-notes/2026-05-07-apache-httpclient-ssrf-sinks.md b/java/ql/lib/change-notes/2026-05-07-apache-httpclient-ssrf-sinks.md new file mode 100644 index 00000000000..d51f4897486 --- /dev/null +++ b/java/ql/lib/change-notes/2026-05-07-apache-httpclient-ssrf-sinks.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Improved modeling of Apache HttpClient `execute` method sinks for `java/ssrf` and `java/non-https-url`. From 71cd5be513e09d36bcffa0ebee44c7284e121b1b Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 28 Apr 2026 15:06:30 +0000 Subject: [PATCH 018/226] Python: Add self-validating CFG tests These tests consist of various Python constructions (hopefully a somewhat comprehensive set) with specific timestamp annotations scattered throughout. When the tests are run using the Python 3 interpreter, these annotations are checked and compared to the "current timestamp" to see that they are in agreement. This is what makes the tests "self-validating". There are a few different kinds of annotations: the basic `t[4]` style (meaning this is executed at timestamp 4), the `t[dead(4)]` variant (meaning this _would_ happen at timestamp 4, but it is in a dead branch), and `t[never]` (meaning this is never executed at all). In addition to this, there is a query, MissingAnnotations, which checks whether we have applied these annotations maximally. Many expression nodes are not actually annotatable, so there is a sizeable list of excluded nodes for that query. --- .../MissingAnnotations.expected | 0 .../evaluation-order/MissingAnnotations.ql | 15 + .../evaluation-order/OldCfgImpl.qll | 16 + .../evaluation-order/TimerUtils.qll | 613 ++++++++++++++++++ .../evaluation-order/test_assert_raise.py | 56 ++ .../evaluation-order/test_async.py | 97 +++ .../evaluation-order/test_augassign.py | 53 ++ .../evaluation-order/test_basic.py | 223 +++++++ .../evaluation-order/test_boolean.py | 76 +++ .../evaluation-order/test_classes.py | 74 +++ .../evaluation-order/test_comprehensions.py | 46 ++ .../evaluation-order/test_conditional.py | 44 ++ .../evaluation-order/test_fstring.py | 34 + .../evaluation-order/test_functions.py | 85 +++ .../ControlFlow/evaluation-order/test_if.py | 108 +++ .../evaluation-order/test_lambda.py | 46 ++ .../evaluation-order/test_loops.py | 146 +++++ .../evaluation-order/test_match.py | 173 +++++ .../ControlFlow/evaluation-order/test_try.py | 182 ++++++ .../evaluation-order/test_unpacking.py | 48 ++ .../ControlFlow/evaluation-order/test_with.py | 58 ++ .../evaluation-order/test_yield.py | 105 +++ .../ControlFlow/evaluation-order/timer.py | 189 ++++++ 23 files changed, 2487 insertions(+) create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/MissingAnnotations.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/MissingAnnotations.ql create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/OldCfgImpl.qll create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/TimerUtils.qll create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_assert_raise.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_async.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_augassign.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_boolean.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_classes.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_comprehensions.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_conditional.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_fstring.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_functions.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_if.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_lambda.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_loops.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_match.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_try.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_unpacking.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_with.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/test_yield.py create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/timer.py diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/MissingAnnotations.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/MissingAnnotations.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/MissingAnnotations.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/MissingAnnotations.ql new file mode 100644 index 00000000000..51f324e9399 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/MissingAnnotations.ql @@ -0,0 +1,15 @@ +/** + * Finds expressions in test functions that lack a timer annotation + * and are not part of the timer mechanism or otherwise excluded. + * An empty result means every annotatable expression is covered. + */ + +import python +import TimerUtils + +from TestFunction f, Expr e +where + e.getScope().getEnclosingScope*() = f and + not isTimerMechanism(e, f) and + not isUnannotatable(e) +select e, "Missing annotation in $@", f, f.getName() diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/OldCfgImpl.qll b/python/ql/test/library-tests/ControlFlow/evaluation-order/OldCfgImpl.qll new file mode 100644 index 00000000000..fc52c8dd3ed --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/OldCfgImpl.qll @@ -0,0 +1,16 @@ +/** + * Implementation of the evaluation-order CFG signature using the existing + * Python control flow graph. + */ + +private import python as Py +import TimerUtils + +/** Existing Python CFG implementation of the evaluation-order signature. */ +module OldCfg implements EvalOrderCfgSig { + class CfgNode = Py::ControlFlowNode; + + class BasicBlock = Py::BasicBlock; + + CfgNode scopeGetEntryNode(Py::Scope s) { result = s.getEntryNode() } +} diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/TimerUtils.qll b/python/ql/test/library-tests/ControlFlow/evaluation-order/TimerUtils.qll new file mode 100644 index 00000000000..9782152b8cf --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/TimerUtils.qll @@ -0,0 +1,613 @@ +/** + * Utility library for identifying timer annotations in evaluation-order tests. + * + * Identifies `expr @ t[n]` (matmul), `t(expr, n)` (call), and + * `expr @ t.dead[n]` (dead-code) patterns, extracts timestamp values, + * and provides predicates for traversing consecutive annotated CFG nodes. + */ + +import python + +/** + * A function decorated with `@test` from the timer module. + * The first parameter is the timer object. + */ +class TestFunction extends Function { + TestFunction() { + this.getADecorator().(Name).getId() = "test" and + this.getPositionalParameterCount() >= 1 + } + + /** Gets the name of the timer parameter (first parameter). */ + string getTimerParamName() { result = this.getArgName(0) } +} + +/** + * Gets an element from a timestamp subscript index. Each element is either + * an `IntegerLiteral` (live), a `Call` to `dead` (dead), a `Name("never")` + * (never), or a tuple containing any mix of these. + */ +private Expr timestampElement(Expr timestamps) { + result = timestamps and not timestamps instanceof Tuple + or + result = timestamps.(Tuple).getAnElt() +} + +/** Gets a live timestamp value from a subscript index expression. */ +private IntegerLiteral liveTimestampLiteral(Expr timestamps) { + result = timestampElement(timestamps) and + not result = any(Call c).getAnArg() +} + +/** Gets a dead timestamp value from a subscript index expression. */ +private IntegerLiteral deadTimestampLiteral(Expr timestamps) { + exists(Call c | + c = timestampElement(timestamps) and + c.getFunc().(Name).getId() = "dead" and + result = c.getArg(0) + ) +} + +/** Holds if the subscript index contains `never`. */ +private predicate hasNever(Expr timestamps) { + timestampElement(timestamps).(Name).getId() = "never" +} + +/** A timer annotation in the AST. */ +private newtype TTimerAnnotation = + /** `expr @ t[n]` or `expr @ t[n, m, ...]` or `expr @ t[dead(n), m, never]` */ + TMatmulAnnotation(TestFunction func, Expr annotated, Expr timestamps) { + exists(BinaryExpr be | + be.getOp() instanceof MatMult and + be.getRight().(Subscript).getObject().(Name).getId() = func.getTimerParamName() and + be.getScope().getEnclosingScope*() = func and + annotated = be.getLeft() and + timestamps = be.getRight().(Subscript).getIndex() + ) + } or + /** `t(expr, n)` */ + TCallAnnotation(TestFunction func, Expr annotated, Expr timestamps) { + exists(Call call | + call.getFunc().(Name).getId() = func.getTimerParamName() and + call.getScope().getEnclosingScope*() = func and + annotated = call.getArg(0) and + timestamps = call.getArg(1) + ) + } + +/** A timer annotation (wrapping the newtype for a clean API). */ +class TimerAnnotation extends TTimerAnnotation { + /** Gets a live timestamp value from this annotation. */ + int getATimestamp() { exists(this.getTimestampExpr(result)) } + + /** Gets the source expression for live timestamp value `ts`. */ + IntegerLiteral getTimestampExpr(int ts) { + result = liveTimestampLiteral(this.getTimestampsExpr()) and + result.getValue() = ts + } + + /** Gets a dead timestamp value from this annotation. */ + int getADeadTimestamp() { exists(this.getDeadTimestampExpr(result)) } + + /** Gets the source expression for dead timestamp value `ts`. */ + IntegerLiteral getDeadTimestampExpr(int ts) { + result = deadTimestampLiteral(this.getTimestampsExpr()) and + result.getValue() = ts + } + + /** Gets the raw timestamp expression (single element or tuple). */ + abstract Expr getTimestampsExpr(); + + /** Gets the test function this annotation belongs to. */ + abstract TestFunction getTestFunction(); + + /** Gets the annotated expression (the LHS of `@` or the first arg of `t(...)`). */ + abstract Expr getAnnotatedExpr(); + + /** Gets the enclosing annotation expression (the `BinaryExpr` or `Call`). */ + abstract Expr getTimerExpr(); + + /** Holds if timestamp `ts` is marked as dead in this annotation. */ + predicate isDeadTimestamp(int ts) { ts = this.getADeadTimestamp() } + + /** Holds if all timestamps in this annotation are dead (no live timestamps). */ + predicate isDead() { + not exists(this.getATimestamp()) and + not this.isNever() and + exists(this.getADeadTimestamp()) + } + + /** Holds if this is a never-evaluated annotation (contains `never`). */ + predicate isNever() { hasNever(this.getTimestampsExpr()) } + + string toString() { result = this.getAnnotatedExpr().toString() } + + Location getLocation() { result = this.getAnnotatedExpr().getLocation() } +} + +/** A matmul-based timer annotation: `expr @ t[...]`. */ +class MatmulTimerAnnotation extends TMatmulAnnotation, TimerAnnotation { + TestFunction func; + Expr annotated; + Expr timestamps; + + MatmulTimerAnnotation() { this = TMatmulAnnotation(func, annotated, timestamps) } + + override Expr getTimestampsExpr() { result = timestamps } + + override TestFunction getTestFunction() { result = func } + + override Expr getAnnotatedExpr() { result = annotated } + + override BinaryExpr getTimerExpr() { result.getLeft() = annotated } +} + +/** A call-based timer annotation: `t(expr, n)`. */ +class CallTimerAnnotation extends TCallAnnotation, TimerAnnotation { + TestFunction func; + Expr annotated; + Expr timestamps; + + CallTimerAnnotation() { this = TCallAnnotation(func, annotated, timestamps) } + + override Expr getTimestampsExpr() { result = timestamps } + + override TestFunction getTestFunction() { result = func } + + override Expr getAnnotatedExpr() { result = annotated } + + override Call getTimerExpr() { result.getArg(0) = annotated } +} + +/** + * Signature module defining the CFG interface needed by evaluation-order tests. + * This allows the test utilities to be instantiated with different CFG implementations. + */ +signature module EvalOrderCfgSig { + /** A control flow node. */ + class CfgNode { + /** Gets a textual representation of this node. */ + string toString(); + + /** Gets the location of this node. */ + Location getLocation(); + + /** Gets the AST node corresponding to this CFG node, if any. */ + AstNode getNode(); + + /** Gets a successor of this CFG node (including exceptional). */ + CfgNode getASuccessor(); + + /** Gets a true-branch successor of this CFG node, if any. */ + CfgNode getATrueSuccessor(); + + /** Gets a false-branch successor of this CFG node, if any. */ + CfgNode getAFalseSuccessor(); + + /** Gets an exceptional successor of this CFG node. */ + CfgNode getAnExceptionalSuccessor(); + + /** Gets the scope containing this CFG node. */ + Scope getScope(); + + /** Gets the basic block containing this CFG node. */ + BasicBlock getBasicBlock(); + } + + /** A basic block in the control flow graph. */ + class BasicBlock { + /** Gets the CFG node at position `n` in this basic block. */ + CfgNode getNode(int n); + + /** Holds if this basic block reaches `bb` (reflexive). */ + predicate reaches(BasicBlock bb); + + /** Holds if this basic block strictly reaches `bb` (non-reflexive). */ + predicate strictlyReaches(BasicBlock bb); + + /** Holds if this basic block strictly dominates `bb`. */ + predicate strictlyDominates(BasicBlock bb); + } + + /** Gets the entry CFG node for scope `s`. */ + CfgNode scopeGetEntryNode(Scope s); +} + +/** + * Parameterised module providing CFG-dependent utilities for evaluation-order tests. + * Instantiate with a specific CFG implementation to get `TimerCfgNode` and related predicates. + */ +module EvalOrderCfgUtils { + /** The CFG node type from the underlying implementation. */ + final class CfgNode = Input::CfgNode; + + /** The basic block type from the underlying implementation (named to avoid clash with `python::BasicBlock`). */ + final class CfgBasicBlock = Input::BasicBlock; + + /** Gets the entry CFG node for scope `s`. */ + CfgNode scopeGetEntryNode(Scope s) { result = Input::scopeGetEntryNode(s) } + + /** + * A CFG node corresponding to a timer annotation. + */ + class TimerCfgNode extends CfgNode { + private TimerAnnotation annot; + + TimerCfgNode() { annot.getAnnotatedExpr() = this.getNode() } + + /** Gets a timestamp value from this annotation. */ + int getATimestamp() { result = annot.getATimestamp() } + + /** Gets the source expression for timestamp value `ts`. */ + IntegerLiteral getTimestampExpr(int ts) { result = annot.getTimestampExpr(ts) } + + /** Gets the test function this annotation belongs to. */ + TestFunction getTestFunction() { result = annot.getTestFunction() } + + /** Holds if timestamp `ts` is marked as dead. */ + predicate isDeadTimestamp(int ts) { annot.isDeadTimestamp(ts) } + + /** Holds if all timestamps in this annotation are dead. */ + predicate isDead() { annot.isDead() } + + /** Holds if this is a never-evaluated annotation. */ + predicate isNever() { annot.isNever() } + } + + /** + * Holds if `next` is the next timer annotation reachable from `n` via + * CFG successors (both normal and exceptional), skipping non-annotated + * intermediaries within the same scope. + */ + predicate nextTimerAnnotation(CfgNode n, TimerCfgNode next) { + next = n.getASuccessor() and + next.getScope() = n.getScope() + or + exists(CfgNode mid | + mid = n.getASuccessor() and + not mid instanceof TimerCfgNode and + mid.getScope() = n.getScope() and + nextTimerAnnotation(mid, next) + ) + } + + /** + * Holds if `next` is the next timer annotation reachable from `n` via + * the true branch, skipping non-annotated intermediaries and after-value + * nodes for the same AST node. + */ + predicate nextTimerAnnotationFromTrue(CfgNode n, TimerCfgNode next) { + exists(CfgNode trueSucc | + trueSucc = n.getATrueSuccessor() and + trueSucc.getScope() = n.getScope() + | + // If the true successor is a different annotated node, use it + next = trueSucc and next.getNode() != n.getNode() + or + // Otherwise skip through it (it's an after-value node for the same expr) + nextTimerAnnotation(trueSucc, next) + ) + } + + /** + * Holds if `next` is the next timer annotation reachable from `n` via + * the false branch, skipping non-annotated intermediaries and after-value + * nodes for the same AST node. + */ + predicate nextTimerAnnotationFromFalse(CfgNode n, TimerCfgNode next) { + exists(CfgNode falseSucc | + falseSucc = n.getAFalseSuccessor() and + falseSucc.getScope() = n.getScope() + | + // If the false successor is a different annotated node, use it + next = falseSucc and next.getNode() != n.getNode() + or + // Otherwise skip through it (it's an after-value node for the same expr) + nextTimerAnnotation(falseSucc, next) + ) + } + + /** CFG-dependent test predicates, one per evaluation-order query. */ + module CfgTests { + /** + * Holds if live annotation `a` in function `f` is unreachable from + * the function entry in the CFG. + */ + predicate allLiveReachable(TimerCfgNode a, TestFunction f) { + not a.isDead() and + f = a.getTestFunction() and + a.getScope() = f and + not scopeGetEntryNode(f).getBasicBlock().reaches(a.getBasicBlock()) + } + + /** + * Holds if annotated node `a` is followed by unannotated `succ` in the + * same basic block. + */ + predicate basicBlockAnnotationGap(TimerCfgNode a, CfgNode succ) { + exists(CfgBasicBlock bb, int i | + a = bb.getNode(i) and + succ = bb.getNode(i + 1) + ) and + not succ instanceof TimerCfgNode and + not isUnannotatable(succ.getNode()) and + not isTimerMechanism(succ.getNode(), a.getTestFunction()) and + not exists(a.getAnExceptionalSuccessor()) and + succ.getNode() instanceof Expr + } + + /** + * Holds if annotations `a` and `b` appear in the same basic block with + * `a` before `b`, but `a`'s minimum timestamp is not less than `b`'s. + */ + predicate basicBlockOrdering(TimerCfgNode a, TimerCfgNode b, int minA, int minB) { + exists(CfgBasicBlock bb, int i, int j | a = bb.getNode(i) and b = bb.getNode(j) and i < j) and + minA = min(a.getATimestamp()) and + minB = min(b.getATimestamp()) and + minA >= minB + } + + /** + * Holds if function `f` has an annotation in a nested scope + * (generator, async function, comprehension, lambda). + */ + private predicate hasNestedScopeAnnotation(TestFunction f) { + exists(TimerAnnotation a | + a.getTestFunction() = f and + a.getAnnotatedExpr().getScope() != f + ) + } + + /** + * Holds if annotation `ann` with timestamp `a` has no consecutive + * successor (expected `a + 1`) in the CFG. + */ + predicate consecutiveTimestamps(TimerAnnotation ann, int a) { + not hasNestedScopeAnnotation(ann.getTestFunction()) and + not ann.isDead() and + a = ann.getATimestamp() and + not exists(TimerCfgNode x, TimerCfgNode y | + ann.getAnnotatedExpr() = x.getNode() and + nextTimerAnnotation(x, y) and + (a + 1) = y.getATimestamp() + ) and + // Exclude the maximum timestamp in the function (it has no successor) + not a = + max(TimerAnnotation other | + other.getTestFunction() = ann.getTestFunction() + | + other.getATimestamp() + ) + } + + /** + * Holds if the expression annotated with `t.never` is reachable from + * its scope's entry. + */ + predicate neverReachable(TimerAnnotation ann) { + ann.isNever() and + exists(CfgNode n, Scope s | + n.getNode() = ann.getAnnotatedExpr() and + s = n.getScope() and + ( + // Reachable via inter-block path (includes same block) + scopeGetEntryNode(s).getBasicBlock().reaches(n.getBasicBlock()) + or + // In same block as entry but at a later index + exists(CfgBasicBlock bb, int i, int j | + bb.getNode(i) = scopeGetEntryNode(s) and bb.getNode(j) = n and i < j + ) + ) + ) + } + + /** + * Holds if consecutive annotated nodes `a` -> `b` have backward time + * flow (`minA >= maxB`). + */ + predicate noBackwardFlow(TimerCfgNode a, TimerCfgNode b, int minA, int maxB) { + nextTimerAnnotation(a, b) and + not a.isDead() and + not b.isDead() and + minA = min(a.getATimestamp()) and + maxB = max(b.getATimestamp()) and + minA >= maxB + } + + /** + * Holds if annotations `a` and `b` share timestamp `ts` but `a` + * can reach `b` in the CFG. + */ + predicate noSharedReachable(TimerCfgNode a, TimerCfgNode b, int ts) { + a != b and + not a.isDead() and + not b.isDead() and + a.getTestFunction() = b.getTestFunction() and + ts = a.getATimestamp() and + ts = b.getATimestamp() and + ( + a.getBasicBlock().strictlyReaches(b.getBasicBlock()) + or + exists(CfgBasicBlock bb, int i, int j | a = bb.getNode(i) and b = bb.getNode(j) and i < j) + ) + } + + /** + * Holds if consecutive single-timestamp annotations `a` -> `b` on a + * forward edge have `maxA >= minB`. + */ + predicate strictForward(TimerCfgNode a, TimerCfgNode b, int maxA, int minB) { + nextTimerAnnotation(a, b) and + not a.isDead() and + not b.isDead() and + // Only apply to non-loop code (single timestamps on both sides) + strictcount(a.getATimestamp()) = 1 and + strictcount(b.getATimestamp()) = 1 and + // Forward edge: B does not strictly dominate A (excludes loop back-edges + // but still checks same-basic-block pairs) + not b.getBasicBlock().strictlyDominates(a.getBasicBlock()) and + maxA = max(a.getATimestamp()) and + minB = min(b.getATimestamp()) and + maxA >= minB + } + + /** + * Holds if CFG node `n` in test function `f` does not belong to any basic block. + */ + predicate noBasicBlock(CfgNode n, TestFunction f) { + n.getScope() = f and + not exists(n.getBasicBlock()) + } + + /** + * Holds if non-dead annotation `ann` has no corresponding CFG node. + */ + predicate annotationWithoutCfgNode(TimerAnnotation ann) { + not ann.isDead() and + not ann.isNever() and + not exists(CfgNode n | n.getNode() = ann.getAnnotatedExpr()) + } + + predicate annotationWithCfgNode(TimerAnnotation ann) { + exists(CfgNode n | n.getNode() = ann.getAnnotatedExpr()) + } + + /** + * Holds if annotation `ann` with timestamp `a` has no consecutive + * predecessor (expected `a - 1`) in the CFG. + */ + predicate consecutivePredecessorTimestamps(TimerAnnotation ann, int a) { + not hasNestedScopeAnnotation(ann.getTestFunction()) and + not ann.isDead() and + a = ann.getATimestamp() and + not exists(TimerCfgNode x, TimerCfgNode y | + ann.getAnnotatedExpr() = y.getNode() and + nextTimerAnnotation(x, y) and + (a - 1) = x.getATimestamp() + ) and + // Exclude the minimum timestamp in the function (it has no predecessor) + not a = + min(TimerAnnotation other | + other.getTestFunction() = ann.getTestFunction() and + not other.isDead() + | + other.getATimestamp() + ) + } + + /** + * Holds if `node` has both a true and false successor, but the true + * successor's timestamp `ts` is not marked as dead on the false + * successor (or vice versa). + * + * This checks that boolean branches are properly annotated: when a + * condition splits into true/false paths, the next annotated node + * on each side should account for the other side's timestamps as dead. + */ + predicate missingBranchTimestamp(TimerCfgNode node, int ts, string branch) { + not hasNestedScopeAnnotation(node.getTestFunction()) and + exists(TimerCfgNode trueNext, TimerCfgNode falseNext | + nextTimerAnnotationFromTrue(node, trueNext) and + nextTimerAnnotationFromFalse(node, falseNext) and + trueNext != falseNext + | + // True successor has live timestamp ts, but false successor + // doesn't have it as dead + ts = trueNext.getATimestamp() and + not falseNext.isDeadTimestamp(ts) and + not ts = falseNext.getATimestamp() and + branch = "false" + or + // False successor has live timestamp ts, but true successor + // doesn't have it as dead + ts = falseNext.getATimestamp() and + not trueNext.isDeadTimestamp(ts) and + not ts = trueNext.getATimestamp() and + branch = "true" + ) + } + } +} + +/** + * Holds if `e` is part of the timer mechanism: a top-level timer + * expression or a (transitive) sub-expression of one. + */ +predicate isTimerMechanism(Expr e, TestFunction f) { + exists(TimerAnnotation a | + a.getTestFunction() = f and + e = a.getTimerExpr().getASubExpression*() + ) +} + +/** + * Holds if expression `e` cannot be annotated due to Python syntax + * limitations (e.g., it is a definition target, a pattern, or part + * of a decorator application). + */ +predicate isUnannotatable(Expr e) { + // Function/class definitions + e instanceof FunctionExpr + or + e instanceof ClassExpr + or + // Docstrings are string literals used as expression statements + e instanceof StringLiteral and e.getParent() instanceof ExprStmt + or + // Function parameters are bound by the call, not evaluated in the body + e instanceof Parameter + or + // Name nodes that are definitions or deletions (assignment targets, def/class + // name bindings, augmented assignment targets, for-loop targets, del targets) + e.(Name).isDefinition() + or + e.(Name).isDeletion() + or + // Tuple/List/Starred nodes in assignment or for-loop targets are + // structural unpack patterns, not evaluations + (e instanceof Tuple or e instanceof List or e instanceof Starred) and + e = any(AssignStmt a).getATarget().getASubExpression*() + or + (e instanceof Tuple or e instanceof List or e instanceof Starred) and + e = any(For f).getTarget().getASubExpression*() + or + // The decorator call node wrapping a function/class definition, + // and its sub-expressions (the decorator name itself) + e = any(FunctionExpr func).getADecoratorCall().getASubExpression*() + or + e = any(ClassExpr cls).getADecoratorCall().getASubExpression*() + or + // Augmented assignment (x += e): the implicit BinaryExpr for the operation + e = any(AugAssign aug).getOperation() + or + // with-statement `as` variables are bindings + (e instanceof Name or e instanceof Tuple or e instanceof List) and + e = any(With w).getOptionalVars().getASubExpression*() + or + // except-clause exception type and `as` variable are part of except syntax + exists(ExceptStmt ex | e = ex.getType() or e = ex.getName()) + or + // match/case pattern expressions are part of pattern syntax + e.getParent+() instanceof Pattern + or + // Subscript/Attribute nodes on the LHS of an assignment are store + // operations, not value expressions (including nested ones like d["a"][1]) + (e instanceof Subscript or e instanceof Attribute) and + e = any(AssignStmt a).getATarget().getASubExpression*() + or + // Match/case guard nodes are part of case syntax + e instanceof Guard + or + // Yield/YieldFrom in statement position — the return value is + // discarded and cannot be meaningfully annotated + (e instanceof Yield or e instanceof YieldFrom) and + e.getParent() instanceof ExprStmt + or + // Synthetic nodes inside desugared comprehensions + e.getScope() = any(Comp c).getFunction() and + ( + e.(Name).getId() = ".0" + or + e instanceof Tuple and e.getParent() instanceof Yield + ) +} diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_assert_raise.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_assert_raise.py new file mode 100644 index 00000000000..692a9c6e407 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_assert_raise.py @@ -0,0 +1,56 @@ +"""Assert and raise statement evaluation order.""" + +from timer import test, dead + + +@test +def test_assert_true(t): + x = True @ t[0] + assert x @ t[1] + y = 1 @ t[2] + + +@test +def test_assert_true_with_message(t): + x = True @ t[0] + assert x @ t[1], "msg" @ t[dead(2)] + y = 1 @ t[2] + + +@test +def test_assert_false_caught(t): + try: + x = False @ t[0] + assert x @ t[1], "fail" @ t[2] + except AssertionError: + y = 1 @ t[3] + + +@test +def test_raise_caught(t): + try: + x = 1 @ t[0] + raise ((ValueError @ t[1])("test" @ t[2]) @ t[3]) + except ValueError: + y = 2 @ t[4] + + +@test +def test_raise_from_caught(t): + try: + x = 1 @ t[0] + raise ((ValueError @ t[1])("test" @ t[2]) @ t[3]) from ((RuntimeError @ t[4])("cause" @ t[5]) @ t[6]) + except ValueError: + y = 2 @ t[7] + + +@test +def test_bare_reraise(t): + try: + try: + raise ((ValueError @ t[0])("test" @ t[1]) @ t[2]) + except ValueError: + x = 1 @ t[3] + raise + except ValueError: + y = 2 @ t[4] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_async.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_async.py new file mode 100644 index 00000000000..0c9b08e3e9e --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_async.py @@ -0,0 +1,97 @@ +"""Async/await evaluation order tests. + +Coroutine bodies are lazy — like generators, the body runs only when +awaited (or driven by the event loop). asyncio.run() drives the +coroutine to completion synchronously from the caller's perspective. +""" + +import asyncio +from contextlib import asynccontextmanager +from timer import test + + +@test +def test_simple_async(t): + """Simple async function: body runs inside asyncio.run().""" + async def coro(): + x = 1 @ t[4] + return x @ t[5] + + result = ((asyncio @ t[0]).run @ t[1])((coro @ t[2])() @ t[3]) @ t[6] + + +@test +def test_await_expression(t): + """await suspends the caller until the inner coroutine completes.""" + async def helper(): + return 1 @ t[4] + + async def main(): + x = await helper() @ t[5] + return x @ t[6] + + result = ((asyncio @ t[0]).run @ t[1])((main @ t[2])() @ t[3]) @ t[7] + + +@test +def test_async_for(t): + """async for iterates an async generator.""" + async def agen(): + yield 1 @ t[5] + yield 2 @ t[7] + + async def main(): + async for val in agen() @ t[4]: + val @ t[6, 8] + + ((asyncio @ t[0]).run @ t[1])((main @ t[2])() @ t[3]) @ t[9] + + +@test +def test_async_with(t): + """async with enters/exits an async context manager.""" + @asynccontextmanager + async def ctx(): + yield 1 @ t[5] + + async def main(): + async with ctx() @ t[4] as val: + val @ t[6] + + ((asyncio @ t[0]).run @ t[1])((main @ t[2])() @ t[3]) @ t[7] + + +@test +def test_multiple_awaits(t): + """Sequential awaits in one coroutine.""" + async def task_a(): + return 10 @ t[4] + + async def task_b(): + return 20 @ t[6] + + async def main(): + a = await task_a() @ t[5] + b = await task_b() @ t[7] + return (a @ t[8] + b @ t[9]) @ t[10] + + result = ((asyncio @ t[0]).run @ t[1])((main @ t[2])() @ t[3]) @ t[11] + + +@test +def test_gather(t): + """asyncio.gather schedules coroutines as concurrent tasks.""" + async def task_a(): + return 1 @ t[6] + + async def task_b(): + return 2 @ t[7] + + async def main(): + results = await asyncio.gather( + task_a() @ t[4], + task_b() @ t[5], + ) @ t[8] + return results @ t[9] + + result = ((asyncio @ t[0]).run @ t[1])((main @ t[2])() @ t[3]) @ t[10] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_augassign.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_augassign.py new file mode 100644 index 00000000000..2f1d5eb5c3e --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_augassign.py @@ -0,0 +1,53 @@ +"""Augmented assignment evaluation order.""" + +from timer import test + + +@test +def test_plus_equals(t): + x = 1 @ t[0] + x += 2 @ t[1] + y = x @ t[2] + + +@test +def test_sub_mul_div(t): + x = 20 @ t[0] + x -= 5 @ t[1] + x *= 2 @ t[2] + x /= 6 @ t[3] + x = 17 @ t[4] + x //= 3 @ t[5] + x %= 3 @ t[6] + y = x @ t[7] + + +@test +def test_power_equals(t): + x = 2 @ t[0] + x **= 3 @ t[1] + y = x @ t[2] + + +@test +def test_bitwise_equals(t): + x = 0b1111 @ t[0] + x &= 0b1010 @ t[1] + x |= 0b0101 @ t[2] + x ^= 0b0011 @ t[3] + y = x @ t[4] + + +@test +def test_shift_equals(t): + x = 1 @ t[0] + x <<= 4 @ t[1] + x >>= 2 @ t[2] + y = x @ t[3] + + +@test +def test_list_extend(t): + x = [1 @ t[0], 2 @ t[1]] @ t[2] + x += [3 @ t[3], 4 @ t[4]] @ t[5] + y = x @ t[6] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py new file mode 100644 index 00000000000..3e8ee925d91 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py @@ -0,0 +1,223 @@ +"""Basic expression evaluation order. + +These tests verify that sub-expressions within a single expression +are evaluated in the expected order (typically left to right for +operands of binary operators, elements of collection literals, etc.) + +Every evaluated expression has a timestamp annotation, except the +timer mechanism itself (t[n], t.dead[n]). +""" + +from timer import test, never + + +@test +def test_sequential_statements(t): + """Statements execute top to bottom.""" + x = 1 @ t[0] + y = 2 @ t[1] + z = 3 @ t[2] + + +@test +def test_binary_add(t): + """In a + b, left operand evaluates before right.""" + x = (1 @ t[0] + 2 @ t[1]) @ t[2] + + +@test +def test_binary_subtract(t): + """In a - b, left operand evaluates before right.""" + x = (10 @ t[0] - 3 @ t[1]) @ t[2] + + +@test +def test_binary_multiply(t): + """In a * b, left operand evaluates before right.""" + x = ((3 @ t[0]) * (4 @ t[1])) @ t[2] + + +@test +def test_nested_binary(t): + """Sub-expressions evaluate before their containing expression.""" + x = ((1 @ t[0] + 2 @ t[1]) @ t[2] + (3 @ t[3] + 4 @ t[4]) @ t[5]) @ t[6] + + +@test +def test_chained_add(t): + """a + b + c is (a + b) + c: left to right.""" + x = ((1 @ t[0] + 2 @ t[1]) @ t[2] + 3 @ t[3]) @ t[4] + + +@test +def test_mixed_precedence(t): + """In a + b * c, all operands still evaluate left to right.""" + x = (1 @ t[0] + ((2 @ t[1]) * (3 @ t[2])) @ t[3]) @ t[4] + + +@test +def test_string_concat(t): + """String concatenation operands: left to right.""" + x = (("hello" @ t[0] + " " @ t[1]) @ t[2] + "world" @ t[3]) @ t[4] + + +@test +def test_comparison(t): + """In a < b, left operand evaluates before right.""" + x = (1 @ t[0] < 2 @ t[1]) @ t[2] + + +@test +def test_chained_comparison(t): + """Chained a < b < c: all evaluated left to right (b only once).""" + x = (1 @ t[0] < 2 @ t[1] < 3 @ t[2]) @ t[3] + + +@test +def test_list_elements(t): + """List elements evaluate left to right.""" + x = [1 @ t[0], 2 @ t[1], 3 @ t[2]] @ t[3] + + +@test +def test_dict_entries(t): + """Dict: key before value, entries left to right.""" + d = {1 @ t[0]: "a" @ t[1], 2 @ t[2]: "b" @ t[3]} @ t[4] + + +@test +def test_tuple_elements(t): + """Tuple elements evaluate left to right.""" + x = (1 @ t[0], 2 @ t[1], 3 @ t[2]) @ t[3] + + +@test +def test_set_elements(t): + """Set elements evaluate left to right.""" + x = {1 @ t[0], 2 @ t[1], 3 @ t[2]} @ t[3] + + +@test +def test_subscript(t): + """In obj[idx], object evaluates before index.""" + x = ([10 @ t[0], 20 @ t[1], 30 @ t[2]] @ t[3])[1 @ t[4]] @ t[5] + + +@test +def test_slice(t): + """Slice parameters: object, then start, then stop.""" + x = ([1 @ t[0], 2 @ t[1], 3 @ t[2], 4 @ t[3], 5 @ t[4]] @ t[5])[1 @ t[6]:3 @ t[7]] @ t[8] + + +@test +def test_method_call(t): + """Object evaluated, then attribute lookup, then arguments left to right, then call.""" + x = (("hello world" @ t[0]).replace @ t[1])("world" @ t[2], "there" @ t[3]) @ t[4] + + +@test +def test_method_chaining(t): + """Chained method calls: left to right.""" + x = ((((" hello " @ t[0]).strip @ t[1])() @ t[2]).upper @ t[3])() @ t[4] + + +@test +def test_unary_not(t): + """Unary not: operand evaluated first.""" + x = (not True @ t[0]) @ t[1] + + +@test +def test_unary_neg(t): + """Unary negation: operand evaluated first.""" + x = (-(3 @ t[0])) @ t[1] + + +@test +def test_multiple_assignment(t): + """RHS evaluated once in x = y = expr.""" + x = y = (1 @ t[0] + 2 @ t[1]) @ t[2] + + +@test +def test_callable_syntax(t): + """t(value, n) is equivalent to value @ t[n].""" + x = (1 @ t[0] + 2 @ t[1]) @ t[2] + y = (x @ t[3] * 3 @ t[4]) @ t[5] + + +@test +def test_subscript_assign(t): + """In obj[idx] = val, value is evaluated before target sub-expressions.""" + lst = [0 @ t[0], 0 @ t[1], 0 @ t[2]] @ t[3] + (lst @ t[5])[1 @ t[6]] = 42 @ t[4] + x = lst @ t[7] + + +@test +def test_attribute_assign(t): + """In obj.attr = val, value is evaluated before the object.""" + class Obj: + pass + o = (Obj @ t[0])() @ t[1] + (o @ t[3]).x = 42 @ t[2] + y = (o @ t[4]).x @ t[5] + + +@test +def test_nested_subscript_assign(t): + """Nested subscript assignment: val, then outer obj, then keys.""" + d = {"a" @ t[0]: [0 @ t[1], 0 @ t[2]] @ t[3]} @ t[4] + (d @ t[6])["a" @ t[7]][1 @ t[8]] = 99 @ t[5] + x = d @ t[9] + + +@test +def test_unreachable_after_return(t): + """Code after return has no CFG node.""" + def f(): + x = 1 @ t[1] + return x @ t[2] + y = 2 @ t[never] + result = (f @ t[0])() @ t[3] + + +@test +def test_none_literal(t): + """None is a name constant.""" + x = None @ t[0] + y = (x @ t[1] is None @ t[2]) @ t[3] + + +@test +def test_delete(t): + """del statement removes a variable binding.""" + x = 1 @ t[0] + del x + y = 2 @ t[1] + + +@test +def test_global(t): + """global statement allows writing to module-level variable.""" + global _test_global_var + _test_global_var = 1 @ t[0] + x = _test_global_var @ t[1] + + +@test +def test_nonlocal(t): + """nonlocal statement allows inner function to rebind outer variable.""" + x = 0 @ t[0] + def inner(): + nonlocal x + x = 1 @ t[2] + (inner @ t[1])() @ t[3] + y = x @ t[4] + + +@test +def test_walrus(t): + """Walrus operator := evaluates the RHS and binds it.""" + if (y := 1 @ t[0]) @ t[1]: + z = y @ t[2] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_boolean.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_boolean.py new file mode 100644 index 00000000000..a3b2268a831 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_boolean.py @@ -0,0 +1,76 @@ +"""Short-circuit boolean operators and evaluation order.""" + +from timer import test, dead + + +@test +def test_and_both_sides(t): + # True and X — both operands evaluated, result is X + x = (True @ t[0] and 42 @ t[1, dead(2)]) @ t[dead(1), 2] + + +@test +def test_and_short_circuit(t): + # False and ... — right side never evaluated + x = (False @ t[0] and True @ t[dead(1)]) @ t[1, dead(2)] + + +@test +def test_or_short_circuit(t): + # True or ... — right side never evaluated + x = (True @ t[0] or False @ t[dead(1)]) @ t[1, dead(2)] + + +@test +def test_or_both_sides(t): + # False or X — both operands evaluated, result is X + x = (False @ t[0] or 42 @ t[1, dead(2)]) @ t[dead(1), 2] + + +@test +def test_not(t): + # not evaluates its operand, then negates + x = (not True @ t[0]) @ t[1] + y = (not False @ t[2]) @ t[3] + + +@test +def test_chained_and(t): + # 1 and 2 and 3 — all truthy, all evaluated left-to-right + x = (1 @ t[0] and 2 @ t[1, dead(3)] and 3 @ t[2, dead(3)]) @ t[dead(1), dead(2), 3] + + +@test +def test_chained_or(t): + # 0 or "" or 42 — first two falsy, all evaluated until truthy found + x = (0 @ t[0] or "" @ t[1, dead(3)] or 42 @ t[2, dead(3)]) @ t[dead(1), dead(2), 3] + + +@test +def test_mixed_and_or(t): + # True and False or 42 => (True and False) or 42 => False or 42 => 42 + x = ((True @ t[0] and False @ t[1, dead(2)]) @ t[dead(1), 2, dead(4)] or 42 @ t[3, dead(4)]) @ t[dead(2), dead(3), 4] + + +@test +def test_and_side_effects(t): + # Both functions called when left side is truthy + def f(): + return 10 @ t[1] + + def g(): + return 20 @ t[4] + + x = ((f @ t[0])() @ t[2] and (g @ t[3])() @ t[5]) @ t[6] + + +@test +def test_or_side_effects(t): + # Both functions called when left side is falsy + def f(): + return 0 @ t[1] + + def g(): + return 20 @ t[4] + + x = ((f @ t[0])() @ t[2] or (g @ t[3])() @ t[5]) @ t[6] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_classes.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_classes.py new file mode 100644 index 00000000000..92313b5073c --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_classes.py @@ -0,0 +1,74 @@ +"""Class definitions — evaluation order.""" + +from timer import test + + +@test +def test_simple_class(t): + """Simple class definition and instantiation.""" + class Foo: + pass + obj = (Foo @ t[0])() @ t[1] + + +@test +def test_class_with_bases(t): + """Base class expressions evaluated at class definition time.""" + class Base: + pass + class Derived(Base @ t[0]): + pass + obj = (Derived @ t[1])() @ t[2] + + +@test +def test_class_with_methods(t): + """Object evaluated before method is called.""" + class Foo: + def greet(self, name): + return ("hello " @ t[5] + name @ t[6]) @ t[7] + obj = (Foo @ t[0])() @ t[1] + msg = ((obj @ t[2]).greet @ t[3])("world" @ t[4]) @ t[8] + + +@test +def test_class_instantiation(t): + """Arguments to __init__ evaluate before instantiation completes.""" + class Foo: + def __init__(self, x): + (self @ t[3]).x = x @ t[2] + obj = (Foo @ t[0])(42 @ t[1]) @ t[4] + val = (obj @ t[5]).x @ t[6] + + +@test +def test_method_call(t): + """Method arguments evaluate left-to-right before the call.""" + class Calculator: + def __init__(self, value): + (self @ t[3]).value = value @ t[2] + def add(self, x): + return ((self @ t[8]).value @ t[9] + x @ t[10]) @ t[11] + calc = (Calculator @ t[0])(10 @ t[1]) @ t[4] + result = ((calc @ t[5]).add @ t[6])(5 @ t[7]) @ t[12] + + +@test +def test_class_level_attribute(t): + """Multiple attribute accesses in a single expression.""" + class Config: + debug = True @ t[0] + version = 1 @ t[1] + x = ((Config @ t[2]).debug @ t[3], (Config @ t[4]).version @ t[5]) @ t[6] + + +@test +def test_class_decorator(t): + """Decorator expression evaluated, class defined, then decorator called.""" + def add_marker(cls): + (cls @ t[2]).marked = True @ t[1] + return cls @ t[3] + @(add_marker @ t[0]) + class Foo: + pass + result = (Foo @ t[4]).marked @ t[5] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_comprehensions.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_comprehensions.py new file mode 100644 index 00000000000..8ce8ca6e4c4 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_comprehensions.py @@ -0,0 +1,46 @@ +"""Evaluation order tests for comprehensions and generator expressions.""" + +from timer import test + + +@test +def test_list_comprehension(t): + items = [1 @ t[0], 2 @ t[1], 3 @ t[2]] @ t[3] + result = [x @ t[5, 6, 7] for x in items @ t[4]] @ t[8] + + +@test +def test_filtered_comprehension(t): + items = [1 @ t[0], 2 @ t[1], 3 @ t[2], 4 @ t[3]] @ t[4] + result = [x @ t[14, 23] for x in items @ t[5] if (x @ t[6, 10, 15, 19] % 2 @ t[7, 11, 16, 20] == 0 @ t[8, 12, 17, 21]) @ t[9, 13, 18, 22]] @ t[24] + + +@test +def test_dict_comprehension(t): + items = [("a" @ t[0], 1 @ t[1]) @ t[2], ("b" @ t[3], 2 @ t[4]) @ t[5]] @ t[6] + result = {k @ t[8, 10]: v @ t[9, 11] for k, v in items @ t[7]} @ t[12] + + +@test +def test_set_comprehension(t): + items = [1 @ t[0], 2 @ t[1], 3 @ t[2]] @ t[3] + result = {x @ t[5, 6, 7] for x in items @ t[4]} @ t[8] + + +@test +def test_generator_expression(t): + items = [1 @ t[0], 2 @ t[1], 3 @ t[2]] @ t[3] + gen = (x @ t[8, 9, 10] for x in items @ t[4]) @ t[5] + result = (list @ t[6])(gen @ t[7]) @ t[11] + + +@test +def test_nested_comprehension(t): + matrix = [[1 @ t[0], 2 @ t[1]] @ t[2], [3 @ t[3], 4 @ t[4]] @ t[5]] @ t[6] + result = [x @ t[9, 10, 12, 13] for row in matrix @ t[7] for x in row @ t[8, 11]] @ t[14] + + +@test +def test_comprehension_with_call(t): + items = [1 @ t[0], 2 @ t[1], 3 @ t[2]] @ t[3] + result = [(str @ t[5, 8, 11])(x @ t[6, 9, 12]) @ t[7, 10, 13] for x in items @ t[4]] @ t[14] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_conditional.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_conditional.py new file mode 100644 index 00000000000..48d45a77958 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_conditional.py @@ -0,0 +1,44 @@ +"""Ternary conditional expressions and evaluation order.""" + +from timer import test, dead + + +@test +def test_ternary_true(t): + # Condition is True — consequent evaluated, alternative skipped + x = (1 @ t[1] if True @ t[0] else 2 @ t[dead(1)]) @ t[2] + + +@test +def test_ternary_false(t): + # Condition is False — alternative evaluated, consequent skipped + x = (1 @ t[dead(1)] if False @ t[0] else 2 @ t[1]) @ t[2] + + +@test +def test_ternary_nested(t): + # Nested: outer condition True, inner condition True + # ((10 if C1 else 20) if C2 else 30) — C2 first, then C1, then 10 + x = ((10 @ t[2] if True @ t[1] else 20 @ t[dead(2)]) @ t[3] if True @ t[0] else 30 @ t[dead(1)]) @ t[4] + + +@test +def test_ternary_assignment(t): + # Ternary result assigned, then used in later expression + value = (100 @ t[1] if True @ t[0] else 200 @ t[dead(1)]) @ t[2] + result = (value @ t[3] + 1 @ t[4]) @ t[5] + + +@test +def test_ternary_complex_expressions(t): + # Complex sub-expressions in condition and consequent + x = ((1 @ t[3] + 2 @ t[4]) @ t[5] if (3 @ t[0] > 2 @ t[1]) @ t[2] else (4 @ t[dead(3)] + 5 @ t[dead(4)]) @ t[dead(5)]) @ t[6] + + +@test +def test_ternary_as_argument(t): + # Ternary used as a function argument + def f(a): + return a @ t[4] + + result = (f @ t[0])((1 @ t[2] if True @ t[1] else 2 @ t[dead(2)]) @ t[3]) @ t[5] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_fstring.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_fstring.py new file mode 100644 index 00000000000..2dd36f6ef36 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_fstring.py @@ -0,0 +1,34 @@ +"""F-string evaluation order.""" + +from timer import test + + +@test +def test_simple_fstring(t): + name = "world" @ t[0] + s = f"hello {name @ t[1]}" @ t[2] + + +@test +def test_multi_expr_fstring(t): + a = "hello" @ t[0] + b = "world" @ t[1] + s = f"{a @ t[2]} {b @ t[3]}" @ t[4] + + +@test +def test_nested_fstring(t): + inner = "world" @ t[0] + s = f"hello {f'dear {inner @ t[1]}' @ t[2]}" @ t[3] + + +@test +def test_format_spec(t): + x = 3.14159 @ t[0] + s = f"{x @ t[1]:.2f}" @ t[2] + + +@test +def test_method_in_fstring(t): + name = "world" @ t[0] + s = f"hello {((name @ t[1]).upper @ t[2])() @ t[3]}" @ t[4] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_functions.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_functions.py new file mode 100644 index 00000000000..e19b944c4ce --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_functions.py @@ -0,0 +1,85 @@ +"""Function calls and definitions — evaluation order.""" + +from timer import test + + +@test +def test_argument_order(t): + """Arguments evaluate left-to-right before the call.""" + def add(a, b): + return (a @ t[3] + b @ t[4]) @ t[5] + result = (add @ t[0])(1 @ t[1], 2 @ t[2]) @ t[6] + + +@test +def test_multiple_arguments(t): + """All arguments left-to-right, then the call.""" + def f(a, b, c): + return ((a @ t[4] + b @ t[5]) @ t[6] + c @ t[7]) @ t[8] + result = (f @ t[0])(1 @ t[1], 2 @ t[2], 3 @ t[3]) @ t[9] + + +@test +def test_default_arguments(t): + """Default expressions are evaluated at definition time.""" + val = 5 @ t[0] + def f(a, b=val @ t[1]): + return (a @ t[4] + b @ t[5]) @ t[6] + result = (f @ t[2])(10 @ t[3]) @ t[7] + + +@test +def test_args_kwargs(t): + """*args and **kwargs — expressions evaluated before the call.""" + def f(*args, **kwargs): + return ((sum @ t[9])(args @ t[10]) @ t[11] + (sum @ t[12])(((kwargs @ t[13]).values @ t[14])() @ t[15]) @ t[16]) @ t[17] + args = [1 @ t[0], 2 @ t[1]] @ t[2] + kwargs = {"c" @ t[3]: 3 @ t[4]} @ t[5] + result = (f @ t[6])(*args @ t[7], **kwargs @ t[8]) @ t[18] + + +@test +def test_nested_calls(t): + """Inner call completes before becoming an argument to outer call.""" + def f(x): + return (x @ t[7] + 1 @ t[8]) @ t[9] + def g(x): + return (x @ t[3] * 2 @ t[4]) @ t[5] + result = (f @ t[0])((g @ t[1])(1 @ t[2]) @ t[6]) @ t[10] + + +@test +def test_function_as_argument(t): + """Function object is just another argument, evaluated left-to-right.""" + def apply(fn, x): + return (fn @ t[3])(x @ t[4]) @ t[8] + def double(x): + return (x @ t[5] * 2 @ t[6]) @ t[7] + result = (apply @ t[0])(double @ t[1], 5 @ t[2]) @ t[9] + + +@test +def test_decorator(t): + """Decorator: expression evaluated, function defined, decorator called.""" + def my_decorator(fn): + return fn @ t[1] + @(my_decorator @ t[0]) + def f(): + return 42 @ t[3] + result = (f @ t[2])() @ t[4] + + +@test +def test_keyword_arguments(t): + """Keyword argument values evaluate left-to-right.""" + def f(a, b): + return (a @ t[3] + b @ t[4]) @ t[5] + result = (f @ t[0])(a=1 @ t[1], b=2 @ t[2]) @ t[6] + + +@test +def test_return_value(t): + """The return value is just the result of the call expression.""" + def f(x): + return (x @ t[2] * 2 @ t[3]) @ t[4] + result = (f @ t[0])(3 @ t[1]) @ t[5] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_if.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_if.py new file mode 100644 index 00000000000..8880aaaef34 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_if.py @@ -0,0 +1,108 @@ +"""If/elif/else control flow evaluation order.""" + +from timer import test, dead + + +@test +def test_if_true(t): + x = True @ t[0] + if x @ t[1]: + y = 1 @ t[2] + z = 0 @ t[3] + + +@test +def test_if_false(t): + x = False @ t[0] + if x @ t[1]: + y = 1 @ t[dead(2)] + z = 0 @ t[2] + + +@test +def test_if_else_true(t): + x = True @ t[0] + if x @ t[1]: + y = 1 @ t[2] + else: + y = 2 @ t[dead(2)] + z = 0 @ t[3] + + +@test +def test_if_else_false(t): + x = False @ t[0] + if x @ t[1]: + y = 1 @ t[dead(2)] + else: + y = 2 @ t[2] + z = 0 @ t[3] + + +@test +def test_if_elif_else_first(t): + x = 1 @ t[0] + if (x @ t[1] == 1 @ t[2]) @ t[3]: + y = "first" @ t[4] + elif (x @ t[dead(4)] == 2 @ t[dead(5)]) @ t[dead(6)]: + y = "second" @ t[dead(4)] + else: + y = "third" @ t[dead(4)] + z = 0 @ t[5] + + +@test +def test_if_elif_else_second(t): + x = 2 @ t[0] + if (x @ t[1] == 1 @ t[2]) @ t[3]: + y = "first" @ t[dead(7)] + elif (x @ t[4] == 2 @ t[5]) @ t[6]: + y = "second" @ t[7] + else: + y = "third" @ t[dead(7)] + z = 0 @ t[8] + + +@test +def test_if_elif_else_third(t): + x = 3 @ t[0] + if (x @ t[1] == 1 @ t[2]) @ t[3]: + y = "first" @ t[dead(7)] + elif (x @ t[4] == 2 @ t[5]) @ t[6]: + y = "second" @ t[dead(7)] + else: + y = "third" @ t[7] + z = 0 @ t[8] + + +@test +def test_nested_if_else(t): + x = True @ t[0] + y = True @ t[1] + if x @ t[2]: + if y @ t[3]: + z = 1 @ t[4] + else: + z = 2 @ t[dead(4)] + else: + z = 3 @ t[dead(4)] + w = 0 @ t[5] + + +@test +def test_if_compound_condition(t): + x = True @ t[0] + y = False @ t[1] + if (x @ t[2] and y @ t[3]) @ t[4]: + z = 1 @ t[dead(5)] + else: + z = 2 @ t[5] + w = 0 @ t[6] + + +@test +def test_if_pass(t): + x = True @ t[0] + if x @ t[1]: + pass + z = 0 @ t[2] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_lambda.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_lambda.py new file mode 100644 index 00000000000..c60cbb5b317 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_lambda.py @@ -0,0 +1,46 @@ +"""Lambda expressions — evaluation order.""" + +from timer import test + + +@test +def test_simple_lambda(t): + """Lambda creates a function object in one step.""" + f = (lambda x: (x @ t[3] + 1 @ t[4]) @ t[5]) @ t[0] + result = (f @ t[1])(10 @ t[2]) @ t[6] + + +@test +def test_lambda_multiple_args(t): + """Lambda call: arguments evaluate left to right.""" + f = (lambda a, b, c: ((a @ t[5] + b @ t[6]) @ t[7] + c @ t[8]) @ t[9]) @ t[0] + result = (f @ t[1])(1 @ t[2], 2 @ t[3], 3 @ t[4]) @ t[10] + + +@test +def test_lambda_default(t): + """Default argument evaluated at lambda creation time.""" + val = 5 @ t[0] + f = (lambda x, y=val @ t[1]: (x @ t[5] + y @ t[6]) @ t[7]) @ t[2] + result = (f @ t[3])(10 @ t[4]) @ t[8] + + +@test +def test_lambda_map(t): + """Lambda body runs once per element when consumed by list(map(...)).""" + f = (lambda x: (x @ t[9, 12, 15] * 2 @ t[10, 13, 16]) @ t[11, 14, 17]) @ t[0] + result = (list @ t[1])((map @ t[2])(f @ t[3], [1 @ t[4], 2 @ t[5], 3 @ t[6]] @ t[7]) @ t[8]) @ t[18] + + +@test +def test_immediately_invoked(t): + """Arguments evaluated, then immediately-invoked lambda called.""" + result = ((lambda x: (x @ t[2] + 1 @ t[3]) @ t[4]) @ t[0])(10 @ t[1]) @ t[5] + + +@test +def test_lambda_closure(t): + """Lambda captures enclosing scope; body runs at call time.""" + x = 10 @ t[0] + f = (lambda: x @ t[3]) @ t[1] + result = (f @ t[2])() @ t[4] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_loops.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_loops.py new file mode 100644 index 00000000000..17df7a4703a --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_loops.py @@ -0,0 +1,146 @@ +"""Loop control flow evaluation order tests.""" + +from timer import test, dead + + +# 1. Simple while loop (fixed iterations) +@test +def test_while_loop(t): + i = 0 @ t[0] + while (i @ t[1, 7, 13, 19] < 3 @ t[2, 8, 14, 20]) @ t[3, 9, 15, 21]: # 4 checks: 3 true + 1 false + i = (i @ t[4, 10, 16] + 1 @ t[5, 11, 17]) @ t[6, 12, 18] + done = True @ t[22] + + +# 2. While loop with break +@test +def test_while_break(t): + i = 0 @ t[0] + while (i @ t[1, 10, 19] < 5 @ t[2, 11, 20]) @ t[3, 12, 21]: + if (i @ t[4, 13, 22] == 2 @ t[5, 14, 23]) @ t[6, 15, 24]: + break + i = (i @ t[7, 16] + 1 @ t[8, 17]) @ t[9, 18] + done = True @ t[25] + + +# 3. While loop with continue +@test +def test_while_continue(t): + i = 0 @ t[0] + total = 0 @ t[1] + while (i @ t[2, 14, 23, 35] < 3 @ t[3, 15, 24, 36]) @ t[4, 16, 25, 37]: + i = (i @ t[5, 17, 26] + 1 @ t[6, 18, 27]) @ t[7, 19, 28] + if (i @ t[8, 20, 29] == 2 @ t[9, 21, 30]) @ t[10, 22, 31]: + continue + total = (total @ t[11, 32] + i @ t[12, 33]) @ t[13, 34] + done = True @ t[38] + + +# 4. While/else (no break — else executes) +@test +def test_while_else(t): + i = 0 @ t[0] + while (i @ t[1, 7, 13] < 2 @ t[2, 8, 14]) @ t[3, 9, 15]: + i = (i @ t[4, 10] + 1 @ t[5, 11]) @ t[6, 12] + else: + done = True @ t[16] + + +# 5. While/else (with break — else skipped) +@test +def test_while_else_break(t): + i = 0 @ t[0] + while (i @ t[1, 10] < 5 @ t[2, 11]) @ t[3, 12]: + if (i @ t[4, 13] == 1 @ t[5, 14]) @ t[6, 15]: + break + i = (i @ t[7] + 1 @ t[8]) @ t[9] + else: + never = True @ t[dead(16)] + after = True @ t[16] + + +# 6. Simple for loop over a list +@test +def test_for_list(t): + for x in [1 @ t[0], 2 @ t[1], 3 @ t[2]] @ t[3]: + x @ t[4, 5, 6] + done = True @ t[7] + + +# 7. For loop with range +@test +def test_for_range(t): + for i in (range @ t[0])(3 @ t[1]) @ t[2]: + i @ t[3, 4, 5] + done = True @ t[6] + + +# 8. For loop with break +@test +def test_for_break(t): + for x in [1 @ t[0], 2 @ t[1], 3 @ t[2], 4 @ t[3]] @ t[4]: + if (x @ t[5, 9, 13] == 3 @ t[6, 10, 14]) @ t[7, 11, 15]: + break + x @ t[8, 12] + done = True @ t[16] + + +# 9. For loop with continue +@test +def test_for_continue(t): + total = 0 @ t[0] + for x in [1 @ t[1], 2 @ t[2], 3 @ t[3]] @ t[4]: + if (x @ t[5, 11, 14] == 2 @ t[6, 12, 15]) @ t[7, 13, 16]: + continue + total = (total @ t[8, 17] + x @ t[9, 18]) @ t[10, 19] + done = True @ t[20] + + +# 10. For/else (no break — else executes) +@test +def test_for_else(t): + for x in [1 @ t[0], 2 @ t[1]] @ t[2]: + x @ t[3, 4] + else: + done = True @ t[5] + + +# 11. For/else (with break — else skipped) +@test +def test_for_else_break(t): + for x in [1 @ t[0], 2 @ t[1], 3 @ t[2]] @ t[3]: + if (x @ t[4, 8] == 2 @ t[5, 9]) @ t[6, 10]: + break + x @ t[7] + else: + never = True @ t[dead(11)] + after = True @ t[11] + + +# 12. Nested loops +@test +def test_nested_loops(t): + for i in [1 @ t[0], 2 @ t[1]] @ t[2]: + for j in [10 @ t[3, 12], 20 @ t[4, 13]] @ t[5, 14]: + (i @ t[6, 9, 15, 18, dead(21)] + j @ t[7, 10, 16, 19]) @ t[8, 11, 17, 20] + done = True @ t[dead(3), dead(6), dead(9), dead(12), dead(15), dead(18), 21] + + +# 13. While True with conditional break +@test +def test_while_true_break(t): + i = 0 @ t[0] + while True @ t[1, 8, 15]: + i = (i @ t[2, 9, 16] + 1 @ t[3, 10, 17]) @ t[4, 11, 18] + if (i @ t[5, 12, 19] == 3 @ t[6, 13, 20]) @ t[7, 14, 21]: + break + done = True @ t[22] + + +# 14. For with enumerate +@test +def test_for_enumerate(t): + for idx, val in (enumerate @ t[0])(["a" @ t[1], "b" @ t[2], "c" @ t[3]] @ t[4]) @ t[5]: + idx @ t[6, 8, 10] + val @ t[7, 9, 11] + done = True @ t[12] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_match.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_match.py new file mode 100644 index 00000000000..ba15a2d7c85 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_match.py @@ -0,0 +1,173 @@ +"""Evaluation order for match/case (structural pattern matching, Python 3.10+).""" + +import sys +if sys.version_info < (3, 10): + print("Skipping match/case tests (requires Python 3.10+)") + print("---") + print("0/0 tests passed") + sys.exit(0) + +from timer import test, dead, never + + +@test +def test_match_literal(t): + x = 1 @ t[0] + match x @ t[1]: + case 1: + y = "one" @ t[2] + case 2: + y = "two" @ t[dead(2)] + z = y @ t[3] + + +@test +def test_match_literal_fallthrough(t): + x = 3 @ t[0] + match x @ t[1]: + case 1: + y = "one" @ t[dead(2)] + case 2: + y = "two" @ t[dead(2)] + case 3: + y = "three" @ t[2] + z = y @ t[3] + + +@test +def test_match_wildcard(t): + x = 42 @ t[0] + match x @ t[1]: + case 1: + y = "one" @ t[dead(2)] + case _: + y = "other" @ t[2] + z = y @ t[3] + + +@test +def test_match_capture(t): + x = 42 @ t[0] + match x @ t[1]: + case n: + y = n @ t[2] + z = y @ t[3] + + +@test +def test_match_or_pattern(t): + x = 2 @ t[0] + match x @ t[1]: + case 1 | 2: + y = "low" @ t[2] + case _: + y = "other" @ t[dead(2)] + z = y @ t[3] + + +@test +def test_match_guard(t): + x = 5 @ t[0] + match x @ t[1]: + case n if (n @ t[2] > 3 @ t[3]) @ t[4]: + y = n @ t[5] + case _: + y = 0 @ t[dead(5)] + z = y @ t[6] + + +@test +def test_match_class_pattern(t): + x = 42 @ t[0] + match x @ t[1]: + case int(): + y = "integer" @ t[2] + case str(): + y = "string" @ t[dead(2)] + z = y @ t[3] + + +@test +def test_match_sequence(t): + x = [1 @ t[0], 2 @ t[1]] @ t[2] + match x @ t[3]: + case [a, b]: + y = (a @ t[4] + b @ t[5]) @ t[6] + case _: + y = 0 @ t[dead(6)] + z = y @ t[7] + + +@test +def test_match_mapping(t): + x = {"key" @ t[0]: 42 @ t[1]} @ t[2] + match x @ t[3]: + case {"key": value}: + y = value @ t[4] + case _: + y = 0 @ t[dead(4)] + z = y @ t[5] + + +@test +def test_match_nested(t): + x = {"users" @ t[0]: [{"name" @ t[1]: "Alice" @ t[2]} @ t[3]] @ t[4]} @ t[5] + match x @ t[6]: + case {"users": [{"name": name}]}: + y = name @ t[7] + case _: + y = "unknown" @ t[dead(7)] + z = y @ t[8] + + +@test +def test_match_or_pattern_with_as(t): + """OR pattern with `as` binding and method call on the result.""" + clause = "foo@bar" @ t[0] + match clause @ t[1]: + case (str() as uses) | {"uses": uses}: + result = ((uses @ t[2]).partition @ t[3])("@" @ t[4]) @ t[5] + x = (result @ t[6])[0 @ t[7]] @ t[8] + case _: + raise ((ValueError @ t[dead(2)])(clause @ t[dead(3)]) @ t[dead(4)]) + y = x @ t[9] + + +@test +def test_match_wildcard_raise(t): + """Wildcard case that raises, with OR pattern on the other branch.""" + clause = 42 @ t[0] + try: + match clause @ t[1]: + case (str() as uses) | {"uses": uses}: + result = uses @ t[dead(2)] + case _: + raise ((ValueError @ t[2])(f"Invalid: {clause @ t[3]}" @ t[4]) @ t[5]) + except ValueError: + y = 0 @ t[6] + + +@test +def test_match_exhaustive_return_first(t): + """Every case returns; code after match is unreachable (first case taken).""" + def f(x): + match x @ t[2]: + case 1: + return "one" @ t[3] + case _: + return "other" @ t[dead(3)] + y = 0 @ t[never] + result = (f @ t[0])(1 @ t[1]) @ t[4] + + +@test +def test_match_exhaustive_return_wildcard(t): + """Every case returns; code after match is unreachable (wildcard taken).""" + def f(x): + match x @ t[2]: + case 1: + return "one" @ t[dead(3)] + case _: + return "other" @ t[3] + y = 0 @ t[never] + result = (f @ t[0])(99 @ t[1]) @ t[4] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_try.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_try.py new file mode 100644 index 00000000000..dd0b15457d6 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_try.py @@ -0,0 +1,182 @@ +"""Exception handling control flow: try/except/else/finally evaluation order.""" + +from timer import test, dead, never + + +# 1. try/except — no exception raised (except block skipped) +@test +def test_try_no_exception(t): + try: + x = 1 @ t[0] + y = 2 @ t[1] + except ValueError: + z = 3 @ t[dead(2)] + after = 0 @ t[2] + + +# 2. try/except — exception raised and caught +@test +def test_try_with_exception(t): + try: + x = 1 @ t[0] + raise ((ValueError @ t[1])() @ t[2]) + y = 2 @ t[never] + except ValueError: + z = 3 @ t[3] + after = 0 @ t[4] + + +# 3. try/except/else — no exception (else runs) +@test +def test_try_except_else_no_exception(t): + try: + x = 1 @ t[0] + except ValueError: + y = 2 @ t[dead(1)] + else: + z = 3 @ t[1] + after = 0 @ t[2] + + +# 4. try/except/else — exception raised (else skipped) +@test +def test_try_except_else_with_exception(t): + try: + x = 1 @ t[0] + raise ((ValueError @ t[1])() @ t[2]) + except ValueError: + y = 2 @ t[3] + else: + z = 3 @ t[dead(3)] + after = 0 @ t[4] + + +# 5. try/finally — no exception +@test +def test_try_finally_no_exception(t): + try: + x = 1 @ t[0] + y = 2 @ t[1] + finally: + z = 3 @ t[2] + after = 0 @ t[3] + + +# 6. try/finally — exception raised (finally runs, then exception propagates) +@test +def test_try_finally_exception(t): + try: + try: + x = 1 @ t[0] + raise ((ValueError @ t[1])() @ t[2]) + finally: + y = 2 @ t[3] + except ValueError: + z = 3 @ t[4] + + +# 7. try/except/finally — no exception +@test +def test_try_except_finally_no_exception(t): + try: + x = 1 @ t[0] + except ValueError: + y = 2 @ t[dead(1)] + finally: + z = 3 @ t[1] + after = 0 @ t[2] + + +# 8. try/except/finally — exception caught +@test +def test_try_except_finally_exception(t): + try: + x = 1 @ t[0] + raise ((ValueError @ t[1])() @ t[2]) + except ValueError: + y = 2 @ t[3] + finally: + z = 3 @ t[4] + after = 0 @ t[5] + + +# 9. Multiple except clauses — first matching +@test +def test_multiple_except_first(t): + try: + x = 1 @ t[0] + raise ((ValueError @ t[1])() @ t[2]) + except ValueError: + y = 2 @ t[3] + except TypeError: + z = 3 @ t[dead(3)] + after = 0 @ t[4] + + +# 10. Multiple except clauses — second matching +@test +def test_multiple_except_second(t): + try: + x = 1 @ t[0] + raise ((TypeError @ t[1])() @ t[2]) + except ValueError: + y = 2 @ t[dead(3)] + except TypeError: + z = 3 @ t[3] + after = 0 @ t[4] + + +# 11. except with `as` binding +@test +def test_except_as_binding(t): + try: + x = 1 @ t[0] + raise ((ValueError @ t[1])("msg" @ t[2]) @ t[3]) + except ValueError as e: + y = (str @ t[4])(e @ t[5]) @ t[6] + after = 0 @ t[7] + + +# 12. Nested try/except +@test +def test_nested_try_except(t): + try: + x = 1 @ t[0] + try: + y = 2 @ t[1] + raise ((ValueError @ t[2])() @ t[3]) + except ValueError: + z = 3 @ t[4] + w = 4 @ t[5] + except TypeError: + v = 5 @ t[dead(6)] + after = 0 @ t[6] + + +# 13. try/except in a loop +@test +def test_try_in_loop(t): + total = 0 @ t[0] + for i in (range @ t[1])(3 @ t[2]) @ t[3]: + try: + if (i @ t[4, 11, 20] == 1 @ t[5, 12, 21]) @ t[6, 13, 22]: + raise ((ValueError @ t[14])() @ t[15]) + total = (total @ t[7, 23] + 1 @ t[8, 24]) @ t[9, 25] + except ValueError: + total = (total @ t[16] + 10 @ t[17]) @ t[18] + r = 0 @ t[10, 19, 26] + + +# 14. Re-raise with bare `raise` +@test +def test_reraise(t): + try: + try: + x = 1 @ t[0] + raise ((ValueError @ t[1])() @ t[2]) + except ValueError: + y = 2 @ t[3] + raise + except ValueError: + z = 3 @ t[4] + after = 0 @ t[5] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_unpacking.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_unpacking.py new file mode 100644 index 00000000000..45f292cb0b7 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_unpacking.py @@ -0,0 +1,48 @@ +"""Unpacking and star expressions evaluation order.""" + +from timer import test + + +@test +def test_tuple_unpack(t): + """RHS expression evaluates, then unpacking assigns targets.""" + a, b = (1 @ t[0], 2 @ t[1]) @ t[2] + x = (a @ t[3] + b @ t[4]) @ t[5] + + +@test +def test_list_unpack(t): + """List unpacking: RHS elements left to right, then unpack.""" + [a, b] = [1 @ t[0], 2 @ t[1]] @ t[2] + x = (a @ t[3] + b @ t[4]) @ t[5] + + +@test +def test_star_unpack(t): + """Star unpacking: RHS evaluates first.""" + a, *b = [1 @ t[0], 2 @ t[1], 3 @ t[2], 4 @ t[3]] @ t[4] + x = (a @ t[5], b @ t[6]) @ t[7] + + +@test +def test_nested_unpack(t): + """Nested unpacking: RHS evaluates first.""" + (a, b), c = ((1 @ t[0], 2 @ t[1]) @ t[2], 3 @ t[3]) @ t[4] + x = ((a @ t[5] + b @ t[6]) @ t[7] + c @ t[8]) @ t[9] + + +@test +def test_swap(t): + a = 1 @ t[0] + b = 2 @ t[1] + a, b = (b @ t[2], a @ t[3]) @ t[4] + x = a @ t[5] + y = b @ t[6] + + +@test +def test_unpack_for(t): + pairs = [(1 @ t[0], 2 @ t[1]) @ t[2], (3 @ t[3], 4 @ t[4]) @ t[5]] @ t[6] + for a, b in pairs @ t[7]: + x = a @ t[8, 10] + y = b @ t[9, 11] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_with.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_with.py new file mode 100644 index 00000000000..1dcc7169092 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_with.py @@ -0,0 +1,58 @@ +"""Evaluation order tests for with statements.""" + +from contextlib import contextmanager +from timer import test + + +@contextmanager +def ctx(value=None): + yield value + + +@test +def test_simple_with(t): + x = 1 @ t[0] + with (ctx @ t[1])() @ t[2]: + y = 2 @ t[3] + z = 3 @ t[4] + + +@test +def test_with_as(t): + with (ctx @ t[0])(42 @ t[1]) @ t[2] as v: + x = v @ t[3] + y = 0 @ t[4] + + +@test +def test_nested_with(t): + with (ctx @ t[0])() @ t[1]: + with (ctx @ t[2])() @ t[3]: + x = 1 @ t[4] + y = 2 @ t[5] + + +@test +def test_multiple_context_managers(t): + with (ctx @ t[0])(1 @ t[1]) @ t[2] as a, (ctx @ t[3])(2 @ t[4]) @ t[5] as b: + x = (a @ t[6], b @ t[7]) @ t[8] + y = 0 @ t[9] + + +@test +def test_with_exception_handling(t): + try: + with (ctx @ t[0])() @ t[1]: + x = 1 @ t[2] + raise ((ValueError @ t[3])() @ t[4]) + except ValueError: + y = 2 @ t[5] + z = 3 @ t[6] + + +@test +def test_with_in_loop(t): + for i in [1 @ t[0], 2 @ t[1]] @ t[2]: + with (ctx @ t[3, 6])() @ t[4, 7]: + x = i @ t[5, 8] + y = 0 @ t[9] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_yield.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_yield.py new file mode 100644 index 00000000000..b2a28d793bc --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_yield.py @@ -0,0 +1,105 @@ +"""Generator and yield evaluation order tests. + +Generator bodies are lazy — code runs only when iterated. The timer +annotations inside generator bodies fire interleaved with the caller's +annotations, reflecting the suspend/resume semantics of yield. +""" + +from timer import test + + +@test +def test_simple_generator(t): + """Basic generator: body runs on next(), not on gen().""" + def gen(): + yield 1 @ t[4] + yield 2 @ t[8] + + g = (gen @ t[0])() @ t[1] + x = (next @ t[2])(g @ t[3]) @ t[5] + y = (next @ t[6])(g @ t[7]) @ t[9] + + +@test +def test_multiple_yields(t): + """Three yields interleave with three next() calls.""" + def gen(): + yield 1 @ t[4] + yield 2 @ t[8] + yield 3 @ t[12] + + g = (gen @ t[0])() @ t[1] + a = (next @ t[2])(g @ t[3]) @ t[5] + b = (next @ t[6])(g @ t[7]) @ t[9] + c = (next @ t[10])(g @ t[11]) @ t[13] + + +@test +def test_generator_for_loop(t): + """for-loop consumes generator, interleaving body and loop.""" + def gen(): + yield 1 @ t[2] + yield 2 @ t[4] + + for val in (gen @ t[0])() @ t[1]: + val @ t[3, 5] + + +@test +def test_generator_list(t): + """list() consumes the entire generator without interleaving.""" + def gen(): + yield 10 @ t[3] + yield 20 @ t[4] + yield 30 @ t[5] + + result = (list @ t[0])((gen @ t[1])() @ t[2]) @ t[6] + + +@test +def test_yield_from(t): + """yield from delegates to an inner generator transparently.""" + def inner(): + yield 1 @ t[6] + yield 2 @ t[10] + + def outer(): + yield from (inner @ t[4])() @ t[5] + + g = (outer @ t[0])() @ t[1] + x = (next @ t[2])(g @ t[3]) @ t[7] + y = (next @ t[8])(g @ t[9]) @ t[11] + + +@test +def test_generator_return(t): + """Generator return value accessed via yield from.""" + def gen(): + yield 1 @ t[6] + return 42 @ t[10] + + def wrapper(): + result = (yield from (gen @ t[4])() @ t[5]) @ t[11] + yield result @ t[12] + + g = (wrapper @ t[0])() @ t[1] + x = (next @ t[2])(g @ t[3]) @ t[7] + y = (next @ t[8])(g @ t[9]) @ t[13] + + +@test +def test_generator_send(t): + """send() passes a value into the generator at the yield point.""" + def gen(): + x = (yield 1 @ t[4]) @ t[9] + yield (x @ t[10] + 10 @ t[11]) @ t[12] + + g = (gen @ t[0])() @ t[1] + first = (next @ t[2])(g @ t[3]) @ t[5] + second = ((g @ t[6]).send @ t[7])(42 @ t[8]) @ t[13] + + +@test +def test_generator_expression(t): + """Inline generator expression consumed by list().""" + result = (list @ t[0])(x @ t[5, 6, 7] for x in [10 @ t[1], 20 @ t[2], 30 @ t[3]] @ t[4]) @ t[8] diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/timer.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/timer.py new file mode 100644 index 00000000000..e10dde2592a --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/timer.py @@ -0,0 +1,189 @@ +"""Abstract timer for self-validating CFG evaluation-order tests. + +Provides a Timer context manager and a @test decorator for writing tests +that verify the order in which Python evaluates expressions. + +Usage with @test decorator (preferred): + + from timer import test, dead, never + + @test + def test_sequential(t): + x = 1 @ t[0] + y = 2 @ t[1] + z = (x + y) @ t[2] + +Annotation forms: + t[n] - assert current timestamp is n, return marker + t[n, m, ...] - assert current timestamp is one of {n, m, ...} + t[dead(n)] - mark timestamp n as dead (fails if evaluated) + t[dead(n), m] - dead at n, live at m + t[never] - mark as never evaluated (fails if evaluated) + t["label"] - record current timestamp under label (development aid) + t(value, n) - equivalent to: value @ t[n] + +Run a test file directly to self-validate: python test_file.py +""" + +import atexit +import sys + +_results = [] + + +class _Check: + """Marker returned by t[n] — asserts the current timestamp. + + Receives the raw subscript elements: plain ints are live timestamps, + dead(n) markers are dead timestamps, and `never` means any evaluation + is an error. + """ + + __slots__ = ("_timer", "_live", "_dead", "_never") + + def __init__(self, timer, elements): + self._timer = timer + self._live = set() + self._dead = set() + self._never = False + for e in elements: + if isinstance(e, int): + self._live.add(e) + elif isinstance(e, _DeadMarker): + self._dead.add(e.timestamp) + elif isinstance(e, _NeverSentinel): + self._never = True + + def __rmatmul__(self, value): + ts = self._timer._tick() + if self._never: + self._timer._error( + f"expression annotated with t[never] was evaluated (timestamp {ts})" + ) + elif ts in self._dead: + self._timer._error( + f"timestamp {ts} is marked dead but was evaluated" + ) + elif ts not in self._live: + self._timer._error( + f"expected {sorted(self._live)}, got {ts}" + ) + return value + + +class _Label: + """Marker returned by t["name"] — records the timestamp under a label.""" + + __slots__ = ("_timer", "_name") + + def __init__(self, timer, name): + self._timer = timer + self._name = name + + def __rmatmul__(self, value): + ts = self._timer._tick() + self._timer._labels.setdefault(self._name, []).append(ts) + return value + + +class _DeadMarker: + """Marker returned by dead(n) — used inside t[...] to mark a timestamp as dead.""" + + def __init__(self, timestamp): + self.timestamp = timestamp + + +def dead(n): + """Mark timestamp `n` as dead code inside a timer subscript: t[dead(1), 2].""" + return _DeadMarker(n) + + +class _NeverSentinel: + """Sentinel for never-evaluated annotations: t[never].""" + pass + + +never = _NeverSentinel() + + +class Timer: + """Context manager tracking abstract evaluation timestamps. + + Each Timer instance maintains a counter starting at 0. Every time an + annotation (@ t[n] or t(value, n)) is encountered, the counter is + compared against the expected value and then incremented. + """ + + def __init__(self, name=""): + self._name = name + self._counter = 0 + self._errors = [] + self._labels = {} + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + if self._labels: + for name, timestamps in sorted(self._labels.items()): + print(f" {name}: {', '.join(map(str, timestamps))}") + _results.append((self._name, list(self._errors))) + if self._errors: + print(f"{self._name}: FAIL") + for err in self._errors: + print(f" {err}") + else: + print(f"{self._name}: ok") + return False + + def _tick(self): + ts = self._counter + self._counter += 1 + return ts + + def _error(self, msg): + self._errors.append(msg) + + def __getitem__(self, key): + if isinstance(key, str): + return _Label(self, key) + elif isinstance(key, tuple): + return _Check(self, key) + else: + return _Check(self, [key]) + + def __call__(self, value, key): + """Alternative to @ operator: t(value, 4) or t(value, [1, 2, 3]).""" + if isinstance(key, list): + key = tuple(key) + marker = self[key] + return marker.__rmatmul__(value) + + +def test(fn): + """Decorator that creates a Timer and runs the test function immediately. + + The function receives a fresh Timer as its sole argument. Errors are + collected (not raised) and reported after the function completes. + """ + with Timer(fn.__name__) as t: + try: + fn(t) + except Exception as e: + t._error(f"exception: {type(e).__name__}: {e}") + return fn + + +def _report(): + """Print summary at interpreter exit.""" + if not _results: + return + total = len(_results) + passed = sum(1 for _, errors in _results if not errors) + print("---") + print(f"{passed}/{total} tests passed") + if passed < total: + sys.exit(1) + + +atexit.register(_report) From 3a979ac2f84814d7f427f762b128876cc0216cea Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 28 Apr 2026 15:06:50 +0000 Subject: [PATCH 019/226] Python: Add some CFG-validation queries These use the annotated, self-verifying test files to check various consistency requirements. Some of these may be expressing the same thing in different ways, but it's fairly cheap to keep them around, so I have not attempted to produce a minimal set of queries for this. --- .../AllLiveReachable.expected | 0 .../evaluation-order/AllLiveReachable.ql | 17 +++++++++++++++ .../AnnotationHasCfgNode.expected | 1 + .../evaluation-order/AnnotationHasCfgNode.ql | 14 +++++++++++++ .../BasicBlockAnnotationGap.expected | 0 .../BasicBlockAnnotationGap.ql | 21 +++++++++++++++++++ .../ContiguousTimestamps.expected | 0 .../evaluation-order/ContiguousTimestamps.ql | 17 +++++++++++++++ .../evaluation-order/NoBackwardFlow.expected | 11 ++++++++++ .../evaluation-order/NoBackwardFlow.ql | 17 +++++++++++++++ .../evaluation-order/NoBasicBlock.expected | 1 + .../evaluation-order/NoBasicBlock.ql | 14 +++++++++++++ .../NoSharedReachable.expected | 0 .../evaluation-order/NoSharedReachable.ql | 16 ++++++++++++++ .../evaluation-order/OldCfgImpl.qll | 8 +++---- .../evaluation-order/StrictForward.expected | 11 ++++++++++ .../evaluation-order/StrictForward.ql | 17 +++++++++++++++ 17 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/AllLiveReachable.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/AllLiveReachable.ql create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/AnnotationHasCfgNode.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/AnnotationHasCfgNode.ql create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockAnnotationGap.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockAnnotationGap.ql create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/ContiguousTimestamps.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/ContiguousTimestamps.ql create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.ql create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/NoBasicBlock.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/NoBasicBlock.ql create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/NoSharedReachable.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/NoSharedReachable.ql create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.ql diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/AllLiveReachable.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/AllLiveReachable.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/AllLiveReachable.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/AllLiveReachable.ql new file mode 100644 index 00000000000..886ccb4c348 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/AllLiveReachable.ql @@ -0,0 +1,17 @@ +/** + * Checks that every live (non-dead) annotation in the test function's + * own scope is reachable from the function entry in the CFG. + * Annotations in nested scopes (generators, async, lambdas, comprehensions) + * have separate CFGs and are excluded from this check. + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils +private import Utils::CfgTests + +from TimerCfgNode a, TestFunction f +where allLiveReachable(a, f) +select a, "Unreachable live annotation; entry of $@ does not reach this node", f, f.getName() diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/AnnotationHasCfgNode.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/AnnotationHasCfgNode.expected new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/AnnotationHasCfgNode.expected @@ -0,0 +1 @@ + diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/AnnotationHasCfgNode.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/AnnotationHasCfgNode.ql new file mode 100644 index 00000000000..04c01abf8a6 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/AnnotationHasCfgNode.ql @@ -0,0 +1,14 @@ +/** + * Checks that every timer annotation has a corresponding CFG node. + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils::CfgTests + +from TimerAnnotation ann +where annotationWithoutCfgNode(ann) +select ann, "Annotation in $@ has no CFG node", ann.getTestFunction(), + ann.getTestFunction().getName() diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockAnnotationGap.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockAnnotationGap.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockAnnotationGap.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockAnnotationGap.ql new file mode 100644 index 00000000000..691144e06e4 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockAnnotationGap.ql @@ -0,0 +1,21 @@ +/** + * Checks that within a basic block, if a node is annotated then its + * successor is also annotated (or excluded). A gap in annotations + * within a basic block indicates a missing annotation, since there + * are no branches to justify the gap. + * + * Nodes with exceptional successors are excluded, as the exception + * edge leaves the basic block and the normal successor may be dead. + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils +private import Utils::CfgTests + +from TimerCfgNode a, CfgNode succ +where basicBlockAnnotationGap(a, succ) +select a, "Annotated node followed by unannotated $@ in the same basic block", succ, + succ.getNode().toString() diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/ContiguousTimestamps.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/ContiguousTimestamps.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/ContiguousTimestamps.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/ContiguousTimestamps.ql new file mode 100644 index 00000000000..f18c52750b5 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/ContiguousTimestamps.ql @@ -0,0 +1,17 @@ +/** + * Checks that timestamps form a contiguous sequence {0, 1, ..., max} + * within each test function. Every integer in the range must appear + * in at least one annotation (live or dead). + */ + +import TimerUtils + +from TestFunction f, int missing, int maxTs, TimerAnnotation maxAnn +where + maxTs = max(TimerAnnotation a | a.getTestFunction() = f | a.getATimestamp()) and + maxAnn.getTestFunction() = f and + maxAnn.getATimestamp() = maxTs and + missing = [0 .. maxTs] and + not exists(TimerAnnotation a | a.getTestFunction() = f and a.getATimestamp() = missing) +select f, "Missing timestamp " + missing + " (max is $@)", maxAnn.getTimestampExpr(maxTs), + maxTs.toString() diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.expected new file mode 100644 index 00000000000..775cc7bdbbf --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.expected @@ -0,0 +1,11 @@ +| test_boolean.py:9:10:9:43 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:9:59:9:59 | IntegerLiteral | 2 | test_boolean.py:9:10:9:13 | ControlFlowNode for True | True | test_boolean.py:9:19:9:19 | IntegerLiteral | 0 | +| test_boolean.py:15:10:15:43 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:15:50:15:50 | IntegerLiteral | 1 | test_boolean.py:15:10:15:14 | ControlFlowNode for False | False | test_boolean.py:15:20:15:20 | IntegerLiteral | 0 | +| test_boolean.py:21:10:21:42 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:21:49:21:49 | IntegerLiteral | 1 | test_boolean.py:21:10:21:13 | ControlFlowNode for True | True | test_boolean.py:21:19:21:19 | IntegerLiteral | 0 | +| test_boolean.py:27:10:27:43 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:27:59:27:59 | IntegerLiteral | 2 | test_boolean.py:27:10:27:14 | ControlFlowNode for False | False | test_boolean.py:27:20:27:20 | IntegerLiteral | 0 | +| test_boolean.py:40:10:40:61 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:40:86:40:86 | IntegerLiteral | 3 | test_boolean.py:40:10:40:10 | ControlFlowNode for IntegerLiteral | IntegerLiteral | test_boolean.py:40:16:40:16 | IntegerLiteral | 0 | +| test_boolean.py:46:10:46:61 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:46:86:46:86 | IntegerLiteral | 3 | test_boolean.py:46:10:46:10 | ControlFlowNode for IntegerLiteral | IntegerLiteral | test_boolean.py:46:16:46:16 | IntegerLiteral | 0 | +| test_boolean.py:52:10:52:95 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:52:120:52:120 | IntegerLiteral | 4 | test_boolean.py:52:11:52:47 | ControlFlowNode for BoolExpr | BoolExpr | test_boolean.py:52:63:52:63 | IntegerLiteral | 2 | +| test_boolean.py:52:11:52:47 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:52:63:52:63 | IntegerLiteral | 2 | test_boolean.py:52:11:52:14 | ControlFlowNode for True | True | test_boolean.py:52:20:52:20 | IntegerLiteral | 0 | +| test_boolean.py:64:10:64:52 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:64:59:64:59 | IntegerLiteral | 6 | test_boolean.py:64:11:64:11 | ControlFlowNode for f | f | test_boolean.py:64:17:64:17 | IntegerLiteral | 0 | +| test_boolean.py:76:10:76:51 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:76:58:76:58 | IntegerLiteral | 6 | test_boolean.py:76:11:76:11 | ControlFlowNode for f | f | test_boolean.py:76:17:76:17 | IntegerLiteral | 0 | +| test_if.py:96:9:96:29 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_if.py:96:36:96:36 | IntegerLiteral | 4 | test_if.py:96:9:96:9 | ControlFlowNode for x | x | test_if.py:96:15:96:15 | IntegerLiteral | 2 | diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.ql new file mode 100644 index 00000000000..e9926284295 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.ql @@ -0,0 +1,17 @@ +/** + * Checks that time never flows backward between consecutive timer annotations + * in the CFG. For each pair of consecutive annotated nodes (A -> B), there must + * exist timestamps a in A and b in B with a < b. + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils +private import Utils::CfgTests + +from TimerCfgNode a, TimerCfgNode b, int minA, int maxB +where noBackwardFlow(a, b, minA, maxB) +select a, "Backward flow: $@ flows to $@ (max timestamp $@)", a.getTimestampExpr(minA), + minA.toString(), b, b.getNode().toString(), b.getTimestampExpr(maxB), maxB.toString() diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBasicBlock.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBasicBlock.expected new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBasicBlock.expected @@ -0,0 +1 @@ + diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBasicBlock.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBasicBlock.ql new file mode 100644 index 00000000000..82d9589a975 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBasicBlock.ql @@ -0,0 +1,14 @@ +/** + * Checks that every annotated CFG node belongs to a basic block. + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils +private import Utils::CfgTests + +from CfgNode n, TestFunction f +where noBasicBlock(n, f) +select n, "CFG node in $@ does not belong to any basic block", f, f.getName() diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/NoSharedReachable.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoSharedReachable.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/NoSharedReachable.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoSharedReachable.ql new file mode 100644 index 00000000000..e9f685e8ffa --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoSharedReachable.ql @@ -0,0 +1,16 @@ +/** + * Checks that two annotations sharing a timestamp value are on + * mutually exclusive CFG paths (neither can reach the other). + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils +private import Utils::CfgTests + +from TimerCfgNode a, TimerCfgNode b, int ts +where noSharedReachable(a, b, ts) +select a, "Shared timestamp $@ but this node reaches $@", a.getTimestampExpr(ts), ts.toString(), b, + b.getNode().toString() diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/OldCfgImpl.qll b/python/ql/test/library-tests/ControlFlow/evaluation-order/OldCfgImpl.qll index fc52c8dd3ed..cb7bbb495b8 100644 --- a/python/ql/test/library-tests/ControlFlow/evaluation-order/OldCfgImpl.qll +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/OldCfgImpl.qll @@ -3,14 +3,14 @@ * Python control flow graph. */ -private import python as Py +private import python as PY import TimerUtils /** Existing Python CFG implementation of the evaluation-order signature. */ module OldCfg implements EvalOrderCfgSig { - class CfgNode = Py::ControlFlowNode; + class CfgNode = PY::ControlFlowNode; - class BasicBlock = Py::BasicBlock; + class BasicBlock = PY::BasicBlock; - CfgNode scopeGetEntryNode(Py::Scope s) { result = s.getEntryNode() } + CfgNode scopeGetEntryNode(PY::Scope s) { result = s.getEntryNode() } } diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.expected new file mode 100644 index 00000000000..34e050b0f8a --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.expected @@ -0,0 +1,11 @@ +| test_boolean.py:9:10:9:43 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:9:59:9:59 | IntegerLiteral | timestamp 2 | test_boolean.py:9:19:9:19 | IntegerLiteral | timestamp 0 | +| test_boolean.py:15:10:15:43 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:15:50:15:50 | IntegerLiteral | timestamp 1 | test_boolean.py:15:20:15:20 | IntegerLiteral | timestamp 0 | +| test_boolean.py:21:10:21:42 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:21:49:21:49 | IntegerLiteral | timestamp 1 | test_boolean.py:21:19:21:19 | IntegerLiteral | timestamp 0 | +| test_boolean.py:27:10:27:43 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:27:59:27:59 | IntegerLiteral | timestamp 2 | test_boolean.py:27:20:27:20 | IntegerLiteral | timestamp 0 | +| test_boolean.py:40:10:40:61 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:40:86:40:86 | IntegerLiteral | timestamp 3 | test_boolean.py:40:16:40:16 | IntegerLiteral | timestamp 0 | +| test_boolean.py:46:10:46:61 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:46:86:46:86 | IntegerLiteral | timestamp 3 | test_boolean.py:46:16:46:16 | IntegerLiteral | timestamp 0 | +| test_boolean.py:52:10:52:95 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:52:120:52:120 | IntegerLiteral | timestamp 4 | test_boolean.py:52:63:52:63 | IntegerLiteral | timestamp 2 | +| test_boolean.py:52:11:52:47 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:52:63:52:63 | IntegerLiteral | timestamp 2 | test_boolean.py:52:20:52:20 | IntegerLiteral | timestamp 0 | +| test_boolean.py:64:10:64:52 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:64:59:64:59 | IntegerLiteral | timestamp 6 | test_boolean.py:64:17:64:17 | IntegerLiteral | timestamp 0 | +| test_boolean.py:76:10:76:51 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:76:58:76:58 | IntegerLiteral | timestamp 6 | test_boolean.py:76:17:76:17 | IntegerLiteral | timestamp 0 | +| test_if.py:96:9:96:29 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_if.py:96:36:96:36 | IntegerLiteral | timestamp 4 | test_if.py:96:15:96:15 | IntegerLiteral | timestamp 2 | diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.ql new file mode 100644 index 00000000000..79b383a4acf --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.ql @@ -0,0 +1,17 @@ +/** + * Stronger version of NoBackwardFlow: for consecutive annotated nodes + * A -> B that both have a single timestamp (non-loop code) and B does + * NOT dominate A (forward edge), requires max(A) < min(B). + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils +private import Utils::CfgTests + +from TimerCfgNode a, TimerCfgNode b, int maxA, int minB +where strictForward(a, b, maxA, minB) +select a, "Strict forward violation: $@ flows to $@", a.getTimestampExpr(maxA), "timestamp " + maxA, + b.getTimestampExpr(minB), "timestamp " + minB From fc2bc26f36f2250ce53dc46ea7b383dbee6c12ff Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 28 Apr 2026 15:06:56 +0000 Subject: [PATCH 020/226] Python: Add BasicBlockOrdering test This one demonstrates a bug in the current CFG. In a dictionary comprehension `{k: v for k, v in d.items()}`, we evaluate the value before the key, which is incorrect. (A fix for this bug has been implemented in a separate PR.) --- .../evaluation-order/BasicBlockOrdering.expected | 14 ++++++++++++++ .../evaluation-order/BasicBlockOrdering.ql | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.ql diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.expected new file mode 100644 index 00000000000..c5ef1ba9394 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.expected @@ -0,0 +1,14 @@ +| test_boolean.py:9:10:9:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:9:59:9:59 | IntegerLiteral | timestamp 2 | test_boolean.py:9:19:9:19 | IntegerLiteral | timestamp 0 | +| test_boolean.py:15:10:15:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:15:50:15:50 | IntegerLiteral | timestamp 1 | test_boolean.py:15:20:15:20 | IntegerLiteral | timestamp 0 | +| test_boolean.py:21:10:21:42 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:21:49:21:49 | IntegerLiteral | timestamp 1 | test_boolean.py:21:19:21:19 | IntegerLiteral | timestamp 0 | +| test_boolean.py:27:10:27:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:27:59:27:59 | IntegerLiteral | timestamp 2 | test_boolean.py:27:20:27:20 | IntegerLiteral | timestamp 0 | +| test_boolean.py:40:10:40:61 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:40:86:40:86 | IntegerLiteral | timestamp 3 | test_boolean.py:40:16:40:16 | IntegerLiteral | timestamp 0 | +| test_boolean.py:46:10:46:61 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:46:86:46:86 | IntegerLiteral | timestamp 3 | test_boolean.py:46:16:46:16 | IntegerLiteral | timestamp 0 | +| test_boolean.py:52:10:52:95 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:52:120:52:120 | IntegerLiteral | timestamp 4 | test_boolean.py:52:20:52:20 | IntegerLiteral | timestamp 0 | +| test_boolean.py:52:10:52:95 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:52:120:52:120 | IntegerLiteral | timestamp 4 | test_boolean.py:52:63:52:63 | IntegerLiteral | timestamp 2 | +| test_boolean.py:52:11:52:47 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:52:63:52:63 | IntegerLiteral | timestamp 2 | test_boolean.py:52:20:52:20 | IntegerLiteral | timestamp 0 | +| test_boolean.py:64:10:64:52 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:64:59:64:59 | IntegerLiteral | timestamp 6 | test_boolean.py:64:17:64:17 | IntegerLiteral | timestamp 0 | +| test_boolean.py:64:10:64:52 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:64:59:64:59 | IntegerLiteral | timestamp 6 | test_boolean.py:64:27:64:27 | IntegerLiteral | timestamp 2 | +| test_boolean.py:76:10:76:51 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:76:58:76:58 | IntegerLiteral | timestamp 6 | test_boolean.py:76:17:76:17 | IntegerLiteral | timestamp 0 | +| test_boolean.py:76:10:76:51 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:76:58:76:58 | IntegerLiteral | timestamp 6 | test_boolean.py:76:27:76:27 | IntegerLiteral | timestamp 2 | +| test_if.py:96:9:96:29 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_if.py:96:36:96:36 | IntegerLiteral | timestamp 4 | test_if.py:96:15:96:15 | IntegerLiteral | timestamp 2 | diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.ql new file mode 100644 index 00000000000..6c08d44a5a5 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.ql @@ -0,0 +1,16 @@ +/** + * Checks that within a single basic block, annotations appear in + * increasing minimum-timestamp order. + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils +private import Utils::CfgTests + +from TimerCfgNode a, TimerCfgNode b, int minA, int minB +where basicBlockOrdering(a, b, minA, minB) +select a, "Basic block ordering: $@ appears before $@", a.getTimestampExpr(minA), + "timestamp " + minA, b.getTimestampExpr(minB), "timestamp " + minB From c30d6ae3aa156f460177959152bce299fdc6061c Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 28 Apr 2026 15:07:04 +0000 Subject: [PATCH 021/226] Python: Add NeverReachable test This looks for nodes annotated with `t[never]` in the test that are reachable in the CFG. This should not happen (it messes with various queries, e.g. the "mixed returns" query), but the test shows that in a few particular cases (involving the `match` statement where all cases contain `return`s), we _do_ have reachable nodes that shouldn't be. --- .../evaluation-order/NeverReachable.expected | 2 ++ .../evaluation-order/NeverReachable.ql | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/NeverReachable.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/NeverReachable.ql diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/NeverReachable.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/NeverReachable.expected new file mode 100644 index 00000000000..874a7dfb096 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/NeverReachable.expected @@ -0,0 +1,2 @@ +| test_match.py:159:13:159:13 | IntegerLiteral | Node annotated with t.never is reachable in $@ | test_match.py:151:1:151:42 | Function test_match_exhaustive_return_first | test_match_exhaustive_return_first | +| test_match.py:172:13:172:13 | IntegerLiteral | Node annotated with t.never is reachable in $@ | test_match.py:164:1:164:45 | Function test_match_exhaustive_return_wildcard | test_match_exhaustive_return_wildcard | diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/NeverReachable.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/NeverReachable.ql new file mode 100644 index 00000000000..9fbb9115814 --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/NeverReachable.ql @@ -0,0 +1,16 @@ +/** + * Checks that expressions annotated with `t.never` either have no CFG + * node, or if they do, that the node is not reachable from its scope's + * entry (including within the same basic block). + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils::CfgTests + +from TimerAnnotation ann +where neverReachable(ann) +select ann, "Node annotated with t.never is reachable in $@", ann.getTestFunction(), + ann.getTestFunction().getName() From f5c3b63a4aab45009976cda132f36564f5db3a34 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 28 Apr 2026 15:07:15 +0000 Subject: [PATCH 022/226] Python: Add ConsecutiveTimestamps test This one is potentially a bit iffy -- it checks for a very powerful property (that implies many of the other queries), but as the test results show, it can produce false positives when there is in fact no problem. We may want to get rid of it entirely, if it becomes too noisy. --- .../ConsecutiveTimestamps.expected | 12 ++++++++++ .../evaluation-order/ConsecutiveTimestamps.ql | 24 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/ConsecutiveTimestamps.expected create mode 100644 python/ql/test/library-tests/ControlFlow/evaluation-order/ConsecutiveTimestamps.ql diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/ConsecutiveTimestamps.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/ConsecutiveTimestamps.expected new file mode 100644 index 00000000000..ed22c971ecb --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/ConsecutiveTimestamps.expected @@ -0,0 +1,12 @@ +| test_boolean.py:9:26:9:27 | IntegerLiteral | $@ in $@ has no consecutive successor (expected 2) | test_boolean.py:9:33:9:33 | IntegerLiteral | Timestamp 1 | test_boolean.py:7:1:7:27 | Function test_and_both_sides | test_and_both_sides | +| test_boolean.py:15:10:15:14 | False | $@ in $@ has no consecutive successor (expected 1) | test_boolean.py:15:20:15:20 | IntegerLiteral | Timestamp 0 | test_boolean.py:13:1:13:30 | Function test_and_short_circuit | test_and_short_circuit | +| test_boolean.py:21:10:21:13 | True | $@ in $@ has no consecutive successor (expected 1) | test_boolean.py:21:19:21:19 | IntegerLiteral | Timestamp 0 | test_boolean.py:19:1:19:29 | Function test_or_short_circuit | test_or_short_circuit | +| test_boolean.py:27:26:27:27 | IntegerLiteral | $@ in $@ has no consecutive successor (expected 2) | test_boolean.py:27:33:27:33 | IntegerLiteral | Timestamp 1 | test_boolean.py:25:1:25:26 | Function test_or_both_sides | test_or_both_sides | +| test_boolean.py:40:45:40:45 | IntegerLiteral | $@ in $@ has no consecutive successor (expected 3) | test_boolean.py:40:51:40:51 | IntegerLiteral | Timestamp 2 | test_boolean.py:38:1:38:24 | Function test_chained_and | test_chained_and | +| test_boolean.py:46:44:46:45 | IntegerLiteral | $@ in $@ has no consecutive successor (expected 3) | test_boolean.py:46:51:46:51 | IntegerLiteral | Timestamp 2 | test_boolean.py:44:1:44:23 | Function test_chained_or | test_chained_or | +| test_boolean.py:52:11:52:47 | BoolExpr | $@ in $@ has no consecutive successor (expected 3) | test_boolean.py:52:63:52:63 | IntegerLiteral | Timestamp 2 | test_boolean.py:50:1:50:25 | Function test_mixed_and_or | test_mixed_and_or | +| test_boolean.py:52:27:52:31 | False | $@ in $@ has no consecutive successor (expected 2) | test_boolean.py:52:37:52:37 | IntegerLiteral | Timestamp 1 | test_boolean.py:50:1:50:25 | Function test_mixed_and_or | test_mixed_and_or | +| test_boolean.py:52:78:52:79 | IntegerLiteral | $@ in $@ has no consecutive successor (expected 4) | test_boolean.py:52:85:52:85 | IntegerLiteral | Timestamp 3 | test_boolean.py:50:1:50:25 | Function test_mixed_and_or | test_mixed_and_or | +| test_if.py:95:9:95:13 | False | $@ in $@ has no consecutive successor (expected 2) | test_if.py:95:19:95:19 | IntegerLiteral | Timestamp 1 | test_if.py:93:1:93:34 | Function test_if_compound_condition | test_if_compound_condition | +| test_if.py:96:9:96:29 | BoolExpr | $@ in $@ has no consecutive successor (expected 5) | test_if.py:96:36:96:36 | IntegerLiteral | Timestamp 4 | test_if.py:93:1:93:34 | Function test_if_compound_condition | test_if_compound_condition | +| test_if.py:96:22:96:22 | y | $@ in $@ has no consecutive successor (expected 4) | test_if.py:96:28:96:28 | IntegerLiteral | Timestamp 3 | test_if.py:93:1:93:34 | Function test_if_compound_condition | test_if_compound_condition | diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/ConsecutiveTimestamps.ql b/python/ql/test/library-tests/ControlFlow/evaluation-order/ConsecutiveTimestamps.ql new file mode 100644 index 00000000000..01ff59b49bf --- /dev/null +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/ConsecutiveTimestamps.ql @@ -0,0 +1,24 @@ +/** + * Checks that consecutive annotated nodes have consecutive timestamps: + * for each annotation with timestamp `a`, some CFG node for that annotation + * must have a next annotation containing `a + 1`. + * + * Handles CFG splitting (e.g., finally blocks duplicated for normal/exceptional + * flow) by checking that at least one split has the required successor. + * + * Only applies to functions where all annotations are in the function's + * own scope (excludes tests with generators, async, comprehensions, or + * lambdas that have annotations in nested scopes). + */ + +import OldCfgImpl + +private module Utils = EvalOrderCfgUtils; + +private import Utils +private import Utils::CfgTests + +from TimerAnnotation ann, int a +where consecutiveTimestamps(ann, a) +select ann, "$@ in $@ has no consecutive successor (expected " + (a + 1) + ")", + ann.getTimestampExpr(a), "Timestamp " + a, ann.getTestFunction(), ann.getTestFunction().getName() From 9dddd93460cf70dd2802101bb9fc68b3d26d7769 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 8 May 2026 21:40:53 +0000 Subject: [PATCH 023/226] unified: add field declarations for statements and members Part 1 of N of "getting rid of $children" in node-types.yml Note: in one of the cases the affected node still has the $children field present. This is because there's some weirdness about recording multiline comments as class member separators that I did not want to figure out how to address right now. --- unified/extractor/tree-sitter-swift/grammar.js | 16 ++++++++-------- .../extractor/tree-sitter-swift/node-types.yml | 12 +++++++----- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 5dbfd7fdbbf..76e8020b0b8 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -255,11 +255,11 @@ module.exports = grammar({ //////////////////////////////// source_file: ($) => seq( - optional($.shebang_line), + optional(field("shebang", $.shebang_line)), optional( seq( - $._top_level_statement, - repeat(seq($._semi, $._top_level_statement)), + field("statement", $._top_level_statement), + repeat(seq($._semi, field("statement", $._top_level_statement))), optional($._semi) ) ) @@ -1182,8 +1182,8 @@ module.exports = grammar({ prec.left( // Left precedence is required in switch statements seq( - $._local_statement, - repeat(seq($._semi, $._local_statement)), + field("statement", $._local_statement), + repeat(seq($._semi, field("statement", $._local_statement))), optional($._semi) ) ), @@ -1605,7 +1605,7 @@ module.exports = grammar({ _class_member_separator: ($) => choice($._semi, $.multiline_comment), _class_member_declarations: ($) => seq( - sep1($.type_level_declaration, $._class_member_separator), + sep1(field("member", $.type_level_declaration), $._class_member_separator), optional($._class_member_separator) ), _function_value_parameters: ($) => @@ -1673,7 +1673,7 @@ module.exports = grammar({ throws_clause: ($) => seq($._throws_keyword, "(", field("type", $.unannotated_type), ")"), enum_class_body: ($) => - seq("{", repeat(choice($.enum_entry, $.type_level_declaration)), "}"), + seq("{", repeat(field("member", choice($.enum_entry, $.type_level_declaration))), "}"), enum_entry: ($) => seq( optional($.modifiers), @@ -1725,7 +1725,7 @@ module.exports = grammar({ protocol_body: ($) => seq("{", optional($._protocol_member_declarations), "}"), _protocol_member_declarations: ($) => - seq(sep1($.protocol_member_declaration, $._semi), optional($._semi)), + seq(sep1(field("member", $.protocol_member_declaration), $._semi), optional($._semi)), protocol_member_declaration: ($) => choice( $.protocol_function_declaration, diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index c4bf650944b..7d9d096d9c9 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -166,7 +166,8 @@ named: target: expression type: type class_body: - $children*: [multiline_comment, type_level_declaration] + $children*: multiline_comment + member*: type_level_declaration class_declaration: $children*: [attribute, inheritance_modifier, inheritance_specifier, modifiers, ownership_modifier, property_behavior_modifier, type_constraints, type_parameters] body: [class_body, enum_class_body] @@ -226,7 +227,7 @@ named: $children*: [catch_block, statements] else: enum_class_body: - $children*: [enum_entry, type_level_declaration] + member*: [enum_entry, type_level_declaration] enum_entry: $children?: modifiers data_contents*: enum_type_parameters @@ -410,7 +411,7 @@ named: value*: expression property_modifier: protocol_body: - $children*: protocol_member_declaration + member*: protocol_member_declaration protocol_composition_type: $children+: unannotated_type protocol_declaration: @@ -459,11 +460,12 @@ named: shebang_line: simple_identifier: source_file: - $children*: [do_statement, expression, for_statement, global_declaration, guard_statement, repeat_while_statement, shebang_line, statement_label, throw_keyword, while_statement] + shebang?: shebang_line + statement*: [do_statement, expression, for_statement, global_declaration, guard_statement, repeat_while_statement, statement_label, throw_keyword, while_statement] special_literal: statement_label: statements: - $children+: [control_transfer_statement, do_statement, expression, for_statement, guard_statement, local_declaration, repeat_while_statement, statement_label, while_statement] + statement+: [control_transfer_statement, do_statement, expression, for_statement, guard_statement, local_declaration, repeat_while_statement, statement_label, while_statement] str_escaped_char: subscript_declaration: $children+: [attribute, computed_property, modifiers, parameter, type_constraints, type_parameters] From 75c07996f38184cbbc0467f35a4f8b05c3afd804 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 8 May 2026 21:42:21 +0000 Subject: [PATCH 024/226] unified: regenerate files --- unified/ql/lib/codeql/unified/Ast.qll | 38 +++++++++++++++++---------- unified/ql/lib/unified.dbscheme | 36 ++++++++++++++++--------- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/unified/ql/lib/codeql/unified/Ast.qll b/unified/ql/lib/codeql/unified/Ast.qll index 5b9491fdb9f..dbe217fb951 100644 --- a/unified/ql/lib/codeql/unified/Ast.qll +++ b/unified/ql/lib/codeql/unified/Ast.qll @@ -436,11 +436,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ClassBody" } + /** Gets the node corresponding to the field `member`. */ + final TypeLevelDeclaration getMember(int i) { swift_class_body_member(this, i, result) } + /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_class_body_child(this, i, result) } + final MultilineComment getChild(int i) { swift_class_body_child(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_class_body_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_class_body_member(this, _, result) or swift_class_body_child(this, _, result) + } } /** A class representing `class_declaration` nodes. */ @@ -818,11 +823,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "EnumClassBody" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_enum_class_body_child(this, i, result) } + /** Gets the node corresponding to the field `member`. */ + final AstNode getMember(int i) { swift_enum_class_body_member(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_enum_class_body_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_enum_class_body_member(this, _, result) } } /** A class representing `enum_entry` nodes. */ @@ -1927,11 +1932,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ProtocolBody" } - /** Gets the `i`th child of this node. */ - final ProtocolMemberDeclaration getChild(int i) { swift_protocol_body_child(this, i, result) } + /** Gets the node corresponding to the field `member`. */ + final ProtocolMemberDeclaration getMember(int i) { swift_protocol_body_member(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_protocol_body_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_protocol_body_member(this, _, result) } } /** A class representing `protocol_composition_type` nodes. */ @@ -2231,11 +2236,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SourceFile" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_source_file_child(this, i, result) } + /** Gets the node corresponding to the field `shebang`. */ + final ShebangLine getShebang() { swift_source_file_shebang(this, result) } + + /** Gets the node corresponding to the field `statement`. */ + final AstNode getStatement(int i) { swift_source_file_statement(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_source_file_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_source_file_shebang(this, result) or swift_source_file_statement(this, _, result) + } } /** A class representing `special_literal` tokens. */ @@ -2255,11 +2265,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Statements" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_statements_child(this, i, result) } + /** Gets the node corresponding to the field `statement`. */ + final AstNode getStatement(int i) { swift_statements_statement(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_statements_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_statements_statement(this, _, result) } } /** A class representing `str_escaped_char` tokens. */ diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme index b50bc56eaa2..5d9826b69a8 100644 --- a/unified/ql/lib/unified.dbscheme +++ b/unified/ql/lib/unified.dbscheme @@ -356,13 +356,18 @@ swift_check_expression_def( int type__: @swift_type__ ref ); -@swift_class_body_child_type = @swift_token_multiline_comment | @swift_type_level_declaration +#keyset[swift_class_body, index] +swift_class_body_member( + int swift_class_body: @swift_class_body ref, + int index: int ref, + unique int member: @swift_type_level_declaration ref +); #keyset[swift_class_body, index] swift_class_body_child( int swift_class_body: @swift_class_body ref, int index: int ref, - unique int child: @swift_class_body_child_type ref + unique int child: @swift_token_multiline_comment ref ); swift_class_body_def( @@ -626,13 +631,13 @@ swift_do_statement_def( unique int id: @swift_do_statement ); -@swift_enum_class_body_child_type = @swift_enum_entry | @swift_type_level_declaration +@swift_enum_class_body_member_type = @swift_enum_entry | @swift_type_level_declaration #keyset[swift_enum_class_body, index] -swift_enum_class_body_child( +swift_enum_class_body_member( int swift_enum_class_body: @swift_enum_class_body ref, int index: int ref, - unique int child: @swift_enum_class_body_child_type ref + unique int member: @swift_enum_class_body_member_type ref ); swift_enum_class_body_def( @@ -1443,10 +1448,10 @@ swift_property_declaration_def( ); #keyset[swift_protocol_body, index] -swift_protocol_body_child( +swift_protocol_body_member( int swift_protocol_body: @swift_protocol_body ref, int index: int ref, - unique int child: @swift_protocol_member_declaration ref + unique int member: @swift_protocol_member_declaration ref ); swift_protocol_body_def( @@ -1642,26 +1647,31 @@ swift_setter_specifier_def( unique int id: @swift_setter_specifier ); -@swift_source_file_child_type = @swift_do_statement | @swift_expression | @swift_for_statement | @swift_global_declaration | @swift_guard_statement | @swift_repeat_while_statement | @swift_token_shebang_line | @swift_token_statement_label | @swift_token_throw_keyword | @swift_while_statement +swift_source_file_shebang( + unique int swift_source_file: @swift_source_file ref, + unique int shebang: @swift_token_shebang_line ref +); + +@swift_source_file_statement_type = @swift_do_statement | @swift_expression | @swift_for_statement | @swift_global_declaration | @swift_guard_statement | @swift_repeat_while_statement | @swift_token_statement_label | @swift_token_throw_keyword | @swift_while_statement #keyset[swift_source_file, index] -swift_source_file_child( +swift_source_file_statement( int swift_source_file: @swift_source_file ref, int index: int ref, - unique int child: @swift_source_file_child_type ref + unique int statement: @swift_source_file_statement_type ref ); swift_source_file_def( unique int id: @swift_source_file ); -@swift_statements_child_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement +@swift_statements_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement #keyset[swift_statements, index] -swift_statements_child( +swift_statements_statement( int swift_statements: @swift_statements ref, int index: int ref, - unique int child: @swift_statements_child_type ref + unique int statement: @swift_statements_statement_type ref ); swift_statements_def( From c75d819a928d8ca4b3a7c486e05d9f3abf387567 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 13:46:25 +0000 Subject: [PATCH 025/226] unified: Add `effect` field I ended up also aliasing `_async_keyword` to a named node to make it more consistent with the other node kinds that can be in this field (as it would be awkward to have two named types and a token here). Elsewhere in the node types, we'll still have `async?: "async"`, and I think that's okay. --- unified/extractor/tree-sitter-swift/grammar.js | 2 +- unified/extractor/tree-sitter-swift/node-types.yml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 76e8020b0b8..75d7c450bf0 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1804,7 +1804,7 @@ module.exports = grammar({ setter_specifier: ($) => seq(optional($.mutation_modifier), "set"), modify_specifier: ($) => seq(optional($.mutation_modifier), "_modify"), _getter_effects: ($) => - repeat1(choice($._async_keyword, $.throws_clause, $.throws)), + repeat1(field("effect", choice(alias($._async_keyword, $.async_keyword), $.throws_clause, $.throws))), operator_declaration: ($) => seq( choice("prefix", "infix", "postfix"), diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 7d9d096d9c9..219904ae939 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -132,6 +132,7 @@ named: default_value?: type must_inherit?: type name: type_identifier + async_keyword: attribute: $children+: [expression, user_type] availability_condition: @@ -266,7 +267,8 @@ named: params: unannotated_type return_type: type getter_specifier: - $children*: [mutation_modifier, throws, throws_clause] + $children?: mutation_modifier + effect*: [async_keyword, throws, throws_clause] guard_statement: $children+: [else, statements] condition+: if_condition From d6ef467fba82e0ddab0f86e0458a1ad413a8501c Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 13:59:56 +0000 Subject: [PATCH 026/226] unified: Add more fields A lot of changes, but for the most part these are just adding named fields in places where they make sense. After this, there are still ~20 instances of unnamed children appearing. --- .../extractor/tree-sitter-swift/grammar.js | 318 +++++++++--------- .../tree-sitter-swift/node-types.yml | 276 ++++++++++----- 2 files changed, 343 insertions(+), 251 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 75d7c450bf0..9137fb94cee 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -291,7 +291,7 @@ module.exports = grammar({ "package", $._parameter_ownership_modifier ), - identifier: ($) => sep1($.simple_identifier, $._dot), + identifier: ($) => sep1(field("part", $.simple_identifier), $._dot), // Literals _basic_literal: ($) => choice( @@ -355,13 +355,13 @@ module.exports = grammar({ seq( field("text", $.raw_str_part), field("interpolation", $.raw_str_interpolation), - optional($.raw_str_continuing_indicator) + field("continuing", optional($.raw_str_continuing_indicator)) ) ), field("text", $.raw_str_end_part) ), raw_str_interpolation: ($) => - seq($.raw_str_interpolation_start, $._interpolation_contents, ")"), + seq(field("start", $.raw_str_interpolation_start), $._interpolation_contents, ")"), raw_str_interpolation_start: ($) => /\\#*\(/, _multi_line_string_content: ($) => choice($.multi_line_str_text, $.str_escaped_char, '"'), @@ -410,7 +410,7 @@ module.exports = grammar({ _possibly_implicitly_unwrapped_type: ($) => choice($.type, $.implicitly_unwrapped_type), implicitly_unwrapped_type: ($) => - seq($.type, token.immediate("!")), + seq(field("name", $.type), token.immediate("!")), type: ($) => prec.right( PRECS.ty, @@ -436,7 +436,7 @@ module.exports = grammar({ ) ), // The grammar just calls this whole thing a `type-identifier` but that's a bit confusing. - user_type: ($) => sep1($._simple_user_type, $._dot), + user_type: ($) => sep1(field("part", $._simple_user_type), $._dot), _simple_user_type: ($) => prec.right( PRECS.ty, @@ -459,7 +459,7 @@ module.exports = grammar({ PRECS.expr, seq( optional($._tuple_type_item_identifier), - optional($.parameter_modifiers), + field("modifiers", optional($.parameter_modifiers)), field("type", $.type) ) ), @@ -475,8 +475,8 @@ module.exports = grammar({ function_type: ($) => seq( field("params", choice($.tuple_type, $.unannotated_type)), - optional($._async_keyword), - optional(choice($.throws_clause, $.throws)), + field("async", optional($._async_keyword)), + field("throws", optional(choice($.throws_clause, $.throws))), $._arrow_operator, field("return_type", $.type) ), @@ -493,18 +493,18 @@ module.exports = grammar({ repeat1(alias($._immediate_quest, "?")) ) ), - metatype: ($) => seq($.unannotated_type, ".", choice("Type", "Protocol")), + metatype: ($) => seq(field("name", $.unannotated_type), ".", choice("Type", "Protocol")), _quest: ($) => "?", _immediate_quest: ($) => token.immediate("?"), - opaque_type: ($) => prec.right(seq("some", $.unannotated_type)), - existential_type: ($) => prec.right(seq("any", $.unannotated_type)), - type_parameter_pack: ($) => prec.left(seq("each", $.unannotated_type)), - type_pack_expansion: ($) => prec.left(seq("repeat", $.unannotated_type)), + opaque_type: ($) => prec.right(seq("some", field("name", $.unannotated_type))), + existential_type: ($) => prec.right(seq("any", field("name", $.unannotated_type))), + type_parameter_pack: ($) => prec.left(seq("each", field("name", $.unannotated_type))), + type_pack_expansion: ($) => prec.left(seq("repeat", field("name", $.unannotated_type))), protocol_composition_type: ($) => prec.left( seq( - $.unannotated_type, - repeat1(seq("&", prec.right($.unannotated_type))) + field("type", $.unannotated_type), + repeat1(seq("&", prec.right(field("type", $.unannotated_type)))) ) ), suppressed_constraint: ($) => @@ -535,7 +535,7 @@ module.exports = grammar({ ) ), optional_chain_marker: ($) => - seq($.expression, alias($._immediate_quest, "?")), + seq(field("expr", $.expression), alias($._immediate_quest, "?")), // Unary expressions _unary_expression: ($) => choice( @@ -568,7 +568,7 @@ module.exports = grammar({ "constructed_type", choice($.array_type, $.dictionary_type, $.user_type) ), - $.constructor_suffix + field("suffix", $.constructor_suffix) ) ), _parenthesized_type: ($) => @@ -626,7 +626,7 @@ module.exports = grammar({ as_expression: ($) => prec.left( PRECS.as, - seq(field("expr", $.expression), $.as_operator, field("type", $.type)) + seq(field("expr", $.expression), field("operator", $.as_operator), field("type", $.type)) ), selector_expression: ($) => seq( @@ -634,7 +634,7 @@ module.exports = grammar({ "selector", "(", optional(choice("getter:", "setter:")), - $.expression, + field("expr", $.expression), ")" ), // Binary expressions @@ -778,15 +778,15 @@ module.exports = grammar({ ) ), _constructor_value_arguments: ($) => - seq("(", optional(sep1Opt($.value_argument, ",")), ")"), + seq("(", optional(sep1Opt(field("argument", $.value_argument), ",")), ")"), _fn_call_lambda_arguments: ($) => sep1($.lambda_literal, seq(field("name", $.simple_identifier), ":")), - type_arguments: ($) => prec.left(seq("<", sep1Opt($.type, ","), ">")), + type_arguments: ($) => prec.left(seq("<", sep1Opt(field("argument", $.type), ","), ">")), value_arguments: ($) => seq( choice( - seq("(", optional(sep1Opt($.value_argument, ",")), ")"), - seq("[", optional(sep1Opt($.value_argument, ",")), "]") + seq("(", optional(sep1Opt(field("argument", $.value_argument), ",")), ")"), + seq("[", optional(sep1Opt(field("argument", $.value_argument), ",")), "]") ) ), value_argument_label: ($) => @@ -802,7 +802,7 @@ module.exports = grammar({ value_argument: ($) => prec.left( seq( - optional($.type_modifiers), + field("type_modifiers", optional($.type_modifiers)), choice( repeat1( seq(field("reference_specifier", $.value_argument_label), ":") @@ -818,7 +818,7 @@ module.exports = grammar({ prec.right( PRECS["try"], seq( - $.try_operator, + field("operator", $.try_operator), field( "expr", choice( @@ -885,7 +885,7 @@ module.exports = grammar({ call_expression: ($) => prec( PRECS.call, - prec.dynamic(DYNAMIC_PRECS.call, seq($.expression, $.call_suffix)) + prec.dynamic(DYNAMIC_PRECS.call, seq(field("function", $.expression), field("suffix", $.call_suffix))) ), macro_invocation: ($) => prec( @@ -894,9 +894,9 @@ module.exports = grammar({ DYNAMIC_PRECS.call, seq( $._hash_symbol, - $.simple_identifier, - optional($.type_parameters), - $.call_suffix + field("name", $.simple_identifier), + field("type_parameters", optional($.type_parameters)), + field("suffix", $.call_suffix) ) ) ), @@ -965,7 +965,7 @@ module.exports = grammar({ $._hash_symbol, choice("colorLiteral", "fileLiteral", "imageLiteral"), "(", - sep1Opt(seq($.simple_identifier, ":", $.expression), ","), + sep1Opt(seq(field("name", $.simple_identifier), ":", field("value", $.expression)), ","), ")" ), lambda_literal: ($) => @@ -974,25 +974,25 @@ module.exports = grammar({ seq( choice("{", "^{"), optional($._lambda_type_declaration), - optional($.statements), + field("body", optional($.statements)), "}" ) ), _lambda_type_declaration: ($) => seq( - repeat($.attribute), + repeat(field("attribute", $.attribute)), prec(PRECS.expr, optional(field("captures", $.capture_list))), optional(field("type", $.lambda_function_type)), "in" ), - capture_list: ($) => seq("[", sep1Opt($.capture_list_item, ","), "]"), + capture_list: ($) => seq("[", sep1Opt(field("item", $.capture_list_item), ","), "]"), capture_list_item: ($) => choice( field("name", $.self_expression), prec( PRECS.expr, seq( - optional($.ownership_modifier), + field("ownership", optional($.ownership_modifier)), field("name", $.simple_identifier), optional(seq($._equal_sign, field("value", $.expression))) ) @@ -1003,11 +1003,11 @@ module.exports = grammar({ PRECS.expr, seq( choice( - $.lambda_function_type_parameters, - seq("(", optional($.lambda_function_type_parameters), ")") + field("params", $.lambda_function_type_parameters), + seq("(", field("params", optional($.lambda_function_type_parameters)), ")") ), - optional($._async_keyword), - optional(choice($.throws_clause, $.throws)), + field("async", optional($._async_keyword)), + field("throws", optional(choice($.throws_clause, $.throws))), optional( seq( $._arrow_operator, @@ -1016,11 +1016,11 @@ module.exports = grammar({ ) ) ), - lambda_function_type_parameters: ($) => sep1Opt($.lambda_parameter, ","), + lambda_function_type_parameters: ($) => sep1Opt(field("parameter", $.lambda_parameter), ","), lambda_parameter: ($) => seq( choice( - $.self_expression, + field("name", $.self_expression), prec(PRECS.expr, field("name", $.simple_identifier)), prec( PRECS.expr, @@ -1028,7 +1028,7 @@ module.exports = grammar({ optional(field("external_name", $.simple_identifier)), field("name", $.simple_identifier), ":", - optional($.parameter_modifiers), + field("modifiers", optional($.parameter_modifiers)), field("type", $._possibly_implicitly_unwrapped_type) ) ) @@ -1036,7 +1036,7 @@ module.exports = grammar({ ), self_expression: ($) => "self", super_expression: ($) => seq("super"), - _else_options: ($) => choice($._block, $.if_statement), + _else_options: ($) => choice($._block, field("else_branch", $.if_statement)), if_statement: ($) => prec.right( PRECS["if"], @@ -1044,16 +1044,16 @@ module.exports = grammar({ "if", sep1(field("condition", $.if_condition), ","), $._block, - optional(seq($["else"], $._else_options)) + optional(seq(field("else_keyword", $["else"]), $._else_options)) ) ), if_condition: ($) => - choice($.if_let_binding, $.expression, $.availability_condition), + field("kind", choice($.if_let_binding, $.expression, $.availability_condition)), if_let_binding: ($) => seq( $._direct_or_indirect_binding, - optional(seq($._equal_sign, $.expression)), - optional($.where_clause) + optional(seq($._equal_sign, field("value", $.expression))), + field("where", optional($.where_clause)) ), guard_statement: ($) => prec.right( @@ -1061,7 +1061,7 @@ module.exports = grammar({ seq( "guard", sep1(field("condition", $.if_condition), ","), - $["else"], + field("else_keyword", $["else"]), $._block ) ), @@ -1072,7 +1072,7 @@ module.exports = grammar({ "switch", field("expr", $.expression), "{", - repeat($.switch_entry), + repeat(field("entry", $.switch_entry)), "}" ) ), @@ -1096,15 +1096,15 @@ module.exports = grammar({ ), switch_pattern: ($) => alias($._binding_pattern_with_expr, $.pattern), do_statement: ($) => - prec.right(PRECS["do"], seq("do", $._block, repeat($.catch_block))), + prec.right(PRECS["do"], seq("do", $._block, repeat(field("catch", $.catch_block)))), catch_block: ($) => seq( - $.catch_keyword, + field("keyword", $.catch_keyword), field("error", optional(alias($._binding_pattern_no_expr, $.pattern))), - optional($.where_clause), + field("where", optional($.where_clause)), $._block ), - where_clause: ($) => prec.left(seq($.where_keyword, $.expression)), + where_clause: ($) => prec.left(seq(field("keyword", $.where_keyword), field("expr", $.expression))), key_path_expression: ($) => prec.right( PRECS.keypath, @@ -1117,7 +1117,7 @@ module.exports = grammar({ ) ), key_path_string_expression: ($) => - prec.left(seq($._hash_symbol, "keyPath", "(", $.expression, ")")), + prec.left(seq($._hash_symbol, "keyPath", "(", field("expr", $.expression), ")")), _key_path_component: ($) => prec.left( choice( @@ -1173,7 +1173,7 @@ module.exports = grammar({ ), _bitwise_binary_operator: ($) => choice("&", "|", "^", "<<", ">>"), _postfix_unary_operator: ($) => choice("++", "--", $.bang), - directly_assignable_expression: ($) => $.expression, + directly_assignable_expression: ($) => field("expr", $.expression), //////////////////////////////// // Statements - https://docs.swift.org/swift-book/ReferenceManual/Statements.html @@ -1201,7 +1201,7 @@ module.exports = grammar({ $._labeled_statement, $._throw_statement ), - _block: ($) => prec(PRECS.block, seq("{", optional($.statements), "}")), + _block: ($) => prec(PRECS.block, seq("{", field("body", optional($.statements)), "}")), _labeled_statement: ($) => seq( optional($.statement_label), @@ -1221,13 +1221,13 @@ module.exports = grammar({ PRECS.loop, seq( "for", - optional($.try_operator), + field("try", optional($.try_operator)), optional($._await_operator), field("item", alias($._binding_pattern_no_expr, $.pattern)), - optional($.type_annotation), + field("type", optional($.type_annotation)), "in", field("collection", $._for_statement_collection), - optional($.where_clause), + field("where", optional($.where_clause)), $._block ) ), @@ -1246,7 +1246,7 @@ module.exports = grammar({ "while", sep1(field("condition", $.if_condition), ","), "{", - optional($.statements), + field("body", optional($.statements)), "}" ) ), @@ -1256,7 +1256,7 @@ module.exports = grammar({ seq( "repeat", "{", - optional($.statements), + field("body", optional($.statements)), "}", // Make sure we make it to the `while` before assuming this is a parameter pack. repeat($._implicit_semi), @@ -1270,7 +1270,7 @@ module.exports = grammar({ prec.right( PRECS.control_transfer, seq( - $._optionally_valueful_control_keyword, + field("kind", $._optionally_valueful_control_keyword), field("result", optional($.expression)) ) ) @@ -1289,9 +1289,9 @@ module.exports = grammar({ ) ), value_parameter_pack: ($) => - prec.left(PRECS.parameter_pack, seq("each", $.expression)), + prec.left(PRECS.parameter_pack, seq("each", field("expr", $.expression))), value_pack_expansion: ($) => - prec.left(PRECS.parameter_pack, seq("repeat", $.expression)), + prec.left(PRECS.parameter_pack, seq("repeat", field("expr", $.expression))), availability_condition: ($) => seq( $._hash_symbol, @@ -1343,30 +1343,30 @@ module.exports = grammar({ ), _local_property_declaration: ($) => seq( - optional($._locally_permitted_modifiers), + field("modifiers", optional($._locally_permitted_modifiers)), $._modifierless_property_declaration ), _local_typealias_declaration: ($) => seq( - optional($._locally_permitted_modifiers), + field("modifiers", optional($._locally_permitted_modifiers)), $._modifierless_typealias_declaration ), _local_function_declaration: ($) => seq( - optional($._locally_permitted_modifiers), + field("modifiers", optional($._locally_permitted_modifiers)), $._modifierless_function_declaration ), _local_class_declaration: ($) => seq( - optional($._locally_permitted_modifiers), + field("modifiers", optional($._locally_permitted_modifiers)), $._modifierless_class_declaration ), import_declaration: ($) => seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), "import", optional($._import_kind), - $.identifier + field("name", $.identifier) ), _import_kind: ($) => choice( @@ -1382,17 +1382,17 @@ module.exports = grammar({ protocol_property_declaration: ($) => prec.right( seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), field("name", alias($._binding_kind_and_pattern, $.pattern)), - optional($.type_annotation), - optional($.type_constraints), - $.protocol_property_requirements + field("type", optional($.type_annotation)), + field("type_constraints", optional($.type_constraints)), + field("requirements", $.protocol_property_requirements) ) ), protocol_property_requirements: ($) => - seq("{", repeat(choice($.getter_specifier, $.setter_specifier)), "}"), + seq("{", repeat(field("accessor", choice($.getter_specifier, $.setter_specifier))), "}"), property_declaration: ($) => - seq(optional($.modifiers), $._modifierless_property_declaration), + seq(field("modifiers", optional($.modifiers)), $._modifierless_property_declaration), _modifierless_property_declaration: ($) => prec.right( seq( @@ -1429,30 +1429,30 @@ module.exports = grammar({ seq($._equal_sign, field("value", $.expression)), willset_didset_block: ($) => choice( - seq("{", $.willset_clause, optional($.didset_clause), "}"), - seq("{", $.didset_clause, optional($.willset_clause), "}") + seq("{", field("willset", $.willset_clause), field("didset", optional($.didset_clause)), "}"), + seq("{", field("didset", $.didset_clause), field("willset", optional($.willset_clause)), "}") ), willset_clause: ($) => seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), "willSet", - optional(seq("(", $.simple_identifier, ")")), + optional(seq("(", field("parameter", $.simple_identifier), ")")), $._block ), didset_clause: ($) => seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), "didSet", - optional(seq("(", $.simple_identifier, ")")), + optional(seq("(", field("parameter", $.simple_identifier), ")")), $._block ), typealias_declaration: ($) => - seq(optional($.modifiers), $._modifierless_typealias_declaration), + seq(field("modifiers", optional($.modifiers)), $._modifierless_typealias_declaration), _modifierless_typealias_declaration: ($) => seq( "typealias", field("name", alias($.simple_identifier, $.type_identifier)), - optional($.type_parameters), + field("type_parameters", optional($.type_parameters)), $._equal_sign, field("value", $.type) ), @@ -1469,7 +1469,7 @@ module.exports = grammar({ ), _bodyless_function_declaration: ($) => seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), optional("class"), // XXX: This should be possible in non-last position, but that creates parsing ambiguity $._modifierless_function_declaration_no_body ), @@ -1477,17 +1477,17 @@ module.exports = grammar({ prec.right( seq( $._non_constructor_function_decl, - optional($.type_parameters), + field("type_parameters", optional($.type_parameters)), $._function_value_parameters, - optional($._async_keyword), - optional(choice($.throws_clause, $.throws)), + field("async", optional($._async_keyword)), + field("throws", optional(choice($.throws_clause, $.throws))), optional( seq( $._arrow_operator, field("return_type", $._possibly_implicitly_unwrapped_type) ) ), - optional($.type_constraints) + field("type_constraints", optional($.type_constraints)) ) ), function_body: ($) => $._block, @@ -1513,36 +1513,36 @@ module.exports = grammar({ ), external_macro_definition: ($) => - seq($._hash_symbol, "externalMacro", $.value_arguments), + seq($._hash_symbol, "externalMacro", field("arguments", $.value_arguments)), class_declaration: ($) => - seq(optional($.modifiers), $._modifierless_class_declaration), + seq(field("modifiers", optional($.modifiers)), $._modifierless_class_declaration), _modifierless_class_declaration: ($) => prec.right( choice( seq( field("declaration_kind", choice("class", "struct", "actor")), field("name", alias($.simple_identifier, $.type_identifier)), - optional($.type_parameters), + field("type_parameters", optional($.type_parameters)), optional(seq(":", $._inheritance_specifiers)), - optional($.type_constraints), + field("type_constraints", optional($.type_constraints)), field("body", $.class_body) ), seq( field("declaration_kind", "extension"), field("name", $.unannotated_type), - optional($.type_parameters), + field("type_parameters", optional($.type_parameters)), optional(seq(":", $._inheritance_specifiers)), - optional($.type_constraints), + field("type_constraints", optional($.type_constraints)), field("body", $.class_body) ), seq( optional("indirect"), field("declaration_kind", "enum"), field("name", alias($.simple_identifier, $.type_identifier)), - optional($.type_parameters), + field("type_parameters", optional($.type_parameters)), optional(seq(":", $._inheritance_specifiers)), - optional($.type_constraints), + field("type_constraints", optional($.type_constraints)), field("body", $.enum_class_body) ) ) @@ -1550,6 +1550,8 @@ module.exports = grammar({ class_body: ($) => seq("{", optional($._class_member_declarations), "}"), _inheritance_specifiers: ($) => prec.left(sep1($._annotated_inheritance_specifier, choice(",", "&"))), + _annotated_inheritance_specifier: ($) => + seq(repeat(field("attribute", $.attribute)), $.inheritance_specifier), inheritance_specifier: ($) => prec.left( field( @@ -1557,20 +1559,18 @@ module.exports = grammar({ choice($.user_type, $.function_type, $.suppressed_constraint) ) ), - _annotated_inheritance_specifier: ($) => - seq(repeat($.attribute), $.inheritance_specifier), type_parameters: ($) => seq( "<", - sep1Opt($.type_parameter, ","), - optional($.type_constraints), + sep1Opt(field("parameter", $.type_parameter), ","), + field("constraints", optional($.type_constraints)), ">" ), type_parameter: ($) => seq( - optional($.type_parameter_modifiers), - $._type_parameter_possibly_packed, - optional(seq(":", $.type)) + field("modifiers", optional($.type_parameter_modifiers)), + field("name", $._type_parameter_possibly_packed), + optional(seq(":", field("type", $.type))) ), _type_parameter_possibly_packed: ($) => choice( @@ -1579,19 +1579,19 @@ module.exports = grammar({ ), type_constraints: ($) => - prec.right(seq($.where_keyword, sep1Opt($.type_constraint, ","))), + prec.right(seq(field("keyword", $.where_keyword), sep1Opt(field("constraint", $.type_constraint), ","))), type_constraint: ($) => - choice($.inheritance_constraint, $.equality_constraint), + field("constraint", choice($.inheritance_constraint, $.equality_constraint)), inheritance_constraint: ($) => seq( - repeat($.attribute), + repeat(field("attribute", $.attribute)), field("constrained_type", $._constrained_type), ":", field("inherits_from", $._possibly_implicitly_unwrapped_type) ), equality_constraint: ($) => seq( - repeat($.attribute), + repeat(field("attribute", $.attribute)), field("constrained_type", $._constrained_type), choice($._equal_sign, $._eq_eq), field("must_equal", $.type) @@ -1599,8 +1599,8 @@ module.exports = grammar({ _constrained_type: ($) => choice($.identifier, $.nested_type_identifier), nested_type_identifier: ($) => seq( - $.unannotated_type, - optional(seq(".", sep1($.simple_identifier, "."))) + field("base", $.unannotated_type), + optional(seq(".", sep1(field("member", $.simple_identifier), "."))) ), _class_member_separator: ($) => choice($._semi, $.multiline_comment), _class_member_declarations: ($) => @@ -1614,8 +1614,8 @@ module.exports = grammar({ ), _function_value_parameter: ($) => seq( - optional($.attribute), - $.parameter, + field("attribute", optional($.attribute)), + field("parameter", $.parameter), optional(seq($._equal_sign, field("default_value", $.expression))) ), parameter: ($) => @@ -1623,7 +1623,7 @@ module.exports = grammar({ optional(field("external_name", $.simple_identifier)), field("name", $.simple_identifier), ":", - optional($.parameter_modifiers), + field("modifiers", optional($.parameter_modifiers)), field("type", $._possibly_implicitly_unwrapped_type), optional($._three_dot_operator) ), @@ -1633,7 +1633,7 @@ module.exports = grammar({ field("name", choice($.simple_identifier, $.referenceable_operator)) ), referenceable_operator: ($) => - choice( + field("operator", choice( $.custom_operator, $._comparison_operator, $._additive_operator, @@ -1649,7 +1649,7 @@ module.exports = grammar({ "<<", ">>", "&" - ), + )), // Hide the fact that certain symbols come from the custom scanner by aliasing them to their // string variants. This keeps us from having to see them in the syntax tree (which would be // noisy) but allows callers to refer to them as nodes by their text form like with any @@ -1676,7 +1676,7 @@ module.exports = grammar({ seq("{", repeat(field("member", choice($.enum_entry, $.type_level_declaration))), "}"), enum_entry: ($) => seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), optional("indirect"), "case", sep1( @@ -1713,12 +1713,12 @@ module.exports = grammar({ protocol_declaration: ($) => prec.right( seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), field("declaration_kind", "protocol"), field("name", alias($.simple_identifier, $.type_identifier)), - optional($.type_parameters), + field("type_parameters", optional($.type_parameters)), optional(seq(":", $._inheritance_specifiers)), - optional($.type_constraints), + field("type_constraints", optional($.type_constraints)), field("body", $.protocol_body) ) ), @@ -1744,28 +1744,28 @@ module.exports = grammar({ init_declaration: ($) => prec.right( seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), optional("class"), field("name", "init"), - optional(choice($._quest, $.bang)), - optional($.type_parameters), + optional(choice($._quest, field("bang", $.bang))), + field("type_parameters", optional($.type_parameters)), $._function_value_parameters, - optional($._async_keyword), - optional(choice($.throws_clause, $.throws)), - optional($.type_constraints), + field("async", optional($._async_keyword)), + field("throws", optional(choice($.throws_clause, $.throws))), + field("type_constraints", optional($.type_constraints)), optional(field("body", $.function_body)) ) ), deinit_declaration: ($) => prec.right( - seq(optional($.modifiers), "deinit", field("body", $.function_body)) + seq(field("modifiers", optional($.modifiers)), "deinit", field("body", $.function_body)) ), subscript_declaration: ($) => prec.right( seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), "subscript", - optional($.type_parameters), + field("type_parameters", optional($.type_parameters)), $._function_value_parameters, optional( seq( @@ -1773,45 +1773,45 @@ module.exports = grammar({ field("return_type", $._possibly_implicitly_unwrapped_type) ) ), - optional($.type_constraints), - $.computed_property + field("type_constraints", optional($.type_constraints)), + field("body", $.computed_property) ) ), computed_property: ($) => seq( "{", choice( - optional($.statements), + field("body", optional($.statements)), repeat( - choice($.computed_getter, $.computed_setter, $.computed_modify) + field("accessor", choice($.computed_getter, $.computed_setter, $.computed_modify)) ) ), "}" ), computed_getter: ($) => - seq(repeat($.attribute), $.getter_specifier, optional($._block)), + seq(repeat(field("attribute", $.attribute)), field("specifier", $.getter_specifier), optional($._block)), computed_modify: ($) => - seq(repeat($.attribute), $.modify_specifier, optional($._block)), + seq(repeat(field("attribute", $.attribute)), field("specifier", $.modify_specifier), optional($._block)), computed_setter: ($) => seq( - repeat($.attribute), - $.setter_specifier, - optional(seq("(", $.simple_identifier, ")")), + repeat(field("attribute", $.attribute)), + field("specifier", $.setter_specifier), + optional(seq("(", field("parameter", $.simple_identifier), ")")), optional($._block) ), getter_specifier: ($) => - seq(optional($.mutation_modifier), "get", optional($._getter_effects)), - setter_specifier: ($) => seq(optional($.mutation_modifier), "set"), - modify_specifier: ($) => seq(optional($.mutation_modifier), "_modify"), + seq(field("mutation", optional($.mutation_modifier)), "get", optional($._getter_effects)), + setter_specifier: ($) => seq(field("mutation", optional($.mutation_modifier)), "set"), + modify_specifier: ($) => seq(field("mutation", optional($.mutation_modifier)), "_modify"), _getter_effects: ($) => repeat1(field("effect", choice(alias($._async_keyword, $.async_keyword), $.throws_clause, $.throws))), operator_declaration: ($) => seq( - choice("prefix", "infix", "postfix"), + field("kind", choice("prefix", "infix", "postfix")), "operator", - $.referenceable_operator, - optional(seq(":", $.simple_identifier)), - optional($.deprecated_operator_declaration_body) + field("name", $.referenceable_operator), + optional(seq(":", field("precedence_group", $.simple_identifier))), + field("body", optional($.deprecated_operator_declaration_body)) ), // The Swift compiler no longer accepts these, but some very old code still uses it. deprecated_operator_declaration_body: ($) => @@ -1819,25 +1819,25 @@ module.exports = grammar({ precedence_group_declaration: ($) => seq( "precedencegroup", - $.simple_identifier, + field("name", $.simple_identifier), "{", - optional($.precedence_group_attributes), + field("attributes", optional($.precedence_group_attributes)), "}" ), - precedence_group_attributes: ($) => repeat1($.precedence_group_attribute), + precedence_group_attributes: ($) => repeat1(field("attribute", $.precedence_group_attribute)), precedence_group_attribute: ($) => seq( - $.simple_identifier, + field("name", $.simple_identifier), ":", - choice($.simple_identifier, $.boolean_literal) + field("value", choice($.simple_identifier, $.boolean_literal)) ), associatedtype_declaration: ($) => seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), "associatedtype", field("name", alias($.simple_identifier, $.type_identifier)), optional(seq(":", field("must_inherit", $.type))), - optional($.type_constraints), + field("type_constraints", optional($.type_constraints)), optional(seq($._equal_sign, field("default_value", $.type))) ), //////////////////////////////// @@ -1846,20 +1846,20 @@ module.exports = grammar({ attribute: ($) => seq( "@", - $.user_type, + field("name", $.user_type), // attribute arguments are a mess of special cases, maybe this is good enough? optional(seq("(", sep1Opt($._attribute_argument, ","), ")")) ), _attribute_argument: ($) => choice( // labeled function parameters, used in custom property wrappers - seq($.simple_identifier, ":", $.expression), + seq(field("argument_name", $.simple_identifier), ":", field("argument", $.expression)), // Unlabeled function parameters, simple identifiers, or `*` - $.expression, + field("argument", $.expression), // References to param names (used in `@objc(foo:bar:)`) - repeat1(seq($.simple_identifier, ":")), + repeat1(seq(field("param_ref", $.simple_identifier), ":")), // Version restrictions (iOS 3.4.5, Swift 5.0.0) - seq(repeat1($.simple_identifier), sep1($.integer_literal, ".")) + seq(repeat1(field("platform", $.simple_identifier)), sep1(field("version", $.integer_literal), ".")) ), //////////////////////////////// // Patterns - https://docs.swift.org/swift-book/ReferenceManual/Patterns.html @@ -1952,12 +1952,12 @@ module.exports = grammar({ modifiers: ($) => repeat1( prec.left( - choice($._non_local_scope_modifier, $._locally_permitted_modifiers) + field("modifier", choice($._non_local_scope_modifier, $._locally_permitted_modifiers)) ) ), _locally_permitted_modifiers: ($) => repeat1(choice($.attribute, $._locally_permitted_modifier)), - parameter_modifiers: ($) => repeat1($.parameter_modifier), + parameter_modifiers: ($) => repeat1(field("modifier", $.parameter_modifier)), _modifier: ($) => choice($._non_local_scope_modifier, $._locally_permitted_modifier), _non_local_scope_modifier: ($) => @@ -1976,7 +1976,7 @@ module.exports = grammar({ $.property_behavior_modifier ), property_behavior_modifier: ($) => "lazy", - type_modifiers: ($) => repeat1($.attribute), + type_modifiers: ($) => repeat1(field("attribute", $.attribute)), member_modifier: ($) => choice("override", "convenience", "required", "nonisolated"), visibility_modifier: ($) => @@ -1991,7 +1991,7 @@ module.exports = grammar({ ), optional(seq("(", "set", ")")) ), - type_parameter_modifiers: ($) => repeat1($.attribute), + type_parameter_modifiers: ($) => repeat1(field("attribute", $.attribute)), function_modifier: ($) => choice("infix", "postfix", "prefix"), mutation_modifier: ($) => choice("mutating", "nonmutating"), property_modifier: ($) => diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 219904ae939..4d4faf641d1 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -119,8 +119,8 @@ named: array_type: element: type as_expression: - $children: as_operator expr: expression + operator: as_operator type: type as_operator: assignment: @@ -128,13 +128,19 @@ named: result: expression target: directly_assignable_expression associatedtype_declaration: - $children*: [modifiers, type_constraints] default_value?: type + modifiers?: modifiers must_inherit?: type name: type_identifier + type_constraints?: type_constraints async_keyword: attribute: - $children+: [expression, user_type] + argument*: expression + argument_name*: simple_identifier + name: user_type + param_ref*: simple_identifier + platform*: simple_identifier + version*: integer_literal availability_condition: $children*: [identifier, integer_literal] await_expression: @@ -148,19 +154,23 @@ named: rhs: expression boolean_literal: call_expression: - $children+: [call_suffix, expression] + $children*: [call_suffix, expression] + function?: expression + suffix?: call_suffix call_suffix: $children+: [lambda_literal, value_arguments] name*: simple_identifier capture_list: - $children+: capture_list_item + item+: capture_list_item capture_list_item: - $children?: ownership_modifier name: [self_expression, simple_identifier] + ownership?: ownership_modifier value?: expression catch_block: - $children+: [catch_keyword, statements, where_clause] + body?: statements error?: pattern + keyword: catch_keyword + where?: where_clause catch_keyword: check_expression: op: "is" @@ -170,41 +180,54 @@ named: $children*: multiline_comment member*: type_level_declaration class_declaration: - $children*: [attribute, inheritance_modifier, inheritance_specifier, modifiers, ownership_modifier, property_behavior_modifier, type_constraints, type_parameters] + $children*: inheritance_specifier + attribute*: attribute body: [class_body, enum_class_body] declaration_kind: ["actor", "class", "enum", "extension", "struct"] + modifiers*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier] name: [type_identifier, unannotated_type] + type_constraints?: type_constraints + type_parameters?: type_parameters comment: comparison_expression: lhs: expression op: ["<", "<=", ">", ">="] rhs: expression computed_getter: - $children+: [attribute, getter_specifier, statements] + attribute*: attribute + body?: statements + specifier: getter_specifier computed_modify: - $children+: [attribute, modify_specifier, statements] + attribute*: attribute + body?: statements + specifier: modify_specifier computed_property: - $children*: [computed_getter, computed_modify, computed_setter, statements] + accessor*: [computed_getter, computed_modify, computed_setter] + body?: statements computed_setter: - $children+: [attribute, setter_specifier, simple_identifier, statements] + attribute*: attribute + body?: statements + parameter?: simple_identifier + specifier: setter_specifier conjunction_expression: lhs: expression op: "&&" rhs: expression constructor_expression: - $children: constructor_suffix constructed_type: [array_type, dictionary_type, user_type] + suffix: constructor_suffix constructor_suffix: $children+: [lambda_literal, value_arguments] name*: simple_identifier control_transfer_statement: $children*: [expression, throw_keyword] + kind?: ["break", "continue", "return", "yield"] result?: expression custom_operator: default_keyword: deinit_declaration: - $children?: modifiers body: function_body + modifiers?: modifiers deprecated_operator_declaration_body: $children*: [bin_literal, boolean_literal, hex_literal, integer_literal, line_string_literal, multi_line_string_literal, oct_literal, raw_string_literal, real_literal, regex_literal, simple_identifier] diagnostic: @@ -215,29 +238,32 @@ named: key: type value: type didset_clause: - $children*: [modifiers, simple_identifier, statements] + body?: statements + modifiers?: modifiers + parameter?: simple_identifier directive: $children*: [boolean_literal, integer_literal, simple_identifier] directly_assignable_expression: - $children: expression + expr: expression disjunction_expression: lhs: expression op: "||" rhs: expression do_statement: - $children*: [catch_block, statements] + body?: statements + catch*: catch_block else: enum_class_body: member*: [enum_entry, type_level_declaration] enum_entry: - $children?: modifiers data_contents*: enum_type_parameters + modifiers?: modifiers name+: simple_identifier raw_value*: expression enum_type_parameters: $children*: [expression, type, wildcard_pattern] equality_constraint: - $children*: attribute + attribute*: attribute constrained_type: [identifier, nested_type_identifier] must_equal: type equality_expression: @@ -245,107 +271,137 @@ named: op: ["!=", "!==", "==", "==="] rhs: expression existential_type: - $children: unannotated_type + name: unannotated_type external_macro_definition: - $children: value_arguments + arguments: value_arguments for_statement: - $children*: [statements, try_operator, type_annotation, where_clause] + body?: statements collection: expression item: pattern + try?: try_operator + type?: type_annotation + where?: where_clause fully_open_range: function_body: - $children?: statements + body?: statements function_declaration: - $children*: [attribute, inheritance_modifier, modifiers, ownership_modifier, parameter, property_behavior_modifier, throws, throws_clause, type_constraints, type_parameters] + async?: "async" + attribute*: attribute body: function_body default_value*: expression + modifiers*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier] name: [referenceable_operator, simple_identifier] + parameter*: parameter return_type?: [implicitly_unwrapped_type, type] + throws?: [throws, throws_clause] + type_constraints?: type_constraints + type_parameters?: type_parameters function_modifier: function_type: - $children?: [throws, throws_clause] + async?: "async" params: unannotated_type return_type: type + throws?: [throws, throws_clause] getter_specifier: - $children?: mutation_modifier effect*: [async_keyword, throws, throws_clause] + mutation?: mutation_modifier guard_statement: - $children+: [else, statements] + body?: statements condition+: if_condition + else_keyword: else hex_literal: identifier: - $children+: simple_identifier + part+: simple_identifier if_condition: - $children: [availability_condition, expression, if_let_binding] + kind: [availability_condition, expression, if_let_binding] if_let_binding: - $children*: [expression, pattern, type, type_annotation, user_type, value_binding_pattern, where_clause, wildcard_pattern] + $children*: [pattern, simple_identifier, type, type_annotation, user_type, value_binding_pattern, wildcard_pattern] bound_identifier?: simple_identifier + value?: expression + where?: where_clause if_statement: - $children*: [else, if_statement, statements] + body*: statements condition+: if_condition + else_branch?: if_statement + else_keyword?: else implicitly_unwrapped_type: - $children: type + name: type import_declaration: - $children+: [identifier, modifiers] + modifiers?: modifiers + name: identifier infix_expression: lhs: expression op: custom_operator rhs: expression inheritance_constraint: - $children*: attribute + attribute*: attribute constrained_type: [identifier, nested_type_identifier] inherits_from: [implicitly_unwrapped_type, type] inheritance_modifier: inheritance_specifier: inherits_from: [function_type, suppressed_constraint, user_type] init_declaration: - $children*: [attribute, bang, modifiers, parameter, throws, throws_clause, type_constraints, type_parameters] + async?: "async" + attribute*: attribute + bang?: bang body?: function_body default_value*: expression + modifiers?: modifiers name: "init" + parameter*: parameter + throws?: [throws, throws_clause] + type_constraints?: type_constraints + type_parameters?: type_parameters integer_literal: interpolated_expression: - $children?: type_modifiers name?: value_argument_label reference_specifier*: value_argument_label + type_modifiers?: type_modifiers value?: expression key_path_expression: $children*: [array_type, bang, dictionary_type, simple_identifier, type_arguments, type_identifier, value_argument] key_path_string_expression: - $children: expression + expr: expression lambda_function_type: - $children*: [lambda_function_type_parameters, throws, throws_clause] + async?: "async" + params?: lambda_function_type_parameters return_type?: [implicitly_unwrapped_type, type] + throws?: [throws, throws_clause] lambda_function_type_parameters: - $children+: lambda_parameter + parameter+: lambda_parameter lambda_literal: - $children*: [attribute, statements] + attribute*: attribute + body?: statements captures?: capture_list type?: lambda_function_type lambda_parameter: - $children?: [parameter_modifiers, self_expression] external_name?: simple_identifier - name?: simple_identifier + modifiers?: parameter_modifiers + name: [self_expression, simple_identifier] type?: [implicitly_unwrapped_type, type] line_str_text: line_string_literal: interpolation*: interpolated_expression text*: [line_str_text, str_escaped_char] macro_declaration: - $children+: [attribute, modifiers, parameter, simple_identifier, type_constraints, type_parameters, unannotated_type] + $children+: [modifiers, simple_identifier, type_constraints, type_parameters, unannotated_type] + attribute*: attribute default_value*: expression definition?: macro_definition + parameter*: parameter macro_definition: body: [expression, external_macro_definition] macro_invocation: - $children+: [call_suffix, simple_identifier, type_parameters] + name: simple_identifier + suffix: call_suffix + type_parameters?: type_parameters member_modifier: metatype: - $children: unannotated_type + name: unannotated_type modifiers: - $children+: [attribute, function_modifier, inheritance_modifier, member_modifier, mutation_modifier, ownership_modifier, parameter_modifier, property_behavior_modifier, property_modifier, visibility_modifier] + modifier+: [attribute, function_modifier, inheritance_modifier, member_modifier, mutation_modifier, ownership_modifier, parameter_modifier, property_behavior_modifier, property_modifier, visibility_modifier] modify_specifier: - $children?: mutation_modifier + mutation?: mutation_modifier multi_line_str_text: multi_line_string_literal: interpolation*: interpolated_expression @@ -362,76 +418,97 @@ named: navigation_suffix: suffix: [integer_literal, simple_identifier] nested_type_identifier: - $children+: [simple_identifier, unannotated_type] + base: unannotated_type + member*: simple_identifier nil_coalescing_expression: if_nil: expression value: expression oct_literal: opaque_type: - $children: unannotated_type + name: unannotated_type open_end_range_expression: start: expression open_start_range_expression: end: expression operator_declaration: - $children+: [deprecated_operator_declaration_body, referenceable_operator, simple_identifier] + body?: deprecated_operator_declaration_body + kind: ["infix", "postfix", "prefix"] + name: referenceable_operator + precedence_group?: simple_identifier optional_chain_marker: - $children: expression + expr: expression optional_type: wrapped: [array_type, dictionary_type, tuple_type, user_type] ownership_modifier: parameter: - $children?: parameter_modifiers external_name?: simple_identifier + modifiers?: parameter_modifiers name: simple_identifier type: [implicitly_unwrapped_type, type] parameter_modifier: parameter_modifiers: - $children+: parameter_modifier + modifier+: parameter_modifier pattern: $children*: [expression, pattern, type, user_type, value_binding_pattern, wildcard_pattern] bound_identifier?: simple_identifier playground_literal: - $children+: expression + name+: simple_identifier + value+: expression postfix_expression: operation: ["++", "--", bang] target: expression precedence_group_attribute: - $children+: [boolean_literal, simple_identifier] + name: simple_identifier + value: [boolean_literal, simple_identifier] precedence_group_attributes: - $children+: precedence_group_attribute + attribute+: precedence_group_attribute precedence_group_declaration: - $children+: [precedence_group_attributes, simple_identifier] + attributes?: precedence_group_attributes + name: simple_identifier prefix_expression: operation: ["&", "+", "++", "-", "--", ".", bang, custom_operator, "~"] target: expression property_behavior_modifier: property_declaration: - $children*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier, type_annotation, type_constraints, value_binding_pattern, willset_didset_block] + $children*: [type_annotation, type_constraints, value_binding_pattern, willset_didset_block] computed_value*: computed_property + modifiers*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier] name+: pattern value*: expression property_modifier: protocol_body: member*: protocol_member_declaration protocol_composition_type: - $children+: unannotated_type + type+: unannotated_type protocol_declaration: - $children*: [attribute, inheritance_specifier, modifiers, type_constraints, type_parameters] + $children*: inheritance_specifier + attribute*: attribute body: protocol_body declaration_kind: "protocol" + modifiers?: modifiers name: type_identifier + type_constraints?: type_constraints + type_parameters?: type_parameters protocol_function_declaration: - $children*: [attribute, modifiers, parameter, throws, throws_clause, type_constraints, type_parameters] + async?: "async" + attribute*: attribute body?: function_body default_value*: expression + modifiers?: modifiers name: [referenceable_operator, simple_identifier] + parameter*: parameter return_type?: [implicitly_unwrapped_type, type] + throws?: [throws, throws_clause] + type_constraints?: type_constraints + type_parameters?: type_parameters protocol_property_declaration: - $children+: [modifiers, protocol_property_requirements, type_annotation, type_constraints] + modifiers?: modifiers name: pattern + requirements: protocol_property_requirements + type?: type_annotation + type_constraints?: type_constraints protocol_property_requirements: - $children*: [getter_specifier, setter_specifier] + accessor*: [getter_specifier, setter_specifier] range_expression: end: expression op: ["...", "..<"] @@ -439,26 +516,26 @@ named: raw_str_continuing_indicator: raw_str_end_part: raw_str_interpolation: - $children: raw_str_interpolation_start interpolation+: interpolated_expression + start: raw_str_interpolation_start raw_str_interpolation_start: raw_str_part: raw_string_literal: - $children*: raw_str_continuing_indicator + continuing*: raw_str_continuing_indicator interpolation*: raw_str_interpolation text+: [raw_str_end_part, raw_str_part] real_literal: referenceable_operator: - $children?: [bang, custom_operator] + operator: ["!=", "!==", "%", "%=", "&", "*", "*=", "+", "++", "+=", "-", "--", "-=", "/", "/=", "<", "<<", "<=", "=", "==", "===", ">", ">=", ">>", "^", bang, custom_operator, "|", "~"] regex_literal: repeat_while_statement: - $children?: statements + body?: statements condition+: if_condition selector_expression: - $children: expression + expr: expression self_expression: setter_specifier: - $children?: mutation_modifier + mutation?: mutation_modifier shebang_line: simple_identifier: source_file: @@ -470,9 +547,14 @@ named: statement+: [control_transfer_statement, do_statement, expression, for_statement, guard_statement, local_declaration, repeat_while_statement, statement_label, while_statement] str_escaped_char: subscript_declaration: - $children+: [attribute, computed_property, modifiers, parameter, type_constraints, type_parameters] + attribute*: attribute + body: computed_property default_value*: expression + modifiers?: modifiers + parameter*: parameter return_type?: [implicitly_unwrapped_type, type] + type_constraints?: type_constraints + type_parameters?: type_parameters super_expression: suppressed_constraint: suppressed: type_identifier @@ -481,7 +563,7 @@ named: switch_pattern: $children: pattern switch_statement: - $children*: switch_entry + entry*: switch_entry expr: expression ternary_expression: condition: expression @@ -492,8 +574,8 @@ named: throws_clause: type: unannotated_type try_expression: - $children: try_operator expr: expression + operator: try_operator try_operator: tuple_expression: name*: simple_identifier @@ -502,7 +584,8 @@ named: $children?: tuple_type_item element*: tuple_type_item tuple_type_item: - $children*: [dictionary_type, existential_type, opaque_type, parameter_modifiers, wildcard_pattern] + $children?: [dictionary_type, existential_type, opaque_type, wildcard_pattern] + modifiers?: parameter_modifiers name?: simple_identifier type?: type type: @@ -511,57 +594,66 @@ named: type_annotation: type: [implicitly_unwrapped_type, type] type_arguments: - $children+: type + argument+: type type_constraint: - $children: [equality_constraint, inheritance_constraint] + constraint: [equality_constraint, inheritance_constraint] type_constraints: - $children+: [type_constraint, where_keyword] + constraint+: type_constraint + keyword: where_keyword type_identifier: type_modifiers: - $children+: attribute + attribute+: attribute type_pack_expansion: - $children: unannotated_type + name: unannotated_type type_parameter: - $children+: [type, type_identifier, type_parameter_modifiers, type_parameter_pack] + modifiers?: type_parameter_modifiers + name: [type_identifier, type_parameter_pack] + type?: type type_parameter_modifiers: - $children+: attribute + attribute+: attribute type_parameter_pack: - $children: unannotated_type + name: unannotated_type type_parameters: - $children+: [type_constraints, type_parameter] + constraints?: type_constraints + parameter+: type_parameter typealias_declaration: - $children*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier, type_parameters] + modifiers*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier] name: type_identifier + type_parameters?: type_parameters value: type user_type: - $children+: [type_arguments, type_identifier] + part+: [type_arguments, type_identifier] value_argument: - $children?: type_modifiers name?: value_argument_label reference_specifier*: value_argument_label + type_modifiers?: type_modifiers value?: expression value_argument_label: $children: simple_identifier value_arguments: - $children*: value_argument + argument*: value_argument value_binding_pattern: mutability: ["let", "var"] value_pack_expansion: - $children: expression + expr: expression value_parameter_pack: - $children: expression + expr: expression visibility_modifier: where_clause: - $children+: [expression, where_keyword] + expr: expression + keyword: where_keyword where_keyword: while_statement: - $children?: statements + body?: statements condition+: if_condition wildcard_pattern: willset_clause: - $children*: [modifiers, simple_identifier, statements] + body?: statements + modifiers?: modifiers + parameter?: simple_identifier willset_didset_block: - $children+: [didset_clause, willset_clause] + didset?: didset_clause + willset?: willset_clause unnamed: - "?" From 853a98842da041bb251355111f9521a88972f9ba Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:00:14 +0000 Subject: [PATCH 027/226] unified: Regenerate files --- unified/ql/lib/codeql/unified/Ast.qll | 1029 +++++++++++++++++------ unified/ql/lib/unified.dbscheme | 1121 ++++++++++++++++--------- 2 files changed, 1481 insertions(+), 669 deletions(-) diff --git a/unified/ql/lib/codeql/unified/Ast.qll b/unified/ql/lib/codeql/unified/Ast.qll index dbe217fb951..bf3b98f582e 100644 --- a/unified/ql/lib/codeql/unified/Ast.qll +++ b/unified/ql/lib/codeql/unified/Ast.qll @@ -146,11 +146,11 @@ module Swift { /** Gets the node corresponding to the field `expr`. */ final Expression getExpr() { swift_as_expression_def(this, result, _, _) } - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_as_expression_def(this, _, result, _) } + /** Gets the node corresponding to the field `operator`. */ + final AsOperator getOperator() { swift_as_expression_def(this, _, result, _) } - /** Gets the child of this node. */ - final AsOperator getChild() { swift_as_expression_def(this, _, _, result) } + /** Gets the node corresponding to the field `type`. */ + final Type getType() { swift_as_expression_def(this, _, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { @@ -208,34 +208,68 @@ module Swift { /** Gets the node corresponding to the field `default_value`. */ final Type getDefaultValue() { swift_associatedtype_declaration_default_value(this, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_associatedtype_declaration_modifiers(this, result) } + /** Gets the node corresponding to the field `must_inherit`. */ final Type getMustInherit() { swift_associatedtype_declaration_must_inherit(this, result) } /** Gets the node corresponding to the field `name`. */ final TypeIdentifier getName() { swift_associatedtype_declaration_def(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_associatedtype_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_associatedtype_declaration_type_constraints(this, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_associatedtype_declaration_default_value(this, result) or + swift_associatedtype_declaration_modifiers(this, result) or swift_associatedtype_declaration_must_inherit(this, result) or swift_associatedtype_declaration_def(this, result) or - swift_associatedtype_declaration_child(this, _, result) + swift_associatedtype_declaration_type_constraints(this, result) } } + /** A class representing `async_keyword` tokens. */ + class AsyncKeyword extends @swift_token_async_keyword, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "AsyncKeyword" } + } + /** A class representing `attribute` nodes. */ class Attribute extends @swift_attribute, AstNode { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Attribute" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_attribute_child(this, i, result) } + /** Gets the node corresponding to the field `argument`. */ + final Expression getArgument(int i) { swift_attribute_argument(this, i, result) } + + /** Gets the node corresponding to the field `argument_name`. */ + final SimpleIdentifier getArgumentName(int i) { swift_attribute_argument_name(this, i, result) } + + /** Gets the node corresponding to the field `name`. */ + final UserType getName() { swift_attribute_def(this, result) } + + /** Gets the node corresponding to the field `param_ref`. */ + final SimpleIdentifier getParamRef(int i) { swift_attribute_param_ref(this, i, result) } + + /** Gets the node corresponding to the field `platform`. */ + final SimpleIdentifier getPlatform(int i) { swift_attribute_platform(this, i, result) } + + /** Gets the node corresponding to the field `version`. */ + final IntegerLiteral getVersion(int i) { swift_attribute_version(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_attribute_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_attribute_argument(this, _, result) or + swift_attribute_argument_name(this, _, result) or + swift_attribute_def(this, result) or + swift_attribute_param_ref(this, _, result) or + swift_attribute_platform(this, _, result) or + swift_attribute_version(this, _, result) + } } /** A class representing `availability_condition` nodes. */ @@ -325,11 +359,21 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "CallExpression" } + /** Gets the node corresponding to the field `function`. */ + final Expression getFunction() { swift_call_expression_function(this, result) } + + /** Gets the node corresponding to the field `suffix`. */ + final CallSuffix getSuffix() { swift_call_expression_suffix(this, result) } + /** Gets the `i`th child of this node. */ final AstNode getChild(int i) { swift_call_expression_child(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_call_expression_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_call_expression_function(this, result) or + swift_call_expression_suffix(this, result) or + swift_call_expression_child(this, _, result) + } } /** A class representing `call_suffix` nodes. */ @@ -354,11 +398,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "CaptureList" } - /** Gets the `i`th child of this node. */ - final CaptureListItem getChild(int i) { swift_capture_list_child(this, i, result) } + /** Gets the node corresponding to the field `item`. */ + final CaptureListItem getItem(int i) { swift_capture_list_item(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_capture_list_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_capture_list_item(this, _, result) } } /** A class representing `capture_list_item` nodes. */ @@ -369,17 +413,17 @@ module Swift { /** Gets the node corresponding to the field `name`. */ final AstNode getName() { swift_capture_list_item_def(this, result) } + /** Gets the node corresponding to the field `ownership`. */ + final OwnershipModifier getOwnership() { swift_capture_list_item_ownership(this, result) } + /** Gets the node corresponding to the field `value`. */ final Expression getValue() { swift_capture_list_item_value(this, result) } - /** Gets the child of this node. */ - final OwnershipModifier getChild() { swift_capture_list_item_child(this, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_capture_list_item_def(this, result) or - swift_capture_list_item_value(this, result) or - swift_capture_list_item_child(this, result) + swift_capture_list_item_ownership(this, result) or + swift_capture_list_item_value(this, result) } } @@ -388,15 +432,24 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "CatchBlock" } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_catch_block_body(this, result) } + /** Gets the node corresponding to the field `error`. */ final Pattern getError() { swift_catch_block_error(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_catch_block_child(this, i, result) } + /** Gets the node corresponding to the field `keyword`. */ + final CatchKeyword getKeyword() { swift_catch_block_def(this, result) } + + /** Gets the node corresponding to the field `where`. */ + final WhereClause getWhere() { swift_catch_block_where(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_catch_block_error(this, result) or swift_catch_block_child(this, _, result) + swift_catch_block_body(this, result) or + swift_catch_block_error(this, result) or + swift_catch_block_def(this, result) or + swift_catch_block_where(this, result) } } @@ -453,6 +506,9 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ClassDeclaration" } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_class_declaration_attribute(this, i, result) } + /** Gets the node corresponding to the field `body`. */ final AstNode getBody() { swift_class_declaration_def(this, result, _, _) } @@ -471,16 +527,33 @@ module Swift { ) } + /** Gets the node corresponding to the field `modifiers`. */ + final AstNode getModifiers(int i) { swift_class_declaration_modifiers(this, i, result) } + /** Gets the node corresponding to the field `name`. */ final AstNode getName() { swift_class_declaration_def(this, _, _, result) } + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_class_declaration_type_constraints(this, result) + } + + /** Gets the node corresponding to the field `type_parameters`. */ + final TypeParameters getTypeParameters() { + swift_class_declaration_type_parameters(this, result) + } + /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_class_declaration_child(this, i, result) } + final InheritanceSpecifier getChild(int i) { swift_class_declaration_child(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_class_declaration_attribute(this, _, result) or swift_class_declaration_def(this, result, _, _) or + swift_class_declaration_modifiers(this, _, result) or swift_class_declaration_def(this, _, _, result) or + swift_class_declaration_type_constraints(this, result) or + swift_class_declaration_type_parameters(this, result) or swift_class_declaration_child(this, _, result) } } @@ -527,11 +600,21 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ComputedGetter" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_getter_child(this, i, result) } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_computed_getter_attribute(this, i, result) } + + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_computed_getter_body(this, result) } + + /** Gets the node corresponding to the field `specifier`. */ + final GetterSpecifier getSpecifier() { swift_computed_getter_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_getter_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_computed_getter_attribute(this, _, result) or + swift_computed_getter_body(this, result) or + swift_computed_getter_def(this, result) + } } /** A class representing `computed_modify` nodes. */ @@ -539,11 +622,21 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ComputedModify" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_modify_child(this, i, result) } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_computed_modify_attribute(this, i, result) } + + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_computed_modify_body(this, result) } + + /** Gets the node corresponding to the field `specifier`. */ + final ModifySpecifier getSpecifier() { swift_computed_modify_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_modify_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_computed_modify_attribute(this, _, result) or + swift_computed_modify_body(this, result) or + swift_computed_modify_def(this, result) + } } /** A class representing `computed_property` nodes. */ @@ -551,11 +644,17 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ComputedProperty" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_property_child(this, i, result) } + /** Gets the node corresponding to the field `accessor`. */ + final AstNode getAccessor(int i) { swift_computed_property_accessor(this, i, result) } + + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_computed_property_body(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_property_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_computed_property_accessor(this, _, result) or + swift_computed_property_body(this, result) + } } /** A class representing `computed_setter` nodes. */ @@ -563,11 +662,25 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ComputedSetter" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_setter_child(this, i, result) } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_computed_setter_attribute(this, i, result) } + + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_computed_setter_body(this, result) } + + /** Gets the node corresponding to the field `parameter`. */ + final SimpleIdentifier getParameter() { swift_computed_setter_parameter(this, result) } + + /** Gets the node corresponding to the field `specifier`. */ + final SetterSpecifier getSpecifier() { swift_computed_setter_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_setter_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_computed_setter_attribute(this, _, result) or + swift_computed_setter_body(this, result) or + swift_computed_setter_parameter(this, result) or + swift_computed_setter_def(this, result) + } } /** A class representing `conjunction_expression` nodes. */ @@ -603,8 +716,8 @@ module Swift { /** Gets the node corresponding to the field `constructed_type`. */ final AstNode getConstructedType() { swift_constructor_expression_def(this, result, _) } - /** Gets the child of this node. */ - final ConstructorSuffix getChild() { swift_constructor_expression_def(this, _, result) } + /** Gets the node corresponding to the field `suffix`. */ + final ConstructorSuffix getSuffix() { swift_constructor_expression_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { @@ -636,6 +749,9 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ControlTransferStatement" } + /** Gets the node corresponding to the field `kind`. */ + final AstNode getKind() { swift_control_transfer_statement_kind(this, result) } + /** Gets the node corresponding to the field `result`. */ final Expression getResult() { swift_control_transfer_statement_result(this, result) } @@ -644,6 +760,7 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_control_transfer_statement_kind(this, result) or swift_control_transfer_statement_result(this, result) or swift_control_transfer_statement_child(this, _, result) } @@ -669,12 +786,12 @@ module Swift { /** Gets the node corresponding to the field `body`. */ final FunctionBody getBody() { swift_deinit_declaration_def(this, result) } - /** Gets the child of this node. */ - final Modifiers getChild() { swift_deinit_declaration_child(this, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_deinit_declaration_modifiers(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_deinit_declaration_def(this, result) or swift_deinit_declaration_child(this, result) + swift_deinit_declaration_def(this, result) or swift_deinit_declaration_modifiers(this, result) } } @@ -742,11 +859,21 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "DidsetClause" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_didset_clause_child(this, i, result) } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_didset_clause_body(this, result) } + + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_didset_clause_modifiers(this, result) } + + /** Gets the node corresponding to the field `parameter`. */ + final SimpleIdentifier getParameter() { swift_didset_clause_parameter(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_didset_clause_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_didset_clause_body(this, result) or + swift_didset_clause_modifiers(this, result) or + swift_didset_clause_parameter(this, result) + } } /** A class representing `directive` nodes. */ @@ -766,8 +893,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "DirectlyAssignableExpression" } - /** Gets the child of this node. */ - final Expression getChild() { swift_directly_assignable_expression_def(this, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expression getExpr() { swift_directly_assignable_expression_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { @@ -805,11 +932,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "DoStatement" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_do_statement_child(this, i, result) } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_do_statement_body(this, result) } + + /** Gets the node corresponding to the field `catch`. */ + final CatchBlock getCatch(int i) { swift_do_statement_catch(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_do_statement_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_do_statement_body(this, result) or swift_do_statement_catch(this, _, result) + } } /** A class representing `else` tokens. */ @@ -840,21 +972,21 @@ module Swift { swift_enum_entry_data_contents(this, i, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_enum_entry_modifiers(this, result) } + /** Gets the node corresponding to the field `name`. */ final SimpleIdentifier getName(int i) { swift_enum_entry_name(this, i, result) } /** Gets the node corresponding to the field `raw_value`. */ final Expression getRawValue(int i) { swift_enum_entry_raw_value(this, i, result) } - /** Gets the child of this node. */ - final Modifiers getChild() { swift_enum_entry_child(this, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_enum_entry_data_contents(this, _, result) or + swift_enum_entry_modifiers(this, result) or swift_enum_entry_name(this, _, result) or - swift_enum_entry_raw_value(this, _, result) or - swift_enum_entry_child(this, result) + swift_enum_entry_raw_value(this, _, result) } } @@ -875,20 +1007,20 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "EqualityConstraint" } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_equality_constraint_attribute(this, i, result) } + /** Gets the node corresponding to the field `constrained_type`. */ final AstNode getConstrainedType() { swift_equality_constraint_def(this, result, _) } /** Gets the node corresponding to the field `must_equal`. */ final Type getMustEqual() { swift_equality_constraint_def(this, _, result) } - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_equality_constraint_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_equality_constraint_attribute(this, _, result) or swift_equality_constraint_def(this, result, _) or - swift_equality_constraint_def(this, _, result) or - swift_equality_constraint_child(this, _, result) + swift_equality_constraint_def(this, _, result) } } @@ -928,8 +1060,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ExistentialType" } - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_existential_type_def(this, result) } + /** Gets the node corresponding to the field `name`. */ + final UnannotatedType getName() { swift_existential_type_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_existential_type_def(this, result) } @@ -942,8 +1074,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ExternalMacroDefinition" } - /** Gets the child of this node. */ - final ValueArguments getChild() { swift_external_macro_definition_def(this, result) } + /** Gets the node corresponding to the field `arguments`. */ + final ValueArguments getArguments() { swift_external_macro_definition_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_external_macro_definition_def(this, result) } @@ -954,20 +1086,32 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ForStatement" } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_for_statement_body(this, result) } + /** Gets the node corresponding to the field `collection`. */ final Expression getCollection() { swift_for_statement_def(this, result, _) } /** Gets the node corresponding to the field `item`. */ final Pattern getItem() { swift_for_statement_def(this, _, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_for_statement_child(this, i, result) } + /** Gets the node corresponding to the field `try`. */ + final TryOperator getTry() { swift_for_statement_try(this, result) } + + /** Gets the node corresponding to the field `type`. */ + final TypeAnnotation getType() { swift_for_statement_type(this, result) } + + /** Gets the node corresponding to the field `where`. */ + final WhereClause getWhere() { swift_for_statement_where(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_for_statement_body(this, result) or swift_for_statement_def(this, result, _) or swift_for_statement_def(this, _, result) or - swift_for_statement_child(this, _, result) + swift_for_statement_try(this, result) or + swift_for_statement_type(this, result) or + swift_for_statement_where(this, result) } } @@ -982,11 +1126,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "FunctionBody" } - /** Gets the child of this node. */ - final Statements getChild() { swift_function_body_child(this, result) } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_function_body_body(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_function_body_child(this, result) } + final override AstNode getAFieldOrChild() { swift_function_body_body(this, result) } } /** A class representing `function_declaration` nodes. */ @@ -994,6 +1138,12 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "FunctionDeclaration" } + /** Gets the node corresponding to the field `async`. */ + final AsyncKeyword getAsync() { swift_function_declaration_async(this, result) } + + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_function_declaration_attribute(this, i, result) } + /** Gets the node corresponding to the field `body`. */ final FunctionBody getBody() { swift_function_declaration_def(this, result, _) } @@ -1002,22 +1152,44 @@ module Swift { swift_function_declaration_default_value(this, i, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final AstNode getModifiers(int i) { swift_function_declaration_modifiers(this, i, result) } + /** Gets the node corresponding to the field `name`. */ final AstNode getName() { swift_function_declaration_def(this, _, result) } + /** Gets the node corresponding to the field `parameter`. */ + final Parameter getParameter(int i) { swift_function_declaration_parameter(this, i, result) } + /** Gets the node corresponding to the field `return_type`. */ final AstNode getReturnType() { swift_function_declaration_return_type(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_function_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `throws`. */ + final AstNode getThrows() { swift_function_declaration_throws(this, result) } + + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_function_declaration_type_constraints(this, result) + } + + /** Gets the node corresponding to the field `type_parameters`. */ + final TypeParameters getTypeParameters() { + swift_function_declaration_type_parameters(this, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_function_declaration_async(this, result) or + swift_function_declaration_attribute(this, _, result) or swift_function_declaration_def(this, result, _) or swift_function_declaration_default_value(this, _, result) or + swift_function_declaration_modifiers(this, _, result) or swift_function_declaration_def(this, _, result) or + swift_function_declaration_parameter(this, _, result) or swift_function_declaration_return_type(this, result) or - swift_function_declaration_child(this, _, result) + swift_function_declaration_throws(this, result) or + swift_function_declaration_type_constraints(this, result) or + swift_function_declaration_type_parameters(this, result) } } @@ -1032,20 +1204,24 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "FunctionType" } + /** Gets the node corresponding to the field `async`. */ + final AsyncKeyword getAsync() { swift_function_type_async(this, result) } + /** Gets the node corresponding to the field `params`. */ final UnannotatedType getParams() { swift_function_type_def(this, result, _) } /** Gets the node corresponding to the field `return_type`. */ final Type getReturnType() { swift_function_type_def(this, _, result) } - /** Gets the child of this node. */ - final AstNode getChild() { swift_function_type_child(this, result) } + /** Gets the node corresponding to the field `throws`. */ + final AstNode getThrows() { swift_function_type_throws(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_function_type_async(this, result) or swift_function_type_def(this, result, _) or swift_function_type_def(this, _, result) or - swift_function_type_child(this, result) + swift_function_type_throws(this, result) } } @@ -1054,11 +1230,17 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "GetterSpecifier" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_getter_specifier_child(this, i, result) } + /** Gets the node corresponding to the field `effect`. */ + final AstNode getEffect(int i) { swift_getter_specifier_effect(this, i, result) } + + /** Gets the node corresponding to the field `mutation`. */ + final MutationModifier getMutation() { swift_getter_specifier_mutation(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_getter_specifier_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_getter_specifier_effect(this, _, result) or + swift_getter_specifier_mutation(this, result) + } } class GlobalDeclaration extends @swift_global_declaration, AstNode { } @@ -1068,16 +1250,20 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "GuardStatement" } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_guard_statement_body(this, result) } + /** Gets the node corresponding to the field `condition`. */ final IfCondition getCondition(int i) { swift_guard_statement_condition(this, i, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_guard_statement_child(this, i, result) } + /** Gets the node corresponding to the field `else_keyword`. */ + final Else getElseKeyword() { swift_guard_statement_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_guard_statement_body(this, result) or swift_guard_statement_condition(this, _, result) or - swift_guard_statement_child(this, _, result) + swift_guard_statement_def(this, result) } } @@ -1092,11 +1278,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Identifier" } - /** Gets the `i`th child of this node. */ - final SimpleIdentifier getChild(int i) { swift_identifier_child(this, i, result) } + /** Gets the node corresponding to the field `part`. */ + final SimpleIdentifier getPart(int i) { swift_identifier_part(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_identifier_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_identifier_part(this, _, result) } } /** A class representing `if_condition` nodes. */ @@ -1104,8 +1290,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "IfCondition" } - /** Gets the child of this node. */ - final AstNode getChild() { swift_if_condition_def(this, result) } + /** Gets the node corresponding to the field `kind`. */ + final AstNode getKind() { swift_if_condition_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_if_condition_def(this, result) } @@ -1121,12 +1307,20 @@ module Swift { swift_if_let_binding_bound_identifier(this, result) } + /** Gets the node corresponding to the field `value`. */ + final Expression getValue() { swift_if_let_binding_value(this, result) } + + /** Gets the node corresponding to the field `where`. */ + final WhereClause getWhere() { swift_if_let_binding_where(this, result) } + /** Gets the `i`th child of this node. */ final AstNode getChild(int i) { swift_if_let_binding_child(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_if_let_binding_bound_identifier(this, result) or + swift_if_let_binding_value(this, result) or + swift_if_let_binding_where(this, result) or swift_if_let_binding_child(this, _, result) } } @@ -1136,15 +1330,24 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "IfStatement" } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody(int i) { swift_if_statement_body(this, i, result) } + /** Gets the node corresponding to the field `condition`. */ final IfCondition getCondition(int i) { swift_if_statement_condition(this, i, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_if_statement_child(this, i, result) } + /** Gets the node corresponding to the field `else_branch`. */ + final IfStatement getElseBranch() { swift_if_statement_else_branch(this, result) } + + /** Gets the node corresponding to the field `else_keyword`. */ + final Else getElseKeyword() { swift_if_statement_else_keyword(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_if_statement_condition(this, _, result) or swift_if_statement_child(this, _, result) + swift_if_statement_body(this, _, result) or + swift_if_statement_condition(this, _, result) or + swift_if_statement_else_branch(this, result) or + swift_if_statement_else_keyword(this, result) } } @@ -1153,8 +1356,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ImplicitlyUnwrappedType" } - /** Gets the child of this node. */ - final Type getChild() { swift_implicitly_unwrapped_type_def(this, result) } + /** Gets the node corresponding to the field `name`. */ + final Type getName() { swift_implicitly_unwrapped_type_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_implicitly_unwrapped_type_def(this, result) } @@ -1165,11 +1368,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ImportDeclaration" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_import_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_import_declaration_modifiers(this, result) } + + /** Gets the node corresponding to the field `name`. */ + final Identifier getName() { swift_import_declaration_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_import_declaration_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_import_declaration_modifiers(this, result) or swift_import_declaration_def(this, result) + } } /** A class representing `infix_expression` nodes. */ @@ -1199,20 +1407,20 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "InheritanceConstraint" } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_inheritance_constraint_attribute(this, i, result) } + /** Gets the node corresponding to the field `constrained_type`. */ final AstNode getConstrainedType() { swift_inheritance_constraint_def(this, result, _) } /** Gets the node corresponding to the field `inherits_from`. */ final AstNode getInheritsFrom() { swift_inheritance_constraint_def(this, _, result) } - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_inheritance_constraint_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_inheritance_constraint_attribute(this, _, result) or swift_inheritance_constraint_def(this, result, _) or - swift_inheritance_constraint_def(this, _, result) or - swift_inheritance_constraint_child(this, _, result) + swift_inheritance_constraint_def(this, _, result) } } @@ -1239,6 +1447,15 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "InitDeclaration" } + /** Gets the node corresponding to the field `async`. */ + final AsyncKeyword getAsync() { swift_init_declaration_async(this, result) } + + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_init_declaration_attribute(this, i, result) } + + /** Gets the node corresponding to the field `bang`. */ + final Bang getBang() { swift_init_declaration_bang(this, result) } + /** Gets the node corresponding to the field `body`. */ final FunctionBody getBody() { swift_init_declaration_body(this, result) } @@ -1247,19 +1464,42 @@ module Swift { swift_init_declaration_default_value(this, i, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_init_declaration_modifiers(this, result) } + /** Gets the node corresponding to the field `name`. */ final string getName() { exists(int value | swift_init_declaration_def(this, value) | (result = "init" and value = 0)) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_init_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `parameter`. */ + final Parameter getParameter(int i) { swift_init_declaration_parameter(this, i, result) } + + /** Gets the node corresponding to the field `throws`. */ + final AstNode getThrows() { swift_init_declaration_throws(this, result) } + + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_init_declaration_type_constraints(this, result) + } + + /** Gets the node corresponding to the field `type_parameters`. */ + final TypeParameters getTypeParameters() { + swift_init_declaration_type_parameters(this, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_init_declaration_async(this, result) or + swift_init_declaration_attribute(this, _, result) or + swift_init_declaration_bang(this, result) or swift_init_declaration_body(this, result) or swift_init_declaration_default_value(this, _, result) or - swift_init_declaration_child(this, _, result) + swift_init_declaration_modifiers(this, result) or + swift_init_declaration_parameter(this, _, result) or + swift_init_declaration_throws(this, result) or + swift_init_declaration_type_constraints(this, result) or + swift_init_declaration_type_parameters(this, result) } } @@ -1282,18 +1522,20 @@ module Swift { swift_interpolated_expression_reference_specifier(this, i, result) } + /** Gets the node corresponding to the field `type_modifiers`. */ + final TypeModifiers getTypeModifiers() { + swift_interpolated_expression_type_modifiers(this, result) + } + /** Gets the node corresponding to the field `value`. */ final Expression getValue() { swift_interpolated_expression_value(this, result) } - /** Gets the child of this node. */ - final TypeModifiers getChild() { swift_interpolated_expression_child(this, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_interpolated_expression_name(this, result) or swift_interpolated_expression_reference_specifier(this, _, result) or - swift_interpolated_expression_value(this, result) or - swift_interpolated_expression_child(this, result) + swift_interpolated_expression_type_modifiers(this, result) or + swift_interpolated_expression_value(this, result) } } @@ -1314,8 +1556,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "KeyPathStringExpression" } - /** Gets the child of this node. */ - final Expression getChild() { swift_key_path_string_expression_def(this, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expression getExpr() { swift_key_path_string_expression_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_key_path_string_expression_def(this, result) } @@ -1326,16 +1568,26 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "LambdaFunctionType" } + /** Gets the node corresponding to the field `async`. */ + final AsyncKeyword getAsync() { swift_lambda_function_type_async(this, result) } + + /** Gets the node corresponding to the field `params`. */ + final LambdaFunctionTypeParameters getParams() { + swift_lambda_function_type_params(this, result) + } + /** Gets the node corresponding to the field `return_type`. */ final AstNode getReturnType() { swift_lambda_function_type_return_type(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_lambda_function_type_child(this, i, result) } + /** Gets the node corresponding to the field `throws`. */ + final AstNode getThrows() { swift_lambda_function_type_throws(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_lambda_function_type_async(this, result) or + swift_lambda_function_type_params(this, result) or swift_lambda_function_type_return_type(this, result) or - swift_lambda_function_type_child(this, _, result) + swift_lambda_function_type_throws(this, result) } } @@ -1344,14 +1596,14 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "LambdaFunctionTypeParameters" } - /** Gets the `i`th child of this node. */ - final LambdaParameter getChild(int i) { - swift_lambda_function_type_parameters_child(this, i, result) + /** Gets the node corresponding to the field `parameter`. */ + final LambdaParameter getParameter(int i) { + swift_lambda_function_type_parameters_parameter(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_lambda_function_type_parameters_child(this, _, result) + swift_lambda_function_type_parameters_parameter(this, _, result) } } @@ -1360,20 +1612,24 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "LambdaLiteral" } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_lambda_literal_attribute(this, i, result) } + + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_lambda_literal_body(this, result) } + /** Gets the node corresponding to the field `captures`. */ final CaptureList getCaptures() { swift_lambda_literal_captures(this, result) } /** Gets the node corresponding to the field `type`. */ final LambdaFunctionType getType() { swift_lambda_literal_type(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_lambda_literal_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_lambda_literal_attribute(this, _, result) or + swift_lambda_literal_body(this, result) or swift_lambda_literal_captures(this, result) or - swift_lambda_literal_type(this, result) or - swift_lambda_literal_child(this, _, result) + swift_lambda_literal_type(this, result) } } @@ -1385,21 +1641,21 @@ module Swift { /** Gets the node corresponding to the field `external_name`. */ final SimpleIdentifier getExternalName() { swift_lambda_parameter_external_name(this, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final ParameterModifiers getModifiers() { swift_lambda_parameter_modifiers(this, result) } + /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_lambda_parameter_name(this, result) } + final AstNode getName() { swift_lambda_parameter_def(this, result) } /** Gets the node corresponding to the field `type`. */ final AstNode getType() { swift_lambda_parameter_type(this, result) } - /** Gets the child of this node. */ - final AstNode getChild() { swift_lambda_parameter_child(this, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_lambda_parameter_external_name(this, result) or - swift_lambda_parameter_name(this, result) or - swift_lambda_parameter_type(this, result) or - swift_lambda_parameter_child(this, result) + swift_lambda_parameter_modifiers(this, result) or + swift_lambda_parameter_def(this, result) or + swift_lambda_parameter_type(this, result) } } @@ -1436,6 +1692,9 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "MacroDeclaration" } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_macro_declaration_attribute(this, i, result) } + /** Gets the node corresponding to the field `default_value`. */ final Expression getDefaultValue(int i) { swift_macro_declaration_default_value(this, i, result) @@ -1444,13 +1703,18 @@ module Swift { /** Gets the node corresponding to the field `definition`. */ final MacroDefinition getDefinition() { swift_macro_declaration_definition(this, result) } + /** Gets the node corresponding to the field `parameter`. */ + final Parameter getParameter(int i) { swift_macro_declaration_parameter(this, i, result) } + /** Gets the `i`th child of this node. */ final AstNode getChild(int i) { swift_macro_declaration_child(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_macro_declaration_attribute(this, _, result) or swift_macro_declaration_default_value(this, _, result) or swift_macro_declaration_definition(this, result) or + swift_macro_declaration_parameter(this, _, result) or swift_macro_declaration_child(this, _, result) } } @@ -1472,11 +1736,23 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "MacroInvocation" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_macro_invocation_child(this, i, result) } + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_macro_invocation_def(this, result, _) } + + /** Gets the node corresponding to the field `suffix`. */ + final CallSuffix getSuffix() { swift_macro_invocation_def(this, _, result) } + + /** Gets the node corresponding to the field `type_parameters`. */ + final TypeParameters getTypeParameters() { + swift_macro_invocation_type_parameters(this, result) + } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_macro_invocation_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_macro_invocation_def(this, result, _) or + swift_macro_invocation_def(this, _, result) or + swift_macro_invocation_type_parameters(this, result) + } } /** A class representing `member_modifier` tokens. */ @@ -1490,8 +1766,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Metatype" } - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_metatype_def(this, result) } + /** Gets the node corresponding to the field `name`. */ + final UnannotatedType getName() { swift_metatype_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_metatype_def(this, result) } @@ -1502,11 +1778,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Modifiers" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_modifiers_child(this, i, result) } + /** Gets the node corresponding to the field `modifier`. */ + final AstNode getModifier(int i) { swift_modifiers_modifier(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_modifiers_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_modifiers_modifier(this, _, result) } } /** A class representing `modify_specifier` nodes. */ @@ -1514,11 +1790,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ModifySpecifier" } - /** Gets the child of this node. */ - final MutationModifier getChild() { swift_modify_specifier_child(this, result) } + /** Gets the node corresponding to the field `mutation`. */ + final MutationModifier getMutation() { swift_modify_specifier_mutation(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_modify_specifier_child(this, result) } + final override AstNode getAFieldOrChild() { swift_modify_specifier_mutation(this, result) } } /** A class representing `multi_line_str_text` tokens. */ @@ -1623,12 +1899,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "NestedTypeIdentifier" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_nested_type_identifier_child(this, i, result) } + /** Gets the node corresponding to the field `base`. */ + final UnannotatedType getBase() { swift_nested_type_identifier_def(this, result) } + + /** Gets the node corresponding to the field `member`. */ + final SimpleIdentifier getMember(int i) { swift_nested_type_identifier_member(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_nested_type_identifier_child(this, _, result) + swift_nested_type_identifier_def(this, result) or + swift_nested_type_identifier_member(this, _, result) } } @@ -1661,8 +1941,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "OpaqueType" } - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_opaque_type_def(this, result) } + /** Gets the node corresponding to the field `name`. */ + final UnannotatedType getName() { swift_opaque_type_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_opaque_type_def(this, result) } @@ -1699,11 +1979,36 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "OperatorDeclaration" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_operator_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `body`. */ + final DeprecatedOperatorDeclarationBody getBody() { + swift_operator_declaration_body(this, result) + } + + /** Gets the node corresponding to the field `kind`. */ + final string getKind() { + exists(int value | swift_operator_declaration_def(this, value, _) | + result = "infix" and value = 0 + or + result = "postfix" and value = 1 + or + result = "prefix" and value = 2 + ) + } + + /** Gets the node corresponding to the field `name`. */ + final ReferenceableOperator getName() { swift_operator_declaration_def(this, _, result) } + + /** Gets the node corresponding to the field `precedence_group`. */ + final SimpleIdentifier getPrecedenceGroup() { + swift_operator_declaration_precedence_group(this, result) + } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_operator_declaration_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_operator_declaration_body(this, result) or + swift_operator_declaration_def(this, _, result) or + swift_operator_declaration_precedence_group(this, result) + } } /** A class representing `optional_chain_marker` nodes. */ @@ -1711,8 +2016,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "OptionalChainMarker" } - /** Gets the child of this node. */ - final Expression getChild() { swift_optional_chain_marker_def(this, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expression getExpr() { swift_optional_chain_marker_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_optional_chain_marker_def(this, result) } @@ -1744,21 +2049,21 @@ module Swift { /** Gets the node corresponding to the field `external_name`. */ final SimpleIdentifier getExternalName() { swift_parameter_external_name(this, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final ParameterModifiers getModifiers() { swift_parameter_modifiers(this, result) } + /** Gets the node corresponding to the field `name`. */ final SimpleIdentifier getName() { swift_parameter_def(this, result, _) } /** Gets the node corresponding to the field `type`. */ final AstNode getType() { swift_parameter_def(this, _, result) } - /** Gets the child of this node. */ - final ParameterModifiers getChild() { swift_parameter_child(this, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_parameter_external_name(this, result) or + swift_parameter_modifiers(this, result) or swift_parameter_def(this, result, _) or - swift_parameter_def(this, _, result) or - swift_parameter_child(this, result) + swift_parameter_def(this, _, result) } } @@ -1773,11 +2078,15 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ParameterModifiers" } - /** Gets the `i`th child of this node. */ - final ParameterModifier getChild(int i) { swift_parameter_modifiers_child(this, i, result) } + /** Gets the node corresponding to the field `modifier`. */ + final ParameterModifier getModifier(int i) { + swift_parameter_modifiers_modifier(this, i, result) + } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_parameter_modifiers_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_parameter_modifiers_modifier(this, _, result) + } } /** A class representing `pattern` nodes. */ @@ -1802,11 +2111,17 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "PlaygroundLiteral" } - /** Gets the `i`th child of this node. */ - final Expression getChild(int i) { swift_playground_literal_child(this, i, result) } + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName(int i) { swift_playground_literal_name(this, i, result) } + + /** Gets the node corresponding to the field `value`. */ + final Expression getValue(int i) { swift_playground_literal_value(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_playground_literal_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_playground_literal_name(this, _, result) or + swift_playground_literal_value(this, _, result) + } } /** A class representing `postfix_expression` nodes. */ @@ -1831,12 +2146,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "PrecedenceGroupAttribute" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_precedence_group_attribute_child(this, i, result) } + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_precedence_group_attribute_def(this, result, _) } + + /** Gets the node corresponding to the field `value`. */ + final AstNode getValue() { swift_precedence_group_attribute_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_precedence_group_attribute_child(this, _, result) + swift_precedence_group_attribute_def(this, result, _) or + swift_precedence_group_attribute_def(this, _, result) } } @@ -1845,14 +2164,14 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "PrecedenceGroupAttributes" } - /** Gets the `i`th child of this node. */ - final PrecedenceGroupAttribute getChild(int i) { - swift_precedence_group_attributes_child(this, i, result) + /** Gets the node corresponding to the field `attribute`. */ + final PrecedenceGroupAttribute getAttribute(int i) { + swift_precedence_group_attributes_attribute(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_precedence_group_attributes_child(this, _, result) + swift_precedence_group_attributes_attribute(this, _, result) } } @@ -1861,12 +2180,18 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "PrecedenceGroupDeclaration" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_precedence_group_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `attributes`. */ + final PrecedenceGroupAttributes getAttributes() { + swift_precedence_group_declaration_attributes(this, result) + } + + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_precedence_group_declaration_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_precedence_group_declaration_child(this, _, result) + swift_precedence_group_declaration_attributes(this, result) or + swift_precedence_group_declaration_def(this, result) } } @@ -1903,6 +2228,9 @@ module Swift { swift_property_declaration_computed_value(this, i, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final AstNode getModifiers(int i) { swift_property_declaration_modifiers(this, i, result) } + /** Gets the node corresponding to the field `name`. */ final Pattern getName(int i) { swift_property_declaration_name(this, i, result) } @@ -1915,6 +2243,7 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_property_declaration_computed_value(this, _, result) or + swift_property_declaration_modifiers(this, _, result) or swift_property_declaration_name(this, _, result) or swift_property_declaration_value(this, _, result) or swift_property_declaration_child(this, _, result) @@ -1944,12 +2273,12 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ProtocolCompositionType" } - /** Gets the `i`th child of this node. */ - final UnannotatedType getChild(int i) { swift_protocol_composition_type_child(this, i, result) } + /** Gets the node corresponding to the field `type`. */ + final UnannotatedType getType(int i) { swift_protocol_composition_type_type(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_protocol_composition_type_child(this, _, result) + swift_protocol_composition_type_type(this, _, result) } } @@ -1958,6 +2287,9 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ProtocolDeclaration" } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_protocol_declaration_attribute(this, i, result) } + /** Gets the node corresponding to the field `body`. */ final ProtocolBody getBody() { swift_protocol_declaration_def(this, result, _, _) } @@ -1968,16 +2300,33 @@ module Swift { ) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_protocol_declaration_modifiers(this, result) } + /** Gets the node corresponding to the field `name`. */ final TypeIdentifier getName() { swift_protocol_declaration_def(this, _, _, result) } + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_protocol_declaration_type_constraints(this, result) + } + + /** Gets the node corresponding to the field `type_parameters`. */ + final TypeParameters getTypeParameters() { + swift_protocol_declaration_type_parameters(this, result) + } + /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_declaration_child(this, i, result) } + final InheritanceSpecifier getChild(int i) { swift_protocol_declaration_child(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_protocol_declaration_attribute(this, _, result) or swift_protocol_declaration_def(this, result, _, _) or + swift_protocol_declaration_modifiers(this, result) or swift_protocol_declaration_def(this, _, _, result) or + swift_protocol_declaration_type_constraints(this, result) or + swift_protocol_declaration_type_parameters(this, result) or swift_protocol_declaration_child(this, _, result) } } @@ -1987,6 +2336,14 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ProtocolFunctionDeclaration" } + /** Gets the node corresponding to the field `async`. */ + final AsyncKeyword getAsync() { swift_protocol_function_declaration_async(this, result) } + + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { + swift_protocol_function_declaration_attribute(this, i, result) + } + /** Gets the node corresponding to the field `body`. */ final FunctionBody getBody() { swift_protocol_function_declaration_body(this, result) } @@ -1995,22 +2352,46 @@ module Swift { swift_protocol_function_declaration_default_value(this, i, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_protocol_function_declaration_modifiers(this, result) } + /** Gets the node corresponding to the field `name`. */ final AstNode getName() { swift_protocol_function_declaration_def(this, result) } + /** Gets the node corresponding to the field `parameter`. */ + final Parameter getParameter(int i) { + swift_protocol_function_declaration_parameter(this, i, result) + } + /** Gets the node corresponding to the field `return_type`. */ final AstNode getReturnType() { swift_protocol_function_declaration_return_type(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_function_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `throws`. */ + final AstNode getThrows() { swift_protocol_function_declaration_throws(this, result) } + + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_protocol_function_declaration_type_constraints(this, result) + } + + /** Gets the node corresponding to the field `type_parameters`. */ + final TypeParameters getTypeParameters() { + swift_protocol_function_declaration_type_parameters(this, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_protocol_function_declaration_async(this, result) or + swift_protocol_function_declaration_attribute(this, _, result) or swift_protocol_function_declaration_body(this, result) or swift_protocol_function_declaration_default_value(this, _, result) or + swift_protocol_function_declaration_modifiers(this, result) or swift_protocol_function_declaration_def(this, result) or + swift_protocol_function_declaration_parameter(this, _, result) or swift_protocol_function_declaration_return_type(this, result) or - swift_protocol_function_declaration_child(this, _, result) + swift_protocol_function_declaration_throws(this, result) or + swift_protocol_function_declaration_type_constraints(this, result) or + swift_protocol_function_declaration_type_parameters(this, result) } } @@ -2021,16 +2402,32 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ProtocolPropertyDeclaration" } - /** Gets the node corresponding to the field `name`. */ - final Pattern getName() { swift_protocol_property_declaration_def(this, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_protocol_property_declaration_modifiers(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_property_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `name`. */ + final Pattern getName() { swift_protocol_property_declaration_def(this, result, _) } + + /** Gets the node corresponding to the field `requirements`. */ + final ProtocolPropertyRequirements getRequirements() { + swift_protocol_property_declaration_def(this, _, result) + } + + /** Gets the node corresponding to the field `type`. */ + final TypeAnnotation getType() { swift_protocol_property_declaration_type(this, result) } + + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_protocol_property_declaration_type_constraints(this, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_protocol_property_declaration_def(this, result) or - swift_protocol_property_declaration_child(this, _, result) + swift_protocol_property_declaration_modifiers(this, result) or + swift_protocol_property_declaration_def(this, result, _) or + swift_protocol_property_declaration_def(this, _, result) or + swift_protocol_property_declaration_type(this, result) or + swift_protocol_property_declaration_type_constraints(this, result) } } @@ -2039,12 +2436,14 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ProtocolPropertyRequirements" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_property_requirements_child(this, i, result) } + /** Gets the node corresponding to the field `accessor`. */ + final AstNode getAccessor(int i) { + swift_protocol_property_requirements_accessor(this, i, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_protocol_property_requirements_child(this, _, result) + swift_protocol_property_requirements_accessor(this, _, result) } } @@ -2097,8 +2496,8 @@ module Swift { swift_raw_str_interpolation_interpolation(this, i, result) } - /** Gets the child of this node. */ - final RawStrInterpolationStart getChild() { swift_raw_str_interpolation_def(this, result) } + /** Gets the node corresponding to the field `start`. */ + final RawStrInterpolationStart getStart() { swift_raw_str_interpolation_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { @@ -2124,6 +2523,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "RawStringLiteral" } + /** Gets the node corresponding to the field `continuing`. */ + final RawStrContinuingIndicator getContinuing(int i) { + swift_raw_string_literal_continuing(this, i, result) + } + /** Gets the node corresponding to the field `interpolation`. */ final RawStrInterpolation getInterpolation(int i) { swift_raw_string_literal_interpolation(this, i, result) @@ -2132,16 +2536,11 @@ module Swift { /** Gets the node corresponding to the field `text`. */ final AstNode getText(int i) { swift_raw_string_literal_text(this, i, result) } - /** Gets the `i`th child of this node. */ - final RawStrContinuingIndicator getChild(int i) { - swift_raw_string_literal_child(this, i, result) - } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_raw_string_literal_continuing(this, _, result) or swift_raw_string_literal_interpolation(this, _, result) or - swift_raw_string_literal_text(this, _, result) or - swift_raw_string_literal_child(this, _, result) + swift_raw_string_literal_text(this, _, result) } } @@ -2156,11 +2555,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ReferenceableOperator" } - /** Gets the child of this node. */ - final AstNode getChild() { swift_referenceable_operator_child(this, result) } + /** Gets the node corresponding to the field `operator`. */ + final AstNode getOperator() { swift_referenceable_operator_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_referenceable_operator_child(this, result) } + final override AstNode getAFieldOrChild() { swift_referenceable_operator_def(this, result) } } /** A class representing `regex_literal` tokens. */ @@ -2174,18 +2573,18 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "RepeatWhileStatement" } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_repeat_while_statement_body(this, result) } + /** Gets the node corresponding to the field `condition`. */ final IfCondition getCondition(int i) { swift_repeat_while_statement_condition(this, i, result) } - /** Gets the child of this node. */ - final Statements getChild() { swift_repeat_while_statement_child(this, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_repeat_while_statement_condition(this, _, result) or - swift_repeat_while_statement_child(this, result) + swift_repeat_while_statement_body(this, result) or + swift_repeat_while_statement_condition(this, _, result) } } @@ -2194,8 +2593,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SelectorExpression" } - /** Gets the child of this node. */ - final Expression getChild() { swift_selector_expression_def(this, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expression getExpr() { swift_selector_expression_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_selector_expression_def(this, result) } @@ -2212,11 +2611,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SetterSpecifier" } - /** Gets the child of this node. */ - final MutationModifier getChild() { swift_setter_specifier_child(this, result) } + /** Gets the node corresponding to the field `mutation`. */ + final MutationModifier getMutation() { swift_setter_specifier_mutation(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_setter_specifier_child(this, result) } + final override AstNode getAFieldOrChild() { swift_setter_specifier_mutation(this, result) } } /** A class representing `shebang_line` tokens. */ @@ -2283,22 +2682,46 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SubscriptDeclaration" } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_subscript_declaration_attribute(this, i, result) } + + /** Gets the node corresponding to the field `body`. */ + final ComputedProperty getBody() { swift_subscript_declaration_def(this, result) } + /** Gets the node corresponding to the field `default_value`. */ final Expression getDefaultValue(int i) { swift_subscript_declaration_default_value(this, i, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_subscript_declaration_modifiers(this, result) } + + /** Gets the node corresponding to the field `parameter`. */ + final Parameter getParameter(int i) { swift_subscript_declaration_parameter(this, i, result) } + /** Gets the node corresponding to the field `return_type`. */ final AstNode getReturnType() { swift_subscript_declaration_return_type(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_subscript_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_subscript_declaration_type_constraints(this, result) + } + + /** Gets the node corresponding to the field `type_parameters`. */ + final TypeParameters getTypeParameters() { + swift_subscript_declaration_type_parameters(this, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_subscript_declaration_attribute(this, _, result) or + swift_subscript_declaration_def(this, result) or swift_subscript_declaration_default_value(this, _, result) or + swift_subscript_declaration_modifiers(this, result) or + swift_subscript_declaration_parameter(this, _, result) or swift_subscript_declaration_return_type(this, result) or - swift_subscript_declaration_child(this, _, result) + swift_subscript_declaration_type_constraints(this, result) or + swift_subscript_declaration_type_parameters(this, result) } } @@ -2349,15 +2772,15 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SwitchStatement" } + /** Gets the node corresponding to the field `entry`. */ + final SwitchEntry getEntry(int i) { swift_switch_statement_entry(this, i, result) } + /** Gets the node corresponding to the field `expr`. */ final Expression getExpr() { swift_switch_statement_def(this, result) } - /** Gets the `i`th child of this node. */ - final SwitchEntry getChild(int i) { swift_switch_statement_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_switch_statement_def(this, result) or swift_switch_statement_child(this, _, result) + swift_switch_statement_entry(this, _, result) or swift_switch_statement_def(this, result) } } @@ -2415,8 +2838,8 @@ module Swift { /** Gets the node corresponding to the field `expr`. */ final Expression getExpr() { swift_try_expression_def(this, result, _) } - /** Gets the child of this node. */ - final TryOperator getChild() { swift_try_expression_def(this, _, result) } + /** Gets the node corresponding to the field `operator`. */ + final TryOperator getOperator() { swift_try_expression_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { @@ -2469,20 +2892,24 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TupleTypeItem" } + /** Gets the node corresponding to the field `modifiers`. */ + final ParameterModifiers getModifiers() { swift_tuple_type_item_modifiers(this, result) } + /** Gets the node corresponding to the field `name`. */ final SimpleIdentifier getName() { swift_tuple_type_item_name(this, result) } /** Gets the node corresponding to the field `type`. */ final Type getType() { swift_tuple_type_item_type(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_tuple_type_item_child(this, i, result) } + /** Gets the child of this node. */ + final AstNode getChild() { swift_tuple_type_item_child(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_tuple_type_item_modifiers(this, result) or swift_tuple_type_item_name(this, result) or swift_tuple_type_item_type(this, result) or - swift_tuple_type_item_child(this, _, result) + swift_tuple_type_item_child(this, result) } } @@ -2520,11 +2947,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypeArguments" } - /** Gets the `i`th child of this node. */ - final Type getChild(int i) { swift_type_arguments_child(this, i, result) } + /** Gets the node corresponding to the field `argument`. */ + final Type getArgument(int i) { swift_type_arguments_argument(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_arguments_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_type_arguments_argument(this, _, result) } } /** A class representing `type_constraint` nodes. */ @@ -2532,8 +2959,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypeConstraint" } - /** Gets the child of this node. */ - final AstNode getChild() { swift_type_constraint_def(this, result) } + /** Gets the node corresponding to the field `constraint`. */ + final AstNode getConstraint() { swift_type_constraint_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_type_constraint_def(this, result) } @@ -2544,11 +2971,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypeConstraints" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_type_constraints_child(this, i, result) } + /** Gets the node corresponding to the field `constraint`. */ + final TypeConstraint getConstraint(int i) { swift_type_constraints_constraint(this, i, result) } + + /** Gets the node corresponding to the field `keyword`. */ + final WhereKeyword getKeyword() { swift_type_constraints_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_constraints_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_type_constraints_constraint(this, _, result) or swift_type_constraints_def(this, result) + } } /** A class representing `type_identifier` tokens. */ @@ -2564,11 +2996,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypeModifiers" } - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_type_modifiers_child(this, i, result) } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { swift_type_modifiers_attribute(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_modifiers_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_type_modifiers_attribute(this, _, result) } } /** A class representing `type_pack_expansion` nodes. */ @@ -2576,8 +3008,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypePackExpansion" } - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_type_pack_expansion_def(this, result) } + /** Gets the node corresponding to the field `name`. */ + final UnannotatedType getName() { swift_type_pack_expansion_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_type_pack_expansion_def(this, result) } @@ -2588,11 +3020,21 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypeParameter" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_type_parameter_child(this, i, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final TypeParameterModifiers getModifiers() { swift_type_parameter_modifiers(this, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName() { swift_type_parameter_def(this, result) } + + /** Gets the node corresponding to the field `type`. */ + final Type getType() { swift_type_parameter_type(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_parameter_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_type_parameter_modifiers(this, result) or + swift_type_parameter_def(this, result) or + swift_type_parameter_type(this, result) + } } /** A class representing `type_parameter_modifiers` nodes. */ @@ -2600,12 +3042,14 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypeParameterModifiers" } - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_type_parameter_modifiers_child(this, i, result) } + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute(int i) { + swift_type_parameter_modifiers_attribute(this, i, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_type_parameter_modifiers_child(this, _, result) + swift_type_parameter_modifiers_attribute(this, _, result) } } @@ -2614,8 +3058,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypeParameterPack" } - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_type_parameter_pack_def(this, result) } + /** Gets the node corresponding to the field `name`. */ + final UnannotatedType getName() { swift_type_parameter_pack_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_type_parameter_pack_def(this, result) } @@ -2626,11 +3070,17 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypeParameters" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_type_parameters_child(this, i, result) } + /** Gets the node corresponding to the field `constraints`. */ + final TypeConstraints getConstraints() { swift_type_parameters_constraints(this, result) } + + /** Gets the node corresponding to the field `parameter`. */ + final TypeParameter getParameter(int i) { swift_type_parameters_parameter(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_parameters_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_type_parameters_constraints(this, result) or + swift_type_parameters_parameter(this, _, result) + } } /** A class representing `typealias_declaration` nodes. */ @@ -2638,20 +3088,26 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TypealiasDeclaration" } + /** Gets the node corresponding to the field `modifiers`. */ + final AstNode getModifiers(int i) { swift_typealias_declaration_modifiers(this, i, result) } + /** Gets the node corresponding to the field `name`. */ final TypeIdentifier getName() { swift_typealias_declaration_def(this, result, _) } + /** Gets the node corresponding to the field `type_parameters`. */ + final TypeParameters getTypeParameters() { + swift_typealias_declaration_type_parameters(this, result) + } + /** Gets the node corresponding to the field `value`. */ final Type getValue() { swift_typealias_declaration_def(this, _, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_typealias_declaration_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_typealias_declaration_modifiers(this, _, result) or swift_typealias_declaration_def(this, result, _) or - swift_typealias_declaration_def(this, _, result) or - swift_typealias_declaration_child(this, _, result) + swift_typealias_declaration_type_parameters(this, result) or + swift_typealias_declaration_def(this, _, result) } } @@ -2662,11 +3118,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "UserType" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_user_type_child(this, i, result) } + /** Gets the node corresponding to the field `part`. */ + final AstNode getPart(int i) { swift_user_type_part(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_user_type_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_user_type_part(this, _, result) } } /** A class representing `value_argument` nodes. */ @@ -2682,18 +3138,18 @@ module Swift { swift_value_argument_reference_specifier(this, i, result) } + /** Gets the node corresponding to the field `type_modifiers`. */ + final TypeModifiers getTypeModifiers() { swift_value_argument_type_modifiers(this, result) } + /** Gets the node corresponding to the field `value`. */ final Expression getValue() { swift_value_argument_value(this, result) } - /** Gets the child of this node. */ - final TypeModifiers getChild() { swift_value_argument_child(this, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_value_argument_name(this, result) or swift_value_argument_reference_specifier(this, _, result) or - swift_value_argument_value(this, result) or - swift_value_argument_child(this, result) + swift_value_argument_type_modifiers(this, result) or + swift_value_argument_value(this, result) } } @@ -2714,11 +3170,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ValueArguments" } - /** Gets the `i`th child of this node. */ - final ValueArgument getChild(int i) { swift_value_arguments_child(this, i, result) } + /** Gets the node corresponding to the field `argument`. */ + final ValueArgument getArgument(int i) { swift_value_arguments_argument(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_arguments_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_value_arguments_argument(this, _, result) } } /** A class representing `value_binding_pattern` nodes. */ @@ -2744,8 +3200,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ValuePackExpansion" } - /** Gets the child of this node. */ - final Expression getChild() { swift_value_pack_expansion_def(this, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expression getExpr() { swift_value_pack_expansion_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_value_pack_expansion_def(this, result) } @@ -2756,8 +3212,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ValueParameterPack" } - /** Gets the child of this node. */ - final Expression getChild() { swift_value_parameter_pack_def(this, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expression getExpr() { swift_value_parameter_pack_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_value_parameter_pack_def(this, result) } @@ -2774,11 +3230,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "WhereClause" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_where_clause_child(this, i, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expression getExpr() { swift_where_clause_def(this, result, _) } + + /** Gets the node corresponding to the field `keyword`. */ + final WhereKeyword getKeyword() { swift_where_clause_def(this, _, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_where_clause_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_where_clause_def(this, result, _) or swift_where_clause_def(this, _, result) + } } /** A class representing `where_keyword` tokens. */ @@ -2792,15 +3253,15 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "WhileStatement" } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_while_statement_body(this, result) } + /** Gets the node corresponding to the field `condition`. */ final IfCondition getCondition(int i) { swift_while_statement_condition(this, i, result) } - /** Gets the child of this node. */ - final Statements getChild() { swift_while_statement_child(this, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_while_statement_condition(this, _, result) or swift_while_statement_child(this, result) + swift_while_statement_body(this, result) or swift_while_statement_condition(this, _, result) } } @@ -2815,11 +3276,21 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "WillsetClause" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_willset_clause_child(this, i, result) } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_willset_clause_body(this, result) } + + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_willset_clause_modifiers(this, result) } + + /** Gets the node corresponding to the field `parameter`. */ + final SimpleIdentifier getParameter() { swift_willset_clause_parameter(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_willset_clause_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_willset_clause_body(this, result) or + swift_willset_clause_modifiers(this, result) or + swift_willset_clause_parameter(this, result) + } } /** A class representing `willset_didset_block` nodes. */ @@ -2827,10 +3298,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "WillsetDidsetBlock" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_willset_didset_block_child(this, i, result) } + /** Gets the node corresponding to the field `didset`. */ + final DidsetClause getDidset() { swift_willset_didset_block_didset(this, result) } + + /** Gets the node corresponding to the field `willset`. */ + final WillsetClause getWillset() { swift_willset_didset_block_willset(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_willset_didset_block_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_willset_didset_block_didset(this, result) or + swift_willset_didset_block_willset(this, result) + } } } diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme index 5d9826b69a8..1dfd0395e21 100644 --- a/unified/ql/lib/unified.dbscheme +++ b/unified/ql/lib/unified.dbscheme @@ -164,8 +164,8 @@ swift_array_type_def( swift_as_expression_def( unique int id: @swift_as_expression, int expr: @swift_expression ref, - int type__: @swift_type__ ref, - int child: @swift_token_as_operator ref + int operator: @swift_token_as_operator ref, + int type__: @swift_type__ ref ); case @swift_assignment.operator of @@ -190,18 +190,19 @@ swift_associatedtype_declaration_default_value( unique int default_value: @swift_type__ ref ); +swift_associatedtype_declaration_modifiers( + unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, + unique int modifiers: @swift_modifiers ref +); + swift_associatedtype_declaration_must_inherit( unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, unique int must_inherit: @swift_type__ ref ); -@swift_associatedtype_declaration_child_type = @swift_modifiers | @swift_type_constraints - -#keyset[swift_associatedtype_declaration, index] -swift_associatedtype_declaration_child( - int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - int index: int ref, - unique int child: @swift_associatedtype_declaration_child_type ref +swift_associatedtype_declaration_type_constraints( + unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, + unique int type_constraints: @swift_type_constraints ref ); swift_associatedtype_declaration_def( @@ -209,17 +210,44 @@ swift_associatedtype_declaration_def( int name: @swift_token_type_identifier ref ); -@swift_attribute_child_type = @swift_expression | @swift_user_type - #keyset[swift_attribute, index] -swift_attribute_child( +swift_attribute_argument( int swift_attribute: @swift_attribute ref, int index: int ref, - unique int child: @swift_attribute_child_type ref + unique int argument: @swift_expression ref +); + +#keyset[swift_attribute, index] +swift_attribute_argument_name( + int swift_attribute: @swift_attribute ref, + int index: int ref, + unique int argument_name: @swift_token_simple_identifier ref +); + +#keyset[swift_attribute, index] +swift_attribute_param_ref( + int swift_attribute: @swift_attribute ref, + int index: int ref, + unique int param_ref: @swift_token_simple_identifier ref +); + +#keyset[swift_attribute, index] +swift_attribute_platform( + int swift_attribute: @swift_attribute ref, + int index: int ref, + unique int platform: @swift_token_simple_identifier ref +); + +#keyset[swift_attribute, index] +swift_attribute_version( + int swift_attribute: @swift_attribute ref, + int index: int ref, + unique int version: @swift_token_integer_literal ref ); swift_attribute_def( - unique int id: @swift_attribute + unique int id: @swift_attribute, + int name: @swift_user_type ref ); @swift_availability_condition_child_type = @swift_identifier | @swift_token_integer_literal @@ -265,6 +293,16 @@ swift_bitwise_operation_def( int rhs: @swift_expression ref ); +swift_call_expression_function( + unique int swift_call_expression: @swift_call_expression ref, + unique int function: @swift_expression ref +); + +swift_call_expression_suffix( + unique int swift_call_expression: @swift_call_expression ref, + unique int suffix: @swift_call_suffix ref +); + @swift_call_expression_child_type = @swift_call_suffix | @swift_expression #keyset[swift_call_expression, index] @@ -299,10 +337,10 @@ swift_call_suffix_def( ); #keyset[swift_capture_list, index] -swift_capture_list_child( +swift_capture_list_item( int swift_capture_list: @swift_capture_list ref, int index: int ref, - unique int child: @swift_capture_list_item ref + unique int item: @swift_capture_list_item ref ); swift_capture_list_def( @@ -311,37 +349,39 @@ swift_capture_list_def( @swift_capture_list_item_name_type = @swift_token_self_expression | @swift_token_simple_identifier +swift_capture_list_item_ownership( + unique int swift_capture_list_item: @swift_capture_list_item ref, + unique int ownership: @swift_token_ownership_modifier ref +); + swift_capture_list_item_value( unique int swift_capture_list_item: @swift_capture_list_item ref, unique int value: @swift_expression ref ); -swift_capture_list_item_child( - unique int swift_capture_list_item: @swift_capture_list_item ref, - unique int child: @swift_token_ownership_modifier ref -); - swift_capture_list_item_def( unique int id: @swift_capture_list_item, int name: @swift_capture_list_item_name_type ref ); +swift_catch_block_body( + unique int swift_catch_block: @swift_catch_block ref, + unique int body: @swift_statements ref +); + swift_catch_block_error( unique int swift_catch_block: @swift_catch_block ref, unique int error: @swift_pattern ref ); -@swift_catch_block_child_type = @swift_statements | @swift_token_catch_keyword | @swift_where_clause - -#keyset[swift_catch_block, index] -swift_catch_block_child( - int swift_catch_block: @swift_catch_block ref, - int index: int ref, - unique int child: @swift_catch_block_child_type ref +swift_catch_block_where( + unique int swift_catch_block: @swift_catch_block ref, + unique int where: @swift_where_clause ref ); swift_catch_block_def( - unique int id: @swift_catch_block + unique int id: @swift_catch_block, + int keyword: @swift_token_catch_keyword ref ); case @swift_check_expression.op of @@ -374,6 +414,13 @@ swift_class_body_def( unique int id: @swift_class_body ); +#keyset[swift_class_declaration, index] +swift_class_declaration_attribute( + int swift_class_declaration: @swift_class_declaration ref, + int index: int ref, + unique int attribute: @swift_attribute ref +); + @swift_class_declaration_body_type = @swift_class_body | @swift_enum_class_body case @swift_class_declaration.declaration_kind of @@ -385,15 +432,32 @@ case @swift_class_declaration.declaration_kind of ; +@swift_class_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier + +#keyset[swift_class_declaration, index] +swift_class_declaration_modifiers( + int swift_class_declaration: @swift_class_declaration ref, + int index: int ref, + unique int modifiers: @swift_class_declaration_modifiers_type ref +); + @swift_class_declaration_name_type = @swift_token_type_identifier | @swift_unannotated_type -@swift_class_declaration_child_type = @swift_attribute | @swift_inheritance_specifier | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_type_constraints | @swift_type_parameters +swift_class_declaration_type_constraints( + unique int swift_class_declaration: @swift_class_declaration ref, + unique int type_constraints: @swift_type_constraints ref +); + +swift_class_declaration_type_parameters( + unique int swift_class_declaration: @swift_class_declaration ref, + unique int type_parameters: @swift_type_parameters ref +); #keyset[swift_class_declaration, index] swift_class_declaration_child( int swift_class_declaration: @swift_class_declaration ref, int index: int ref, - unique int child: @swift_class_declaration_child_type ref + unique int child: @swift_inheritance_specifier ref ); swift_class_declaration_def( @@ -418,56 +482,78 @@ swift_comparison_expression_def( int rhs: @swift_expression ref ); -@swift_computed_getter_child_type = @swift_attribute | @swift_getter_specifier | @swift_statements - #keyset[swift_computed_getter, index] -swift_computed_getter_child( +swift_computed_getter_attribute( int swift_computed_getter: @swift_computed_getter ref, int index: int ref, - unique int child: @swift_computed_getter_child_type ref + unique int attribute: @swift_attribute ref +); + +swift_computed_getter_body( + unique int swift_computed_getter: @swift_computed_getter ref, + unique int body: @swift_statements ref ); swift_computed_getter_def( - unique int id: @swift_computed_getter + unique int id: @swift_computed_getter, + int specifier: @swift_getter_specifier ref ); -@swift_computed_modify_child_type = @swift_attribute | @swift_modify_specifier | @swift_statements - #keyset[swift_computed_modify, index] -swift_computed_modify_child( +swift_computed_modify_attribute( int swift_computed_modify: @swift_computed_modify ref, int index: int ref, - unique int child: @swift_computed_modify_child_type ref + unique int attribute: @swift_attribute ref +); + +swift_computed_modify_body( + unique int swift_computed_modify: @swift_computed_modify ref, + unique int body: @swift_statements ref ); swift_computed_modify_def( - unique int id: @swift_computed_modify + unique int id: @swift_computed_modify, + int specifier: @swift_modify_specifier ref ); -@swift_computed_property_child_type = @swift_computed_getter | @swift_computed_modify | @swift_computed_setter | @swift_statements +@swift_computed_property_accessor_type = @swift_computed_getter | @swift_computed_modify | @swift_computed_setter #keyset[swift_computed_property, index] -swift_computed_property_child( +swift_computed_property_accessor( int swift_computed_property: @swift_computed_property ref, int index: int ref, - unique int child: @swift_computed_property_child_type ref + unique int accessor: @swift_computed_property_accessor_type ref +); + +swift_computed_property_body( + unique int swift_computed_property: @swift_computed_property ref, + unique int body: @swift_statements ref ); swift_computed_property_def( unique int id: @swift_computed_property ); -@swift_computed_setter_child_type = @swift_attribute | @swift_setter_specifier | @swift_statements | @swift_token_simple_identifier - #keyset[swift_computed_setter, index] -swift_computed_setter_child( +swift_computed_setter_attribute( int swift_computed_setter: @swift_computed_setter ref, int index: int ref, - unique int child: @swift_computed_setter_child_type ref + unique int attribute: @swift_attribute ref +); + +swift_computed_setter_body( + unique int swift_computed_setter: @swift_computed_setter ref, + unique int body: @swift_statements ref +); + +swift_computed_setter_parameter( + unique int swift_computed_setter: @swift_computed_setter ref, + unique int parameter: @swift_token_simple_identifier ref ); swift_computed_setter_def( - unique int id: @swift_computed_setter + unique int id: @swift_computed_setter, + int specifier: @swift_setter_specifier ref ); case @swift_conjunction_expression.op of @@ -487,7 +573,7 @@ swift_conjunction_expression_def( swift_constructor_expression_def( unique int id: @swift_constructor_expression, int constructed_type: @swift_constructor_expression_constructed_type_type ref, - int child: @swift_constructor_suffix ref + int suffix: @swift_constructor_suffix ref ); #keyset[swift_constructor_suffix, index] @@ -510,6 +596,13 @@ swift_constructor_suffix_def( unique int id: @swift_constructor_suffix ); +@swift_control_transfer_statement_kind_type = @swift_reserved_word + +swift_control_transfer_statement_kind( + unique int swift_control_transfer_statement: @swift_control_transfer_statement ref, + unique int kind: @swift_control_transfer_statement_kind_type ref +); + swift_control_transfer_statement_result( unique int swift_control_transfer_statement: @swift_control_transfer_statement ref, unique int result: @swift_expression ref @@ -528,9 +621,9 @@ swift_control_transfer_statement_def( unique int id: @swift_control_transfer_statement ); -swift_deinit_declaration_child( +swift_deinit_declaration_modifiers( unique int swift_deinit_declaration: @swift_deinit_declaration ref, - unique int child: @swift_modifiers ref + unique int modifiers: @swift_modifiers ref ); swift_deinit_declaration_def( @@ -575,13 +668,19 @@ swift_dictionary_type_def( int value: @swift_type__ ref ); -@swift_didset_clause_child_type = @swift_modifiers | @swift_statements | @swift_token_simple_identifier +swift_didset_clause_body( + unique int swift_didset_clause: @swift_didset_clause ref, + unique int body: @swift_statements ref +); -#keyset[swift_didset_clause, index] -swift_didset_clause_child( - int swift_didset_clause: @swift_didset_clause ref, - int index: int ref, - unique int child: @swift_didset_clause_child_type ref +swift_didset_clause_modifiers( + unique int swift_didset_clause: @swift_didset_clause ref, + unique int modifiers: @swift_modifiers ref +); + +swift_didset_clause_parameter( + unique int swift_didset_clause: @swift_didset_clause ref, + unique int parameter: @swift_token_simple_identifier ref ); swift_didset_clause_def( @@ -603,7 +702,7 @@ swift_directive_def( swift_directly_assignable_expression_def( unique int id: @swift_directly_assignable_expression, - int child: @swift_expression ref + int expr: @swift_expression ref ); case @swift_disjunction_expression.op of @@ -618,13 +717,16 @@ swift_disjunction_expression_def( int rhs: @swift_expression ref ); -@swift_do_statement_child_type = @swift_catch_block | @swift_statements +swift_do_statement_body( + unique int swift_do_statement: @swift_do_statement ref, + unique int body: @swift_statements ref +); #keyset[swift_do_statement, index] -swift_do_statement_child( +swift_do_statement_catch( int swift_do_statement: @swift_do_statement ref, int index: int ref, - unique int child: @swift_do_statement_child_type ref + unique int catch: @swift_catch_block ref ); swift_do_statement_def( @@ -651,6 +753,11 @@ swift_enum_entry_data_contents( unique int data_contents: @swift_enum_type_parameters ref ); +swift_enum_entry_modifiers( + unique int swift_enum_entry: @swift_enum_entry ref, + unique int modifiers: @swift_modifiers ref +); + #keyset[swift_enum_entry, index] swift_enum_entry_name( int swift_enum_entry: @swift_enum_entry ref, @@ -665,11 +772,6 @@ swift_enum_entry_raw_value( unique int raw_value: @swift_expression ref ); -swift_enum_entry_child( - unique int swift_enum_entry: @swift_enum_entry ref, - unique int child: @swift_modifiers ref -); - swift_enum_entry_def( unique int id: @swift_enum_entry ); @@ -687,15 +789,15 @@ swift_enum_type_parameters_def( unique int id: @swift_enum_type_parameters ); -@swift_equality_constraint_constrained_type_type = @swift_identifier | @swift_nested_type_identifier - #keyset[swift_equality_constraint, index] -swift_equality_constraint_child( +swift_equality_constraint_attribute( int swift_equality_constraint: @swift_equality_constraint ref, int index: int ref, - unique int child: @swift_attribute ref + unique int attribute: @swift_attribute ref ); +@swift_equality_constraint_constrained_type_type = @swift_identifier | @swift_nested_type_identifier + swift_equality_constraint_def( unique int id: @swift_equality_constraint, int constrained_type: @swift_equality_constraint_constrained_type_type ref, @@ -719,23 +821,34 @@ swift_equality_expression_def( swift_existential_type_def( unique int id: @swift_existential_type, - int child: @swift_unannotated_type ref + int name: @swift_unannotated_type ref ); @swift_expression = @swift_additive_expression | @swift_array_literal | @swift_as_expression | @swift_assignment | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_check_expression | @swift_comparison_expression | @swift_conjunction_expression | @swift_constructor_expression | @swift_dictionary_literal | @swift_directive | @swift_disjunction_expression | @swift_equality_expression | @swift_if_statement | @swift_infix_expression | @swift_key_path_expression | @swift_key_path_string_expression | @swift_lambda_literal | @swift_line_string_literal | @swift_macro_invocation | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_nil_coalescing_expression | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_optional_chain_marker | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_referenceable_operator | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_diagnostic | @swift_token_fully_open_range | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_self_expression | @swift_token_simple_identifier | @swift_token_special_literal | @swift_token_super_expression | @swift_try_expression | @swift_tuple_expression | @swift_value_pack_expansion | @swift_value_parameter_pack swift_external_macro_definition_def( unique int id: @swift_external_macro_definition, - int child: @swift_value_arguments ref + int arguments: @swift_value_arguments ref ); -@swift_for_statement_child_type = @swift_statements | @swift_token_try_operator | @swift_type_annotation | @swift_where_clause +swift_for_statement_body( + unique int swift_for_statement: @swift_for_statement ref, + unique int body: @swift_statements ref +); -#keyset[swift_for_statement, index] -swift_for_statement_child( - int swift_for_statement: @swift_for_statement ref, - int index: int ref, - unique int child: @swift_for_statement_child_type ref +swift_for_statement_try( + unique int swift_for_statement: @swift_for_statement ref, + unique int try: @swift_token_try_operator ref +); + +swift_for_statement_type( + unique int swift_for_statement: @swift_for_statement ref, + unique int type__: @swift_type_annotation ref +); + +swift_for_statement_where( + unique int swift_for_statement: @swift_for_statement ref, + unique int where: @swift_where_clause ref ); swift_for_statement_def( @@ -744,15 +857,27 @@ swift_for_statement_def( int item: @swift_pattern ref ); -swift_function_body_child( +swift_function_body_body( unique int swift_function_body: @swift_function_body ref, - unique int child: @swift_statements ref + unique int body: @swift_statements ref ); swift_function_body_def( unique int id: @swift_function_body ); +swift_function_declaration_async( + unique int swift_function_declaration: @swift_function_declaration ref, + unique int async: @swift_token_async_keyword ref +); + +#keyset[swift_function_declaration, index] +swift_function_declaration_attribute( + int swift_function_declaration: @swift_function_declaration ref, + int index: int ref, + unique int attribute: @swift_attribute ref +); + #keyset[swift_function_declaration, index] swift_function_declaration_default_value( int swift_function_declaration: @swift_function_declaration ref, @@ -760,8 +885,24 @@ swift_function_declaration_default_value( unique int default_value: @swift_expression ref ); +@swift_function_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier + +#keyset[swift_function_declaration, index] +swift_function_declaration_modifiers( + int swift_function_declaration: @swift_function_declaration ref, + int index: int ref, + unique int modifiers: @swift_function_declaration_modifiers_type ref +); + @swift_function_declaration_name_type = @swift_referenceable_operator | @swift_token_simple_identifier +#keyset[swift_function_declaration, index] +swift_function_declaration_parameter( + int swift_function_declaration: @swift_function_declaration ref, + int index: int ref, + unique int parameter: @swift_parameter ref +); + @swift_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ swift_function_declaration_return_type( @@ -769,13 +910,21 @@ swift_function_declaration_return_type( unique int return_type: @swift_function_declaration_return_type_type ref ); -@swift_function_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_throws_clause | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_token_throws | @swift_type_constraints | @swift_type_parameters +@swift_function_declaration_throws_type = @swift_throws_clause | @swift_token_throws -#keyset[swift_function_declaration, index] -swift_function_declaration_child( - int swift_function_declaration: @swift_function_declaration ref, - int index: int ref, - unique int child: @swift_function_declaration_child_type ref +swift_function_declaration_throws( + unique int swift_function_declaration: @swift_function_declaration ref, + unique int throws: @swift_function_declaration_throws_type ref +); + +swift_function_declaration_type_constraints( + unique int swift_function_declaration: @swift_function_declaration ref, + unique int type_constraints: @swift_type_constraints ref +); + +swift_function_declaration_type_parameters( + unique int swift_function_declaration: @swift_function_declaration ref, + unique int type_parameters: @swift_type_parameters ref ); swift_function_declaration_def( @@ -784,11 +933,16 @@ swift_function_declaration_def( int name: @swift_function_declaration_name_type ref ); -@swift_function_type_child_type = @swift_throws_clause | @swift_token_throws - -swift_function_type_child( +swift_function_type_async( unique int swift_function_type: @swift_function_type ref, - unique int child: @swift_function_type_child_type ref + unique int async: @swift_token_async_keyword ref +); + +@swift_function_type_throws_type = @swift_throws_clause | @swift_token_throws + +swift_function_type_throws( + unique int swift_function_type: @swift_function_type ref, + unique int throws: @swift_function_type_throws_type ref ); swift_function_type_def( @@ -797,13 +951,18 @@ swift_function_type_def( int return_type: @swift_type__ ref ); -@swift_getter_specifier_child_type = @swift_throws_clause | @swift_token_mutation_modifier | @swift_token_throws +@swift_getter_specifier_effect_type = @swift_throws_clause | @swift_token_async_keyword | @swift_token_throws #keyset[swift_getter_specifier, index] -swift_getter_specifier_child( +swift_getter_specifier_effect( int swift_getter_specifier: @swift_getter_specifier ref, int index: int ref, - unique int child: @swift_getter_specifier_child_type ref + unique int effect: @swift_getter_specifier_effect_type ref +); + +swift_getter_specifier_mutation( + unique int swift_getter_specifier: @swift_getter_specifier ref, + unique int mutation: @swift_token_mutation_modifier ref ); swift_getter_specifier_def( @@ -812,6 +971,11 @@ swift_getter_specifier_def( @swift_global_declaration = @swift_associatedtype_declaration | @swift_class_declaration | @swift_function_declaration | @swift_import_declaration | @swift_init_declaration | @swift_macro_declaration | @swift_operator_declaration | @swift_precedence_group_declaration | @swift_property_declaration | @swift_protocol_declaration | @swift_typealias_declaration +swift_guard_statement_body( + unique int swift_guard_statement: @swift_guard_statement ref, + unique int body: @swift_statements ref +); + #keyset[swift_guard_statement, index] swift_guard_statement_condition( int swift_guard_statement: @swift_guard_statement ref, @@ -819,35 +983,27 @@ swift_guard_statement_condition( unique int condition: @swift_if_condition ref ); -@swift_guard_statement_child_type = @swift_statements | @swift_token_else - -#keyset[swift_guard_statement, index] -swift_guard_statement_child( - int swift_guard_statement: @swift_guard_statement ref, - int index: int ref, - unique int child: @swift_guard_statement_child_type ref -); - swift_guard_statement_def( - unique int id: @swift_guard_statement + unique int id: @swift_guard_statement, + int else_keyword: @swift_token_else ref ); #keyset[swift_identifier, index] -swift_identifier_child( +swift_identifier_part( int swift_identifier: @swift_identifier ref, int index: int ref, - unique int child: @swift_token_simple_identifier ref + unique int part: @swift_token_simple_identifier ref ); swift_identifier_def( unique int id: @swift_identifier ); -@swift_if_condition_child_type = @swift_availability_condition | @swift_expression | @swift_if_let_binding +@swift_if_condition_kind_type = @swift_availability_condition | @swift_expression | @swift_if_let_binding swift_if_condition_def( unique int id: @swift_if_condition, - int child: @swift_if_condition_child_type ref + int kind: @swift_if_condition_kind_type ref ); swift_if_let_binding_bound_identifier( @@ -855,7 +1011,17 @@ swift_if_let_binding_bound_identifier( unique int bound_identifier: @swift_token_simple_identifier ref ); -@swift_if_let_binding_child_type = @swift_expression | @swift_pattern | @swift_token_wildcard_pattern | @swift_type__ | @swift_type_annotation | @swift_user_type | @swift_value_binding_pattern | @swift_where_clause +swift_if_let_binding_value( + unique int swift_if_let_binding: @swift_if_let_binding ref, + unique int value: @swift_expression ref +); + +swift_if_let_binding_where( + unique int swift_if_let_binding: @swift_if_let_binding ref, + unique int where: @swift_where_clause ref +); + +@swift_if_let_binding_child_type = @swift_pattern | @swift_token_simple_identifier | @swift_token_wildcard_pattern | @swift_type__ | @swift_type_annotation | @swift_user_type | @swift_value_binding_pattern #keyset[swift_if_let_binding, index] swift_if_let_binding_child( @@ -868,6 +1034,13 @@ swift_if_let_binding_def( unique int id: @swift_if_let_binding ); +#keyset[swift_if_statement, index] +swift_if_statement_body( + int swift_if_statement: @swift_if_statement ref, + int index: int ref, + unique int body: @swift_statements ref +); + #keyset[swift_if_statement, index] swift_if_statement_condition( int swift_if_statement: @swift_if_statement ref, @@ -875,13 +1048,14 @@ swift_if_statement_condition( unique int condition: @swift_if_condition ref ); -@swift_if_statement_child_type = @swift_if_statement | @swift_statements | @swift_token_else +swift_if_statement_else_branch( + unique int swift_if_statement: @swift_if_statement ref, + unique int else_branch: @swift_if_statement ref +); -#keyset[swift_if_statement, index] -swift_if_statement_child( - int swift_if_statement: @swift_if_statement ref, - int index: int ref, - unique int child: @swift_if_statement_child_type ref +swift_if_statement_else_keyword( + unique int swift_if_statement: @swift_if_statement ref, + unique int else_keyword: @swift_token_else ref ); swift_if_statement_def( @@ -890,20 +1064,17 @@ swift_if_statement_def( swift_implicitly_unwrapped_type_def( unique int id: @swift_implicitly_unwrapped_type, - int child: @swift_type__ ref + int name: @swift_type__ ref ); -@swift_import_declaration_child_type = @swift_identifier | @swift_modifiers - -#keyset[swift_import_declaration, index] -swift_import_declaration_child( - int swift_import_declaration: @swift_import_declaration ref, - int index: int ref, - unique int child: @swift_import_declaration_child_type ref +swift_import_declaration_modifiers( + unique int swift_import_declaration: @swift_import_declaration ref, + unique int modifiers: @swift_modifiers ref ); swift_import_declaration_def( - unique int id: @swift_import_declaration + unique int id: @swift_import_declaration, + int name: @swift_identifier ref ); swift_infix_expression_def( @@ -913,17 +1084,17 @@ swift_infix_expression_def( int rhs: @swift_expression ref ); +#keyset[swift_inheritance_constraint, index] +swift_inheritance_constraint_attribute( + int swift_inheritance_constraint: @swift_inheritance_constraint ref, + int index: int ref, + unique int attribute: @swift_attribute ref +); + @swift_inheritance_constraint_constrained_type_type = @swift_identifier | @swift_nested_type_identifier @swift_inheritance_constraint_inherits_from_type = @swift_implicitly_unwrapped_type | @swift_type__ -#keyset[swift_inheritance_constraint, index] -swift_inheritance_constraint_child( - int swift_inheritance_constraint: @swift_inheritance_constraint ref, - int index: int ref, - unique int child: @swift_attribute ref -); - swift_inheritance_constraint_def( unique int id: @swift_inheritance_constraint, int constrained_type: @swift_inheritance_constraint_constrained_type_type ref, @@ -937,6 +1108,23 @@ swift_inheritance_specifier_def( int inherits_from: @swift_inheritance_specifier_inherits_from_type ref ); +swift_init_declaration_async( + unique int swift_init_declaration: @swift_init_declaration ref, + unique int async: @swift_token_async_keyword ref +); + +#keyset[swift_init_declaration, index] +swift_init_declaration_attribute( + int swift_init_declaration: @swift_init_declaration ref, + int index: int ref, + unique int attribute: @swift_attribute ref +); + +swift_init_declaration_bang( + unique int swift_init_declaration: @swift_init_declaration ref, + unique int bang: @swift_token_bang ref +); + swift_init_declaration_body( unique int swift_init_declaration: @swift_init_declaration ref, unique int body: @swift_function_body ref @@ -949,18 +1137,38 @@ swift_init_declaration_default_value( unique int default_value: @swift_expression ref ); +swift_init_declaration_modifiers( + unique int swift_init_declaration: @swift_init_declaration ref, + unique int modifiers: @swift_modifiers ref +); + case @swift_init_declaration.name of 0 = @swift_init_declaration_init ; -@swift_init_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_throws_clause | @swift_token_bang | @swift_token_throws | @swift_type_constraints | @swift_type_parameters - #keyset[swift_init_declaration, index] -swift_init_declaration_child( +swift_init_declaration_parameter( int swift_init_declaration: @swift_init_declaration ref, int index: int ref, - unique int child: @swift_init_declaration_child_type ref + unique int parameter: @swift_parameter ref +); + +@swift_init_declaration_throws_type = @swift_throws_clause | @swift_token_throws + +swift_init_declaration_throws( + unique int swift_init_declaration: @swift_init_declaration ref, + unique int throws: @swift_init_declaration_throws_type ref +); + +swift_init_declaration_type_constraints( + unique int swift_init_declaration: @swift_init_declaration ref, + unique int type_constraints: @swift_type_constraints ref +); + +swift_init_declaration_type_parameters( + unique int swift_init_declaration: @swift_init_declaration ref, + unique int type_parameters: @swift_type_parameters ref ); swift_init_declaration_def( @@ -980,16 +1188,16 @@ swift_interpolated_expression_reference_specifier( unique int reference_specifier: @swift_value_argument_label ref ); +swift_interpolated_expression_type_modifiers( + unique int swift_interpolated_expression: @swift_interpolated_expression ref, + unique int type_modifiers: @swift_type_modifiers ref +); + swift_interpolated_expression_value( unique int swift_interpolated_expression: @swift_interpolated_expression ref, unique int value: @swift_expression ref ); -swift_interpolated_expression_child( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int child: @swift_type_modifiers ref -); - swift_interpolated_expression_def( unique int id: @swift_interpolated_expression ); @@ -1009,7 +1217,17 @@ swift_key_path_expression_def( swift_key_path_string_expression_def( unique int id: @swift_key_path_string_expression, - int child: @swift_expression ref + int expr: @swift_expression ref +); + +swift_lambda_function_type_async( + unique int swift_lambda_function_type: @swift_lambda_function_type ref, + unique int async: @swift_token_async_keyword ref +); + +swift_lambda_function_type_params( + unique int swift_lambda_function_type: @swift_lambda_function_type ref, + unique int params: @swift_lambda_function_type_parameters ref ); @swift_lambda_function_type_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ @@ -1019,13 +1237,11 @@ swift_lambda_function_type_return_type( unique int return_type: @swift_lambda_function_type_return_type_type ref ); -@swift_lambda_function_type_child_type = @swift_lambda_function_type_parameters | @swift_throws_clause | @swift_token_throws +@swift_lambda_function_type_throws_type = @swift_throws_clause | @swift_token_throws -#keyset[swift_lambda_function_type, index] -swift_lambda_function_type_child( - int swift_lambda_function_type: @swift_lambda_function_type ref, - int index: int ref, - unique int child: @swift_lambda_function_type_child_type ref +swift_lambda_function_type_throws( + unique int swift_lambda_function_type: @swift_lambda_function_type ref, + unique int throws: @swift_lambda_function_type_throws_type ref ); swift_lambda_function_type_def( @@ -1033,16 +1249,28 @@ swift_lambda_function_type_def( ); #keyset[swift_lambda_function_type_parameters, index] -swift_lambda_function_type_parameters_child( +swift_lambda_function_type_parameters_parameter( int swift_lambda_function_type_parameters: @swift_lambda_function_type_parameters ref, int index: int ref, - unique int child: @swift_lambda_parameter ref + unique int parameter: @swift_lambda_parameter ref ); swift_lambda_function_type_parameters_def( unique int id: @swift_lambda_function_type_parameters ); +#keyset[swift_lambda_literal, index] +swift_lambda_literal_attribute( + int swift_lambda_literal: @swift_lambda_literal ref, + int index: int ref, + unique int attribute: @swift_attribute ref +); + +swift_lambda_literal_body( + unique int swift_lambda_literal: @swift_lambda_literal ref, + unique int body: @swift_statements ref +); + swift_lambda_literal_captures( unique int swift_lambda_literal: @swift_lambda_literal ref, unique int captures: @swift_capture_list ref @@ -1053,15 +1281,6 @@ swift_lambda_literal_type( unique int type__: @swift_lambda_function_type ref ); -@swift_lambda_literal_child_type = @swift_attribute | @swift_statements - -#keyset[swift_lambda_literal, index] -swift_lambda_literal_child( - int swift_lambda_literal: @swift_lambda_literal ref, - int index: int ref, - unique int child: @swift_lambda_literal_child_type ref -); - swift_lambda_literal_def( unique int id: @swift_lambda_literal ); @@ -1071,11 +1290,13 @@ swift_lambda_parameter_external_name( unique int external_name: @swift_token_simple_identifier ref ); -swift_lambda_parameter_name( +swift_lambda_parameter_modifiers( unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int name: @swift_token_simple_identifier ref + unique int modifiers: @swift_parameter_modifiers ref ); +@swift_lambda_parameter_name_type = @swift_token_self_expression | @swift_token_simple_identifier + @swift_lambda_parameter_type_type = @swift_implicitly_unwrapped_type | @swift_type__ swift_lambda_parameter_type( @@ -1083,15 +1304,9 @@ swift_lambda_parameter_type( unique int type__: @swift_lambda_parameter_type_type ref ); -@swift_lambda_parameter_child_type = @swift_parameter_modifiers | @swift_token_self_expression - -swift_lambda_parameter_child( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int child: @swift_lambda_parameter_child_type ref -); - swift_lambda_parameter_def( - unique int id: @swift_lambda_parameter + unique int id: @swift_lambda_parameter, + int name: @swift_lambda_parameter_name_type ref ); #keyset[swift_line_string_literal, index] @@ -1116,6 +1331,13 @@ swift_line_string_literal_def( @swift_local_declaration = @swift_class_declaration | @swift_function_declaration | @swift_property_declaration | @swift_typealias_declaration +#keyset[swift_macro_declaration, index] +swift_macro_declaration_attribute( + int swift_macro_declaration: @swift_macro_declaration ref, + int index: int ref, + unique int attribute: @swift_attribute ref +); + #keyset[swift_macro_declaration, index] swift_macro_declaration_default_value( int swift_macro_declaration: @swift_macro_declaration ref, @@ -1128,7 +1350,14 @@ swift_macro_declaration_definition( unique int definition: @swift_macro_definition ref ); -@swift_macro_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_token_simple_identifier | @swift_type_constraints | @swift_type_parameters | @swift_unannotated_type +#keyset[swift_macro_declaration, index] +swift_macro_declaration_parameter( + int swift_macro_declaration: @swift_macro_declaration ref, + int index: int ref, + unique int parameter: @swift_parameter ref +); + +@swift_macro_declaration_child_type = @swift_modifiers | @swift_token_simple_identifier | @swift_type_constraints | @swift_type_parameters | @swift_unannotated_type #keyset[swift_macro_declaration, index] swift_macro_declaration_child( @@ -1148,40 +1377,38 @@ swift_macro_definition_def( int body: @swift_macro_definition_body_type ref ); -@swift_macro_invocation_child_type = @swift_call_suffix | @swift_token_simple_identifier | @swift_type_parameters - -#keyset[swift_macro_invocation, index] -swift_macro_invocation_child( - int swift_macro_invocation: @swift_macro_invocation ref, - int index: int ref, - unique int child: @swift_macro_invocation_child_type ref +swift_macro_invocation_type_parameters( + unique int swift_macro_invocation: @swift_macro_invocation ref, + unique int type_parameters: @swift_type_parameters ref ); swift_macro_invocation_def( - unique int id: @swift_macro_invocation + unique int id: @swift_macro_invocation, + int name: @swift_token_simple_identifier ref, + int suffix: @swift_call_suffix ref ); swift_metatype_def( unique int id: @swift_metatype, - int child: @swift_unannotated_type ref + int name: @swift_unannotated_type ref ); -@swift_modifiers_child_type = @swift_attribute | @swift_token_function_modifier | @swift_token_inheritance_modifier | @swift_token_member_modifier | @swift_token_mutation_modifier | @swift_token_ownership_modifier | @swift_token_parameter_modifier | @swift_token_property_behavior_modifier | @swift_token_property_modifier | @swift_token_visibility_modifier +@swift_modifiers_modifier_type = @swift_attribute | @swift_token_function_modifier | @swift_token_inheritance_modifier | @swift_token_member_modifier | @swift_token_mutation_modifier | @swift_token_ownership_modifier | @swift_token_parameter_modifier | @swift_token_property_behavior_modifier | @swift_token_property_modifier | @swift_token_visibility_modifier #keyset[swift_modifiers, index] -swift_modifiers_child( +swift_modifiers_modifier( int swift_modifiers: @swift_modifiers ref, int index: int ref, - unique int child: @swift_modifiers_child_type ref + unique int modifier: @swift_modifiers_modifier_type ref ); swift_modifiers_def( unique int id: @swift_modifiers ); -swift_modify_specifier_child( +swift_modify_specifier_mutation( unique int swift_modify_specifier: @swift_modify_specifier ref, - unique int child: @swift_token_mutation_modifier ref + unique int mutation: @swift_token_mutation_modifier ref ); swift_modify_specifier_def( @@ -1243,17 +1470,16 @@ swift_navigation_suffix_def( int suffix: @swift_navigation_suffix_suffix_type ref ); -@swift_nested_type_identifier_child_type = @swift_token_simple_identifier | @swift_unannotated_type - #keyset[swift_nested_type_identifier, index] -swift_nested_type_identifier_child( +swift_nested_type_identifier_member( int swift_nested_type_identifier: @swift_nested_type_identifier ref, int index: int ref, - unique int child: @swift_nested_type_identifier_child_type ref + unique int member: @swift_token_simple_identifier ref ); swift_nested_type_identifier_def( - unique int id: @swift_nested_type_identifier + unique int id: @swift_nested_type_identifier, + int base: @swift_unannotated_type ref ); swift_nil_coalescing_expression_def( @@ -1264,7 +1490,7 @@ swift_nil_coalescing_expression_def( swift_opaque_type_def( unique int id: @swift_opaque_type, - int child: @swift_unannotated_type ref + int name: @swift_unannotated_type ref ); swift_open_end_range_expression_def( @@ -1277,22 +1503,32 @@ swift_open_start_range_expression_def( int end: @swift_expression ref ); -@swift_operator_declaration_child_type = @swift_deprecated_operator_declaration_body | @swift_referenceable_operator | @swift_token_simple_identifier +swift_operator_declaration_body( + unique int swift_operator_declaration: @swift_operator_declaration ref, + unique int body: @swift_deprecated_operator_declaration_body ref +); -#keyset[swift_operator_declaration, index] -swift_operator_declaration_child( - int swift_operator_declaration: @swift_operator_declaration ref, - int index: int ref, - unique int child: @swift_operator_declaration_child_type ref +case @swift_operator_declaration.kind of + 0 = @swift_operator_declaration_infix +| 1 = @swift_operator_declaration_postfix +| 2 = @swift_operator_declaration_prefix +; + + +swift_operator_declaration_precedence_group( + unique int swift_operator_declaration: @swift_operator_declaration ref, + unique int precedence_group: @swift_token_simple_identifier ref ); swift_operator_declaration_def( - unique int id: @swift_operator_declaration + unique int id: @swift_operator_declaration, + int kind: int ref, + int name: @swift_referenceable_operator ref ); swift_optional_chain_marker_def( unique int id: @swift_optional_chain_marker, - int child: @swift_expression ref + int expr: @swift_expression ref ); @swift_optional_type_wrapped_type = @swift_array_type | @swift_dictionary_type | @swift_tuple_type | @swift_user_type @@ -1307,13 +1543,13 @@ swift_parameter_external_name( unique int external_name: @swift_token_simple_identifier ref ); -@swift_parameter_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_parameter_child( +swift_parameter_modifiers( unique int swift_parameter: @swift_parameter ref, - unique int child: @swift_parameter_modifiers ref + unique int modifiers: @swift_parameter_modifiers ref ); +@swift_parameter_type_type = @swift_implicitly_unwrapped_type | @swift_type__ + swift_parameter_def( unique int id: @swift_parameter, int name: @swift_token_simple_identifier ref, @@ -1321,10 +1557,10 @@ swift_parameter_def( ); #keyset[swift_parameter_modifiers, index] -swift_parameter_modifiers_child( +swift_parameter_modifiers_modifier( int swift_parameter_modifiers: @swift_parameter_modifiers ref, int index: int ref, - unique int child: @swift_token_parameter_modifier ref + unique int modifier: @swift_token_parameter_modifier ref ); swift_parameter_modifiers_def( @@ -1350,10 +1586,17 @@ swift_pattern_def( ); #keyset[swift_playground_literal, index] -swift_playground_literal_child( +swift_playground_literal_name( int swift_playground_literal: @swift_playground_literal ref, int index: int ref, - unique int child: @swift_expression ref + unique int name: @swift_token_simple_identifier ref +); + +#keyset[swift_playground_literal, index] +swift_playground_literal_value( + int swift_playground_literal: @swift_playground_literal ref, + int index: int ref, + unique int value: @swift_expression ref ); swift_playground_literal_def( @@ -1368,41 +1611,33 @@ swift_postfix_expression_def( int target: @swift_expression ref ); -@swift_precedence_group_attribute_child_type = @swift_token_boolean_literal | @swift_token_simple_identifier - -#keyset[swift_precedence_group_attribute, index] -swift_precedence_group_attribute_child( - int swift_precedence_group_attribute: @swift_precedence_group_attribute ref, - int index: int ref, - unique int child: @swift_precedence_group_attribute_child_type ref -); +@swift_precedence_group_attribute_value_type = @swift_token_boolean_literal | @swift_token_simple_identifier swift_precedence_group_attribute_def( - unique int id: @swift_precedence_group_attribute + unique int id: @swift_precedence_group_attribute, + int name: @swift_token_simple_identifier ref, + int value: @swift_precedence_group_attribute_value_type ref ); #keyset[swift_precedence_group_attributes, index] -swift_precedence_group_attributes_child( +swift_precedence_group_attributes_attribute( int swift_precedence_group_attributes: @swift_precedence_group_attributes ref, int index: int ref, - unique int child: @swift_precedence_group_attribute ref + unique int attribute: @swift_precedence_group_attribute ref ); swift_precedence_group_attributes_def( unique int id: @swift_precedence_group_attributes ); -@swift_precedence_group_declaration_child_type = @swift_precedence_group_attributes | @swift_token_simple_identifier - -#keyset[swift_precedence_group_declaration, index] -swift_precedence_group_declaration_child( - int swift_precedence_group_declaration: @swift_precedence_group_declaration ref, - int index: int ref, - unique int child: @swift_precedence_group_declaration_child_type ref +swift_precedence_group_declaration_attributes( + unique int swift_precedence_group_declaration: @swift_precedence_group_declaration ref, + unique int attributes: @swift_precedence_group_attributes ref ); swift_precedence_group_declaration_def( - unique int id: @swift_precedence_group_declaration + unique int id: @swift_precedence_group_declaration, + int name: @swift_token_simple_identifier ref ); @swift_prefix_expression_operation_type = @swift_reserved_word | @swift_token_bang | @swift_token_custom_operator @@ -1420,6 +1655,15 @@ swift_property_declaration_computed_value( unique int computed_value: @swift_computed_property ref ); +@swift_property_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier + +#keyset[swift_property_declaration, index] +swift_property_declaration_modifiers( + int swift_property_declaration: @swift_property_declaration ref, + int index: int ref, + unique int modifiers: @swift_property_declaration_modifiers_type ref +); + #keyset[swift_property_declaration, index] swift_property_declaration_name( int swift_property_declaration: @swift_property_declaration ref, @@ -1434,7 +1678,7 @@ swift_property_declaration_value( unique int value: @swift_expression ref ); -@swift_property_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_type_annotation | @swift_type_constraints | @swift_value_binding_pattern | @swift_willset_didset_block +@swift_property_declaration_child_type = @swift_type_annotation | @swift_type_constraints | @swift_value_binding_pattern | @swift_willset_didset_block #keyset[swift_property_declaration, index] swift_property_declaration_child( @@ -1459,28 +1703,48 @@ swift_protocol_body_def( ); #keyset[swift_protocol_composition_type, index] -swift_protocol_composition_type_child( +swift_protocol_composition_type_type( int swift_protocol_composition_type: @swift_protocol_composition_type ref, int index: int ref, - unique int child: @swift_unannotated_type ref + unique int type__: @swift_unannotated_type ref ); swift_protocol_composition_type_def( unique int id: @swift_protocol_composition_type ); +#keyset[swift_protocol_declaration, index] +swift_protocol_declaration_attribute( + int swift_protocol_declaration: @swift_protocol_declaration ref, + int index: int ref, + unique int attribute: @swift_attribute ref +); + case @swift_protocol_declaration.declaration_kind of 0 = @swift_protocol_declaration_protocol ; -@swift_protocol_declaration_child_type = @swift_attribute | @swift_inheritance_specifier | @swift_modifiers | @swift_type_constraints | @swift_type_parameters +swift_protocol_declaration_modifiers( + unique int swift_protocol_declaration: @swift_protocol_declaration ref, + unique int modifiers: @swift_modifiers ref +); + +swift_protocol_declaration_type_constraints( + unique int swift_protocol_declaration: @swift_protocol_declaration ref, + unique int type_constraints: @swift_type_constraints ref +); + +swift_protocol_declaration_type_parameters( + unique int swift_protocol_declaration: @swift_protocol_declaration ref, + unique int type_parameters: @swift_type_parameters ref +); #keyset[swift_protocol_declaration, index] swift_protocol_declaration_child( int swift_protocol_declaration: @swift_protocol_declaration ref, int index: int ref, - unique int child: @swift_protocol_declaration_child_type ref + unique int child: @swift_inheritance_specifier ref ); swift_protocol_declaration_def( @@ -1490,6 +1754,18 @@ swift_protocol_declaration_def( int name: @swift_token_type_identifier ref ); +swift_protocol_function_declaration_async( + unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, + unique int async: @swift_token_async_keyword ref +); + +#keyset[swift_protocol_function_declaration, index] +swift_protocol_function_declaration_attribute( + int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, + int index: int ref, + unique int attribute: @swift_attribute ref +); + swift_protocol_function_declaration_body( unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, unique int body: @swift_function_body ref @@ -1502,8 +1778,20 @@ swift_protocol_function_declaration_default_value( unique int default_value: @swift_expression ref ); +swift_protocol_function_declaration_modifiers( + unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, + unique int modifiers: @swift_modifiers ref +); + @swift_protocol_function_declaration_name_type = @swift_referenceable_operator | @swift_token_simple_identifier +#keyset[swift_protocol_function_declaration, index] +swift_protocol_function_declaration_parameter( + int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, + int index: int ref, + unique int parameter: @swift_parameter ref +); + @swift_protocol_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ swift_protocol_function_declaration_return_type( @@ -1511,13 +1799,21 @@ swift_protocol_function_declaration_return_type( unique int return_type: @swift_protocol_function_declaration_return_type_type ref ); -@swift_protocol_function_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_throws_clause | @swift_token_throws | @swift_type_constraints | @swift_type_parameters +@swift_protocol_function_declaration_throws_type = @swift_throws_clause | @swift_token_throws -#keyset[swift_protocol_function_declaration, index] -swift_protocol_function_declaration_child( - int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - int index: int ref, - unique int child: @swift_protocol_function_declaration_child_type ref +swift_protocol_function_declaration_throws( + unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, + unique int throws: @swift_protocol_function_declaration_throws_type ref +); + +swift_protocol_function_declaration_type_constraints( + unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, + unique int type_constraints: @swift_type_constraints ref +); + +swift_protocol_function_declaration_type_parameters( + unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, + unique int type_parameters: @swift_type_parameters ref ); swift_protocol_function_declaration_def( @@ -1527,27 +1823,34 @@ swift_protocol_function_declaration_def( @swift_protocol_member_declaration = @swift_associatedtype_declaration | @swift_deinit_declaration | @swift_init_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_subscript_declaration | @swift_typealias_declaration -@swift_protocol_property_declaration_child_type = @swift_modifiers | @swift_protocol_property_requirements | @swift_type_annotation | @swift_type_constraints +swift_protocol_property_declaration_modifiers( + unique int swift_protocol_property_declaration: @swift_protocol_property_declaration ref, + unique int modifiers: @swift_modifiers ref +); -#keyset[swift_protocol_property_declaration, index] -swift_protocol_property_declaration_child( - int swift_protocol_property_declaration: @swift_protocol_property_declaration ref, - int index: int ref, - unique int child: @swift_protocol_property_declaration_child_type ref +swift_protocol_property_declaration_type( + unique int swift_protocol_property_declaration: @swift_protocol_property_declaration ref, + unique int type__: @swift_type_annotation ref +); + +swift_protocol_property_declaration_type_constraints( + unique int swift_protocol_property_declaration: @swift_protocol_property_declaration ref, + unique int type_constraints: @swift_type_constraints ref ); swift_protocol_property_declaration_def( unique int id: @swift_protocol_property_declaration, - int name: @swift_pattern ref + int name: @swift_pattern ref, + int requirements: @swift_protocol_property_requirements ref ); -@swift_protocol_property_requirements_child_type = @swift_getter_specifier | @swift_setter_specifier +@swift_protocol_property_requirements_accessor_type = @swift_getter_specifier | @swift_setter_specifier #keyset[swift_protocol_property_requirements, index] -swift_protocol_property_requirements_child( +swift_protocol_property_requirements_accessor( int swift_protocol_property_requirements: @swift_protocol_property_requirements ref, int index: int ref, - unique int child: @swift_protocol_property_requirements_child_type ref + unique int accessor: @swift_protocol_property_requirements_accessor_type ref ); swift_protocol_property_requirements_def( @@ -1576,7 +1879,14 @@ swift_raw_str_interpolation_interpolation( swift_raw_str_interpolation_def( unique int id: @swift_raw_str_interpolation, - int child: @swift_token_raw_str_interpolation_start ref + int start: @swift_token_raw_str_interpolation_start ref +); + +#keyset[swift_raw_string_literal, index] +swift_raw_string_literal_continuing( + int swift_raw_string_literal: @swift_raw_string_literal ref, + int index: int ref, + unique int continuing: @swift_token_raw_str_continuing_indicator ref ); #keyset[swift_raw_string_literal, index] @@ -1595,26 +1905,20 @@ swift_raw_string_literal_text( unique int text: @swift_raw_string_literal_text_type ref ); -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_child( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int child: @swift_token_raw_str_continuing_indicator ref -); - swift_raw_string_literal_def( unique int id: @swift_raw_string_literal ); -@swift_referenceable_operator_child_type = @swift_token_bang | @swift_token_custom_operator - -swift_referenceable_operator_child( - unique int swift_referenceable_operator: @swift_referenceable_operator ref, - unique int child: @swift_referenceable_operator_child_type ref -); +@swift_referenceable_operator_operator_type = @swift_reserved_word | @swift_token_bang | @swift_token_custom_operator swift_referenceable_operator_def( - unique int id: @swift_referenceable_operator + unique int id: @swift_referenceable_operator, + int operator: @swift_referenceable_operator_operator_type ref +); + +swift_repeat_while_statement_body( + unique int swift_repeat_while_statement: @swift_repeat_while_statement ref, + unique int body: @swift_statements ref ); #keyset[swift_repeat_while_statement, index] @@ -1624,23 +1928,18 @@ swift_repeat_while_statement_condition( unique int condition: @swift_if_condition ref ); -swift_repeat_while_statement_child( - unique int swift_repeat_while_statement: @swift_repeat_while_statement ref, - unique int child: @swift_statements ref -); - swift_repeat_while_statement_def( unique int id: @swift_repeat_while_statement ); swift_selector_expression_def( unique int id: @swift_selector_expression, - int child: @swift_expression ref + int expr: @swift_expression ref ); -swift_setter_specifier_child( +swift_setter_specifier_mutation( unique int swift_setter_specifier: @swift_setter_specifier ref, - unique int child: @swift_token_mutation_modifier ref + unique int mutation: @swift_token_mutation_modifier ref ); swift_setter_specifier_def( @@ -1678,6 +1977,13 @@ swift_statements_def( unique int id: @swift_statements ); +#keyset[swift_subscript_declaration, index] +swift_subscript_declaration_attribute( + int swift_subscript_declaration: @swift_subscript_declaration ref, + int index: int ref, + unique int attribute: @swift_attribute ref +); + #keyset[swift_subscript_declaration, index] swift_subscript_declaration_default_value( int swift_subscript_declaration: @swift_subscript_declaration ref, @@ -1685,6 +1991,18 @@ swift_subscript_declaration_default_value( unique int default_value: @swift_expression ref ); +swift_subscript_declaration_modifiers( + unique int swift_subscript_declaration: @swift_subscript_declaration ref, + unique int modifiers: @swift_modifiers ref +); + +#keyset[swift_subscript_declaration, index] +swift_subscript_declaration_parameter( + int swift_subscript_declaration: @swift_subscript_declaration ref, + int index: int ref, + unique int parameter: @swift_parameter ref +); + @swift_subscript_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ swift_subscript_declaration_return_type( @@ -1692,17 +2010,19 @@ swift_subscript_declaration_return_type( unique int return_type: @swift_subscript_declaration_return_type_type ref ); -@swift_subscript_declaration_child_type = @swift_attribute | @swift_computed_property | @swift_modifiers | @swift_parameter | @swift_type_constraints | @swift_type_parameters +swift_subscript_declaration_type_constraints( + unique int swift_subscript_declaration: @swift_subscript_declaration ref, + unique int type_constraints: @swift_type_constraints ref +); -#keyset[swift_subscript_declaration, index] -swift_subscript_declaration_child( - int swift_subscript_declaration: @swift_subscript_declaration ref, - int index: int ref, - unique int child: @swift_subscript_declaration_child_type ref +swift_subscript_declaration_type_parameters( + unique int swift_subscript_declaration: @swift_subscript_declaration ref, + unique int type_parameters: @swift_type_parameters ref ); swift_subscript_declaration_def( - unique int id: @swift_subscript_declaration + unique int id: @swift_subscript_declaration, + int body: @swift_computed_property ref ); swift_suppressed_constraint_def( @@ -1729,10 +2049,10 @@ swift_switch_pattern_def( ); #keyset[swift_switch_statement, index] -swift_switch_statement_child( +swift_switch_statement_entry( int swift_switch_statement: @swift_switch_statement ref, int index: int ref, - unique int child: @swift_switch_entry ref + unique int entry: @swift_switch_entry ref ); swift_switch_statement_def( @@ -1755,7 +2075,7 @@ swift_throws_clause_def( swift_try_expression_def( unique int id: @swift_try_expression, int expr: @swift_expression ref, - int child: @swift_token_try_operator ref + int operator: @swift_token_try_operator ref ); #keyset[swift_tuple_expression, index] @@ -1792,6 +2112,11 @@ swift_tuple_type_def( unique int id: @swift_tuple_type ); +swift_tuple_type_item_modifiers( + unique int swift_tuple_type_item: @swift_tuple_type_item ref, + unique int modifiers: @swift_parameter_modifiers ref +); + swift_tuple_type_item_name( unique int swift_tuple_type_item: @swift_tuple_type_item ref, unique int name: @swift_token_simple_identifier ref @@ -1802,12 +2127,10 @@ swift_tuple_type_item_type( unique int type__: @swift_type__ ref ); -@swift_tuple_type_item_child_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type | @swift_parameter_modifiers | @swift_token_wildcard_pattern +@swift_tuple_type_item_child_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type | @swift_token_wildcard_pattern -#keyset[swift_tuple_type_item, index] swift_tuple_type_item_child( - int swift_tuple_type_item: @swift_tuple_type_item ref, - int index: int ref, + unique int swift_tuple_type_item: @swift_tuple_type_item ref, unique int child: @swift_tuple_type_item_child_type ref ); @@ -1833,43 +2156,42 @@ swift_type_annotation_def( ); #keyset[swift_type_arguments, index] -swift_type_arguments_child( +swift_type_arguments_argument( int swift_type_arguments: @swift_type_arguments ref, int index: int ref, - unique int child: @swift_type__ ref + unique int argument: @swift_type__ ref ); swift_type_arguments_def( unique int id: @swift_type_arguments ); -@swift_type_constraint_child_type = @swift_equality_constraint | @swift_inheritance_constraint +@swift_type_constraint_constraint_type = @swift_equality_constraint | @swift_inheritance_constraint swift_type_constraint_def( unique int id: @swift_type_constraint, - int child: @swift_type_constraint_child_type ref + int constraint: @swift_type_constraint_constraint_type ref ); -@swift_type_constraints_child_type = @swift_token_where_keyword | @swift_type_constraint - #keyset[swift_type_constraints, index] -swift_type_constraints_child( +swift_type_constraints_constraint( int swift_type_constraints: @swift_type_constraints ref, int index: int ref, - unique int child: @swift_type_constraints_child_type ref + unique int constraint: @swift_type_constraint ref ); swift_type_constraints_def( - unique int id: @swift_type_constraints + unique int id: @swift_type_constraints, + int keyword: @swift_token_where_keyword ref ); @swift_type_level_declaration = @swift_associatedtype_declaration | @swift_class_declaration | @swift_deinit_declaration | @swift_function_declaration | @swift_import_declaration | @swift_init_declaration | @swift_operator_declaration | @swift_precedence_group_declaration | @swift_property_declaration | @swift_protocol_declaration | @swift_subscript_declaration | @swift_typealias_declaration #keyset[swift_type_modifiers, index] -swift_type_modifiers_child( +swift_type_modifiers_attribute( int swift_type_modifiers: @swift_type_modifiers ref, int index: int ref, - unique int child: @swift_attribute ref + unique int attribute: @swift_attribute ref ); swift_type_modifiers_def( @@ -1878,27 +2200,31 @@ swift_type_modifiers_def( swift_type_pack_expansion_def( unique int id: @swift_type_pack_expansion, - int child: @swift_unannotated_type ref + int name: @swift_unannotated_type ref ); -@swift_type_parameter_child_type = @swift_token_type_identifier | @swift_type__ | @swift_type_parameter_modifiers | @swift_type_parameter_pack +swift_type_parameter_modifiers( + unique int swift_type_parameter: @swift_type_parameter ref, + unique int modifiers: @swift_type_parameter_modifiers ref +); -#keyset[swift_type_parameter, index] -swift_type_parameter_child( - int swift_type_parameter: @swift_type_parameter ref, - int index: int ref, - unique int child: @swift_type_parameter_child_type ref +@swift_type_parameter_name_type = @swift_token_type_identifier | @swift_type_parameter_pack + +swift_type_parameter_type( + unique int swift_type_parameter: @swift_type_parameter ref, + unique int type__: @swift_type__ ref ); swift_type_parameter_def( - unique int id: @swift_type_parameter + unique int id: @swift_type_parameter, + int name: @swift_type_parameter_name_type ref ); #keyset[swift_type_parameter_modifiers, index] -swift_type_parameter_modifiers_child( +swift_type_parameter_modifiers_attribute( int swift_type_parameter_modifiers: @swift_type_parameter_modifiers ref, int index: int ref, - unique int child: @swift_attribute ref + unique int attribute: @swift_attribute ref ); swift_type_parameter_modifiers_def( @@ -1907,29 +2233,37 @@ swift_type_parameter_modifiers_def( swift_type_parameter_pack_def( unique int id: @swift_type_parameter_pack, - int child: @swift_unannotated_type ref + int name: @swift_unannotated_type ref ); -@swift_type_parameters_child_type = @swift_type_constraints | @swift_type_parameter +swift_type_parameters_constraints( + unique int swift_type_parameters: @swift_type_parameters ref, + unique int constraints: @swift_type_constraints ref +); #keyset[swift_type_parameters, index] -swift_type_parameters_child( +swift_type_parameters_parameter( int swift_type_parameters: @swift_type_parameters ref, int index: int ref, - unique int child: @swift_type_parameters_child_type ref + unique int parameter: @swift_type_parameter ref ); swift_type_parameters_def( unique int id: @swift_type_parameters ); -@swift_typealias_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_type_parameters +@swift_typealias_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier #keyset[swift_typealias_declaration, index] -swift_typealias_declaration_child( +swift_typealias_declaration_modifiers( int swift_typealias_declaration: @swift_typealias_declaration ref, int index: int ref, - unique int child: @swift_typealias_declaration_child_type ref + unique int modifiers: @swift_typealias_declaration_modifiers_type ref +); + +swift_typealias_declaration_type_parameters( + unique int swift_typealias_declaration: @swift_typealias_declaration ref, + unique int type_parameters: @swift_type_parameters ref ); swift_typealias_declaration_def( @@ -1940,13 +2274,13 @@ swift_typealias_declaration_def( @swift_unannotated_type = @swift_array_type | @swift_dictionary_type | @swift_existential_type | @swift_function_type | @swift_metatype | @swift_opaque_type | @swift_optional_type | @swift_protocol_composition_type | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type -@swift_user_type_child_type = @swift_token_type_identifier | @swift_type_arguments +@swift_user_type_part_type = @swift_token_type_identifier | @swift_type_arguments #keyset[swift_user_type, index] -swift_user_type_child( +swift_user_type_part( int swift_user_type: @swift_user_type ref, int index: int ref, - unique int child: @swift_user_type_child_type ref + unique int part: @swift_user_type_part_type ref ); swift_user_type_def( @@ -1965,16 +2299,16 @@ swift_value_argument_reference_specifier( unique int reference_specifier: @swift_value_argument_label ref ); +swift_value_argument_type_modifiers( + unique int swift_value_argument: @swift_value_argument ref, + unique int type_modifiers: @swift_type_modifiers ref +); + swift_value_argument_value( unique int swift_value_argument: @swift_value_argument ref, unique int value: @swift_expression ref ); -swift_value_argument_child( - unique int swift_value_argument: @swift_value_argument ref, - unique int child: @swift_type_modifiers ref -); - swift_value_argument_def( unique int id: @swift_value_argument ); @@ -1985,10 +2319,10 @@ swift_value_argument_label_def( ); #keyset[swift_value_arguments, index] -swift_value_arguments_child( +swift_value_arguments_argument( int swift_value_arguments: @swift_value_arguments ref, int index: int ref, - unique int child: @swift_value_argument ref + unique int argument: @swift_value_argument ref ); swift_value_arguments_def( @@ -2008,25 +2342,23 @@ swift_value_binding_pattern_def( swift_value_pack_expansion_def( unique int id: @swift_value_pack_expansion, - int child: @swift_expression ref + int expr: @swift_expression ref ); swift_value_parameter_pack_def( unique int id: @swift_value_parameter_pack, - int child: @swift_expression ref -); - -@swift_where_clause_child_type = @swift_expression | @swift_token_where_keyword - -#keyset[swift_where_clause, index] -swift_where_clause_child( - int swift_where_clause: @swift_where_clause ref, - int index: int ref, - unique int child: @swift_where_clause_child_type ref + int expr: @swift_expression ref ); swift_where_clause_def( - unique int id: @swift_where_clause + unique int id: @swift_where_clause, + int expr: @swift_expression ref, + int keyword: @swift_token_where_keyword ref +); + +swift_while_statement_body( + unique int swift_while_statement: @swift_while_statement ref, + unique int body: @swift_statements ref ); #keyset[swift_while_statement, index] @@ -2036,35 +2368,37 @@ swift_while_statement_condition( unique int condition: @swift_if_condition ref ); -swift_while_statement_child( - unique int swift_while_statement: @swift_while_statement ref, - unique int child: @swift_statements ref -); - swift_while_statement_def( unique int id: @swift_while_statement ); -@swift_willset_clause_child_type = @swift_modifiers | @swift_statements | @swift_token_simple_identifier +swift_willset_clause_body( + unique int swift_willset_clause: @swift_willset_clause ref, + unique int body: @swift_statements ref +); -#keyset[swift_willset_clause, index] -swift_willset_clause_child( - int swift_willset_clause: @swift_willset_clause ref, - int index: int ref, - unique int child: @swift_willset_clause_child_type ref +swift_willset_clause_modifiers( + unique int swift_willset_clause: @swift_willset_clause ref, + unique int modifiers: @swift_modifiers ref +); + +swift_willset_clause_parameter( + unique int swift_willset_clause: @swift_willset_clause ref, + unique int parameter: @swift_token_simple_identifier ref ); swift_willset_clause_def( unique int id: @swift_willset_clause ); -@swift_willset_didset_block_child_type = @swift_didset_clause | @swift_willset_clause +swift_willset_didset_block_didset( + unique int swift_willset_didset_block: @swift_willset_didset_block ref, + unique int didset: @swift_didset_clause ref +); -#keyset[swift_willset_didset_block, index] -swift_willset_didset_block_child( - int swift_willset_didset_block: @swift_willset_didset_block ref, - int index: int ref, - unique int child: @swift_willset_didset_block_child_type ref +swift_willset_didset_block_willset( + unique int swift_willset_didset_block: @swift_willset_didset_block ref, + unique int willset: @swift_willset_clause ref ); swift_willset_didset_block_def( @@ -2080,50 +2414,51 @@ swift_tokeninfo( case @swift_token.kind of 0 = @swift_reserved_word | 1 = @swift_token_as_operator -| 2 = @swift_token_bang -| 3 = @swift_token_bin_literal -| 4 = @swift_token_boolean_literal -| 5 = @swift_token_catch_keyword -| 6 = @swift_token_comment -| 7 = @swift_token_custom_operator -| 8 = @swift_token_default_keyword -| 9 = @swift_token_diagnostic -| 10 = @swift_token_else -| 11 = @swift_token_fully_open_range -| 12 = @swift_token_function_modifier -| 13 = @swift_token_hex_literal -| 14 = @swift_token_inheritance_modifier -| 15 = @swift_token_integer_literal -| 16 = @swift_token_line_str_text -| 17 = @swift_token_member_modifier -| 18 = @swift_token_multi_line_str_text -| 19 = @swift_token_multiline_comment -| 20 = @swift_token_mutation_modifier -| 21 = @swift_token_oct_literal -| 22 = @swift_token_ownership_modifier -| 23 = @swift_token_parameter_modifier -| 24 = @swift_token_property_behavior_modifier -| 25 = @swift_token_property_modifier -| 26 = @swift_token_raw_str_continuing_indicator -| 27 = @swift_token_raw_str_end_part -| 28 = @swift_token_raw_str_interpolation_start -| 29 = @swift_token_raw_str_part -| 30 = @swift_token_real_literal -| 31 = @swift_token_regex_literal -| 32 = @swift_token_self_expression -| 33 = @swift_token_shebang_line -| 34 = @swift_token_simple_identifier -| 35 = @swift_token_special_literal -| 36 = @swift_token_statement_label -| 37 = @swift_token_str_escaped_char -| 38 = @swift_token_super_expression -| 39 = @swift_token_throw_keyword -| 40 = @swift_token_throws -| 41 = @swift_token_try_operator -| 42 = @swift_token_type_identifier -| 43 = @swift_token_visibility_modifier -| 44 = @swift_token_where_keyword -| 45 = @swift_token_wildcard_pattern +| 2 = @swift_token_async_keyword +| 3 = @swift_token_bang +| 4 = @swift_token_bin_literal +| 5 = @swift_token_boolean_literal +| 6 = @swift_token_catch_keyword +| 7 = @swift_token_comment +| 8 = @swift_token_custom_operator +| 9 = @swift_token_default_keyword +| 10 = @swift_token_diagnostic +| 11 = @swift_token_else +| 12 = @swift_token_fully_open_range +| 13 = @swift_token_function_modifier +| 14 = @swift_token_hex_literal +| 15 = @swift_token_inheritance_modifier +| 16 = @swift_token_integer_literal +| 17 = @swift_token_line_str_text +| 18 = @swift_token_member_modifier +| 19 = @swift_token_multi_line_str_text +| 20 = @swift_token_multiline_comment +| 21 = @swift_token_mutation_modifier +| 22 = @swift_token_oct_literal +| 23 = @swift_token_ownership_modifier +| 24 = @swift_token_parameter_modifier +| 25 = @swift_token_property_behavior_modifier +| 26 = @swift_token_property_modifier +| 27 = @swift_token_raw_str_continuing_indicator +| 28 = @swift_token_raw_str_end_part +| 29 = @swift_token_raw_str_interpolation_start +| 30 = @swift_token_raw_str_part +| 31 = @swift_token_real_literal +| 32 = @swift_token_regex_literal +| 33 = @swift_token_self_expression +| 34 = @swift_token_shebang_line +| 35 = @swift_token_simple_identifier +| 36 = @swift_token_special_literal +| 37 = @swift_token_statement_label +| 38 = @swift_token_str_escaped_char +| 39 = @swift_token_super_expression +| 40 = @swift_token_throw_keyword +| 41 = @swift_token_throws +| 42 = @swift_token_try_operator +| 43 = @swift_token_type_identifier +| 44 = @swift_token_visibility_modifier +| 45 = @swift_token_where_keyword +| 46 = @swift_token_wildcard_pattern ; From 732cc7bee00d734bd07d5cad8cadc9b56c2ba584 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:07:58 +0000 Subject: [PATCH 028/226] unified: Add fields to inheritance specifiers and calls --- unified/extractor/tree-sitter-swift/grammar.js | 6 +++--- unified/extractor/tree-sitter-swift/node-types.yml | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 9137fb94cee..89310ec2edc 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -877,8 +877,8 @@ module.exports = grammar({ ), expr_hack_at_ternary_binary_call: ($) => seq( - $.expression, - alias($.expr_hack_at_ternary_binary_call_suffix, $.call_suffix) + field("function", $.expression), + field("suffix", alias($.expr_hack_at_ternary_binary_call_suffix, $.call_suffix)) ), expr_hack_at_ternary_binary_call_suffix: ($) => prec(PRECS.call_suffix, $.value_arguments), @@ -1551,7 +1551,7 @@ module.exports = grammar({ _inheritance_specifiers: ($) => prec.left(sep1($._annotated_inheritance_specifier, choice(",", "&"))), _annotated_inheritance_specifier: ($) => - seq(repeat(field("attribute", $.attribute)), $.inheritance_specifier), + seq(repeat(field("attribute", $.attribute)), field("inherits", $.inheritance_specifier)), inheritance_specifier: ($) => prec.left( field( diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 4d4faf641d1..17a3843ebbe 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -154,9 +154,8 @@ named: rhs: expression boolean_literal: call_expression: - $children*: [call_suffix, expression] - function?: expression - suffix?: call_suffix + function: expression + suffix: call_suffix call_suffix: $children+: [lambda_literal, value_arguments] name*: simple_identifier @@ -180,10 +179,10 @@ named: $children*: multiline_comment member*: type_level_declaration class_declaration: - $children*: inheritance_specifier attribute*: attribute body: [class_body, enum_class_body] declaration_kind: ["actor", "class", "enum", "extension", "struct"] + inherits*: inheritance_specifier modifiers*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier] name: [type_identifier, unannotated_type] type_constraints?: type_constraints @@ -481,10 +480,10 @@ named: protocol_composition_type: type+: unannotated_type protocol_declaration: - $children*: inheritance_specifier attribute*: attribute body: protocol_body declaration_kind: "protocol" + inherits*: inheritance_specifier modifiers?: modifiers name: type_identifier type_constraints?: type_constraints From 0499932ba0c037ca8a7b315a2163c73d3600fe2b Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:10:38 +0000 Subject: [PATCH 029/226] unified: Fix fields in await_expression This required a change in a different place, due to aliasing. --- unified/extractor/tree-sitter-swift/grammar.js | 2 +- unified/extractor/tree-sitter-swift/node-types.yml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 89310ec2edc..5ee1d8460aa 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1237,7 +1237,7 @@ module.exports = grammar({ // // To fix that, we simply undo the special casing by defining our own `await_expression`. choice($.expression, alias($.for_statement_await, $.await_expression)), - for_statement_await: ($) => seq($._await_operator, $.expression), + for_statement_await: ($) => seq($._await_operator, field("expr", $.expression)), while_statement: ($) => prec( diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 17a3843ebbe..7877106ad52 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -144,8 +144,7 @@ named: availability_condition: $children*: [identifier, integer_literal] await_expression: - $children?: expression - expr?: expression + expr: expression bang: bin_literal: bitwise_operation: From 15d84b3e532473978cf4a24e7bd3d9615096a1a5 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:15:36 +0000 Subject: [PATCH 030/226] unified: More $children fixes Some nodes with a single child (arguably redundant to do, but I think it's nice to have the types be consistent), and also an instance of ensuring that all branches of a `choice` expose consistent field names. --- unified/extractor/tree-sitter-swift/grammar.js | 8 ++++---- unified/extractor/tree-sitter-swift/node-types.yml | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 5ee1d8460aa..7413ab5a3b2 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -452,7 +452,7 @@ module.exports = grammar({ optional(sep1Opt(field("element", $.tuple_type_item), ",")), ")" ), - alias($._parenthesized_type, $.tuple_type_item) + field("element", alias($._parenthesized_type, $.tuple_type_item)) ), tuple_type_item: ($) => prec( @@ -791,13 +791,13 @@ module.exports = grammar({ ), value_argument_label: ($) => prec.left( - choice( + field("name", choice( $.simple_identifier, // We don't rely on $._contextual_simple_identifier here because // these don't usually fall into that category. alias("if", $.simple_identifier), alias("switch", $.simple_identifier) - ) + )) ), value_argument: ($) => prec.left( @@ -1094,7 +1094,7 @@ module.exports = grammar({ $.statements, optional("fallthrough") ), - switch_pattern: ($) => alias($._binding_pattern_with_expr, $.pattern), + switch_pattern: ($) => field("pattern", alias($._binding_pattern_with_expr, $.pattern)), do_statement: ($) => prec.right(PRECS["do"], seq("do", $._block, repeat(field("catch", $.catch_block)))), catch_block: ($) => diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 7877106ad52..276bcef03ea 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -559,7 +559,7 @@ named: switch_entry: $children+: [default_keyword, expression, modifiers, statements, switch_pattern, where_keyword] switch_pattern: - $children: pattern + pattern: pattern switch_statement: entry*: switch_entry expr: expression @@ -579,7 +579,6 @@ named: name*: simple_identifier value+: expression tuple_type: - $children?: tuple_type_item element*: tuple_type_item tuple_type_item: $children?: [dictionary_type, existential_type, opaque_type, wildcard_pattern] @@ -627,7 +626,7 @@ named: type_modifiers?: type_modifiers value?: expression value_argument_label: - $children: simple_identifier + name: simple_identifier value_arguments: argument*: value_argument value_binding_pattern: From bc96ae6e475671cbeb9c8ce159cc568f55d9008e Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:29:23 +0000 Subject: [PATCH 031/226] unified: Add `lambda` and `arguments` fields --- unified/extractor/tree-sitter-swift/grammar.js | 12 ++++++------ unified/extractor/tree-sitter-swift/node-types.yml | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 7413ab5a3b2..1518df0e3dd 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -760,19 +760,19 @@ module.exports = grammar({ prec( PRECS.call_suffix, choice( - $.value_arguments, + field("arguments", $.value_arguments), prec.dynamic(-1, $._fn_call_lambda_arguments), // Prefer to treat `foo() { }` as one call not two - seq($.value_arguments, $._fn_call_lambda_arguments) + seq(field("arguments", $.value_arguments), $._fn_call_lambda_arguments) ) ), constructor_suffix: ($) => prec( PRECS.call_suffix, choice( - alias($._constructor_value_arguments, $.value_arguments), + field("arguments", alias($._constructor_value_arguments, $.value_arguments)), prec.dynamic(-1, $._fn_call_lambda_arguments), // As above seq( - alias($._constructor_value_arguments, $.value_arguments), + field("arguments", alias($._constructor_value_arguments, $.value_arguments)), $._fn_call_lambda_arguments ) ) @@ -780,7 +780,7 @@ module.exports = grammar({ _constructor_value_arguments: ($) => seq("(", optional(sep1Opt(field("argument", $.value_argument), ",")), ")"), _fn_call_lambda_arguments: ($) => - sep1($.lambda_literal, seq(field("name", $.simple_identifier), ":")), + sep1(field("lambda", $.lambda_literal), seq(field("name", $.simple_identifier), ":")), type_arguments: ($) => prec.left(seq("<", sep1Opt(field("argument", $.type), ","), ">")), value_arguments: ($) => seq( @@ -881,7 +881,7 @@ module.exports = grammar({ field("suffix", alias($.expr_hack_at_ternary_binary_call_suffix, $.call_suffix)) ), expr_hack_at_ternary_binary_call_suffix: ($) => - prec(PRECS.call_suffix, $.value_arguments), + prec(PRECS.call_suffix, field("arguments", $.value_arguments)), call_expression: ($) => prec( PRECS.call, diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 276bcef03ea..b3ac84362bf 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -156,7 +156,8 @@ named: function: expression suffix: call_suffix call_suffix: - $children+: [lambda_literal, value_arguments] + arguments?: value_arguments + lambda*: lambda_literal name*: simple_identifier capture_list: item+: capture_list_item @@ -215,7 +216,8 @@ named: constructed_type: [array_type, dictionary_type, user_type] suffix: constructor_suffix constructor_suffix: - $children+: [lambda_literal, value_arguments] + arguments?: value_arguments + lambda*: lambda_literal name*: simple_identifier control_transfer_statement: $children*: [expression, throw_keyword] From 5784ef22f68d6d310f77a5c821e988c6a4dad72d Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:40:17 +0000 Subject: [PATCH 032/226] unified: Unify more fields Not entirely happy about the mixed nature of the `kind` filed (having both tokens and the named node `throw_keyword` in there), but that's a problem for a different time. --- unified/extractor/tree-sitter-swift/grammar.js | 5 ++++- unified/extractor/tree-sitter-swift/node-types.yml | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 1518df0e3dd..4c5e175f60a 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1266,7 +1266,10 @@ module.exports = grammar({ ), control_transfer_statement: ($) => choice( - prec.right(PRECS.control_transfer, $._throw_statement), + prec.right( + PRECS.control_transfer, + seq(field("kind", $.throw_keyword), field("result", $.expression)) + ), prec.right( PRECS.control_transfer, seq( diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index b3ac84362bf..ca80ea2c359 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -220,8 +220,7 @@ named: lambda*: lambda_literal name*: simple_identifier control_transfer_statement: - $children*: [expression, throw_keyword] - kind?: ["break", "continue", "return", "yield"] + kind: ["break", "continue", "return", throw_keyword, "yield"] result?: expression custom_operator: default_keyword: From e6eac3784a741e8eb47d0badf38bccdd83e56feb Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:43:13 +0000 Subject: [PATCH 033/226] unified: Consolidate fields in `if_let_binding` --- unified/extractor/tree-sitter-swift/grammar.js | 6 +++--- unified/extractor/tree-sitter-swift/node-types.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 4c5e175f60a..5d544aca76b 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1907,10 +1907,10 @@ module.exports = grammar({ _direct_or_indirect_binding: ($) => seq( choice( - $._binding_kind_and_pattern, - seq("case", $._binding_pattern_no_expr) + field("pattern", alias($._binding_kind_and_pattern, $.pattern)), + seq("case", field("pattern", alias($._binding_pattern_no_expr, $.pattern))) ), - optional($.type_annotation) + field("type", optional($.type_annotation)) ), value_binding_pattern: ($) => field("mutability", choice("var", "let")), _possibly_async_binding_pattern_kind: ($) => diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index ca80ea2c359..3eecf7efaee 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -314,8 +314,8 @@ named: if_condition: kind: [availability_condition, expression, if_let_binding] if_let_binding: - $children*: [pattern, simple_identifier, type, type_annotation, user_type, value_binding_pattern, wildcard_pattern] - bound_identifier?: simple_identifier + pattern: pattern + type?: type_annotation value?: expression where?: where_clause if_statement: From 9902beddec7a888c20f269d05f8dcf0b79786035 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:47:58 +0000 Subject: [PATCH 034/226] unified: add proper fields for availability_condition --- unified/extractor/tree-sitter-swift/grammar.js | 2 +- unified/extractor/tree-sitter-swift/node-types.yml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 5d544aca76b..13248b67778 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1304,7 +1304,7 @@ module.exports = grammar({ ")" ), _availability_argument: ($) => - choice(seq($.identifier, sep1($.integer_literal, ".")), "*"), + choice(seq(field("platform", $.identifier), sep1(field("version", $.integer_literal), ".")), "*"), //////////////////////////////// // Declarations - https://docs.swift.org/swift-book/ReferenceManual/Declarations.html //////////////////////////////// diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 3eecf7efaee..cd9ae864e6b 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -142,7 +142,8 @@ named: platform*: simple_identifier version*: integer_literal availability_condition: - $children*: [identifier, integer_literal] + platform*: identifier + version*: integer_literal await_expression: expr: expression bang: From 6ff404a6d05c626b20c4966ad41326af950ed40f Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:49:57 +0000 Subject: [PATCH 035/226] unified: More miscellaneous field additions --- unified/extractor/tree-sitter-swift/grammar.js | 2 +- unified/extractor/tree-sitter-swift/node-types.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 13248b67778..45b037428bb 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1818,7 +1818,7 @@ module.exports = grammar({ ), // The Swift compiler no longer accepts these, but some very old code still uses it. deprecated_operator_declaration_body: ($) => - seq("{", repeat(choice($.simple_identifier, $._basic_literal)), "}"), + seq("{", repeat(field("entry", choice($.simple_identifier, $._basic_literal))), "}"), precedence_group_declaration: ($) => seq( "precedencegroup", diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index cd9ae864e6b..1a101c09563 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -229,7 +229,7 @@ named: body: function_body modifiers?: modifiers deprecated_operator_declaration_body: - $children*: [bin_literal, boolean_literal, hex_literal, integer_literal, line_string_literal, multi_line_string_literal, oct_literal, raw_string_literal, real_literal, regex_literal, simple_identifier] + entry*: [bin_literal, boolean_literal, hex_literal, integer_literal, line_string_literal, multi_line_string_literal, "nil", oct_literal, raw_string_literal, real_literal, regex_literal, simple_identifier] diagnostic: dictionary_literal: key*: expression From 5e14a7574e0adcf20815d92e878319a5607f4c99 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:53:55 +0000 Subject: [PATCH 036/226] unified: make compilation_condition named and add fields --- .../extractor/tree-sitter-swift/grammar.js | 34 +++++++++---------- .../tree-sitter-swift/node-types.yml | 10 +++++- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 45b037428bb..069f29cbe68 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -2027,46 +2027,46 @@ module.exports = grammar({ prec.right( PRECS.comment, choice( - seq(alias($._directive_if, "#if"), $._compilation_condition), - seq(alias($._directive_elseif, "#elseif"), $._compilation_condition), + seq(alias($._directive_if, "#if"), field("condition", $.compilation_condition)), + seq(alias($._directive_elseif, "#elseif"), field("condition", $.compilation_condition)), seq(alias($._directive_else, "#else")), seq(alias($._directive_endif, "#endif")) ) ), - _compilation_condition: ($) => + compilation_condition: ($) => prec.right( choice( - seq("os", "(", $.simple_identifier, ")"), - seq("arch", "(", $.simple_identifier, ")"), + seq("os", "(", field("name", $.simple_identifier), ")"), + seq("arch", "(", field("name", $.simple_identifier), ")"), seq( "swift", "(", $._comparison_operator, - sep1($.integer_literal, "."), + sep1(field("version", $.integer_literal), "."), ")" ), seq( "compiler", "(", $._comparison_operator, - sep1($.integer_literal, "."), + sep1(field("version", $.integer_literal), "."), ")" ), - seq("canImport", "(", sep1($.simple_identifier, "."), ")"), - seq("targetEnvironment", "(", $.simple_identifier, ")"), - $.boolean_literal, - $.simple_identifier, - seq("(", $._compilation_condition, ")"), - seq("!", $._compilation_condition), + seq("canImport", "(", sep1(field("name", $.simple_identifier), "."), ")"), + seq("targetEnvironment", "(", field("name", $.simple_identifier), ")"), + field("value", $.boolean_literal), + field("name", $.simple_identifier), + seq("(", field("inner", $.compilation_condition), ")"), + seq("!", field("operand", $.compilation_condition)), seq( - $._compilation_condition, + field("lhs", $.compilation_condition), $._conjunction_operator, - $._compilation_condition + field("rhs", $.compilation_condition) ), seq( - $._compilation_condition, + field("lhs", $.compilation_condition), $._disjunction_operator, - $._compilation_condition + field("rhs", $.compilation_condition) ) ) ), diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 1a101c09563..d49506a6761 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -193,6 +193,14 @@ named: lhs: expression op: ["<", "<=", ">", ">="] rhs: expression + compilation_condition: + inner?: compilation_condition + lhs?: compilation_condition + name*: simple_identifier + operand?: compilation_condition + rhs?: compilation_condition + value?: boolean_literal + version*: integer_literal computed_getter: attribute*: attribute body?: statements @@ -242,7 +250,7 @@ named: modifiers?: modifiers parameter?: simple_identifier directive: - $children*: [boolean_literal, integer_literal, simple_identifier] + condition?: compilation_condition directly_assignable_expression: expr: expression disjunction_expression: From e1a0e204b13b9844eacace70a35cccb0b040b1e0 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 14:55:35 +0000 Subject: [PATCH 037/226] unified: Promote enum_type_parameter to named and add fields --- .../extractor/tree-sitter-swift/grammar.js | 21 ++++++++----------- .../tree-sitter-swift/node-types.yml | 7 ++++++- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 069f29cbe68..9a62f45845e 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1699,20 +1699,17 @@ module.exports = grammar({ enum_type_parameters: ($) => seq( "(", - optional( - sep1( - seq( - optional( - seq(optional($.wildcard_pattern), $.simple_identifier, ":") - ), - $.type, - optional(seq($._equal_sign, $.expression)) - ), - "," - ) - ), + optional(sep1(field("parameter", $.enum_type_parameter), ",")), ")" ), + enum_type_parameter: ($) => + seq( + optional( + seq(optional(field("external_name", $.wildcard_pattern)), field("name", $.simple_identifier), ":") + ), + field("type", $.type), + optional(seq($._equal_sign, field("default_value", $.expression))) + ), protocol_declaration: ($) => prec.right( seq( diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index d49506a6761..678ab386cb2 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -268,8 +268,13 @@ named: modifiers?: modifiers name+: simple_identifier raw_value*: expression + enum_type_parameter: + default_value?: expression + external_name?: wildcard_pattern + name?: simple_identifier + type: type enum_type_parameters: - $children*: [expression, type, wildcard_pattern] + parameter*: enum_type_parameter equality_constraint: attribute*: attribute constrained_type: [identifier, nested_type_identifier] From eba9f35673465e2576020b8ce8c66ad53418785a Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 15:01:10 +0000 Subject: [PATCH 038/226] unified: Get rid of $children* on key_path_expression Doing this involved materialising a lot of previously anonymous nodes, and I'm not entirely sure it's the best solution, but the node types look decent enough. --- .../extractor/tree-sitter-swift/grammar.js | 32 +++++++++---------- .../tree-sitter-swift/node-types.yml | 14 ++++++-- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 9a62f45845e..93af35f6344 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -97,7 +97,7 @@ module.exports = grammar({ [$.attribute], [$._attribute_argument], // Is `foo { ... }` a constructor invocation or function invocation? - [$._simple_user_type, $.expression], + [$.simple_user_type, $.expression], // To support nested types A.B not being interpreted as `(navigation_expression ... (type_identifier)) (navigation_suffix)` [$.user_type], // How to tell the difference between Foo.bar(with:and:), and Foo.bar(with: smth, and: other)? You need GLR @@ -116,7 +116,7 @@ module.exports = grammar({ [$.referenceable_operator, $._prefix_unary_operator], // `{ [self, b, c] ...` could be a capture list or an array literal depending on what else happens. [$.capture_list_item, $.expression], - [$.capture_list_item, $.expression, $._simple_user_type], + [$.capture_list_item, $.expression, $.simple_user_type], [$._primary_expression, $.capture_list_item], // a ? b : c () could be calling c(), or it could be calling a function that's produced by the result of // `(a ? b : c)`. We have a small hack to force it to be the former of these by intentionally introducing a @@ -436,13 +436,13 @@ module.exports = grammar({ ) ), // The grammar just calls this whole thing a `type-identifier` but that's a bit confusing. - user_type: ($) => sep1(field("part", $._simple_user_type), $._dot), - _simple_user_type: ($) => + user_type: ($) => sep1(field("part", $.simple_user_type), $._dot), + simple_user_type: ($) => prec.right( PRECS.ty, seq( - alias($.simple_identifier, $.type_identifier), - optional($.type_arguments) + field("name", alias($.simple_identifier, $.type_identifier)), + field("arguments", optional($.type_arguments)) ) ), tuple_type: ($) => @@ -1110,27 +1110,27 @@ module.exports = grammar({ PRECS.keypath, seq( "\\", - optional( - choice($._simple_user_type, $.array_type, $.dictionary_type) - ), - repeat(seq(".", $._key_path_component)) + field("type", optional( + choice($.simple_user_type, $.array_type, $.dictionary_type) + )), + repeat(seq(".", field("component", $.key_path_component))) ) ), key_path_string_expression: ($) => prec.left(seq($._hash_symbol, "keyPath", "(", field("expr", $.expression), ")")), - _key_path_component: ($) => + key_path_component: ($) => prec.left( choice( - seq($.simple_identifier, repeat($._key_path_postfixes)), - repeat1($._key_path_postfixes) + seq(field("name", $.simple_identifier), repeat(field("postfix", $.key_path_postfix))), + repeat1(field("postfix", $.key_path_postfix)) ) ), - _key_path_postfixes: ($) => + key_path_postfix: ($) => choice( "?", - $.bang, + field("force_unwrap", $.bang), "self", - seq("[", optional(sep1($.value_argument, ",")), "]") + seq("[", optional(sep1(field("argument", $.value_argument), ",")), "]") ), try_operator: ($) => prec.right( diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 678ab386cb2..da077b13a63 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -371,8 +371,15 @@ named: reference_specifier*: value_argument_label type_modifiers?: type_modifiers value?: expression + key_path_component: + name?: simple_identifier + postfix*: key_path_postfix key_path_expression: - $children*: [array_type, bang, dictionary_type, simple_identifier, type_arguments, type_identifier, value_argument] + component*: key_path_component + type?: [array_type, dictionary_type, simple_user_type] + key_path_postfix: + argument*: value_argument + force_unwrap?: bang key_path_string_expression: expr: expression lambda_function_type: @@ -551,6 +558,9 @@ named: mutation?: mutation_modifier shebang_line: simple_identifier: + simple_user_type: + arguments?: type_arguments + name: type_identifier source_file: shebang?: shebang_line statement*: [do_statement, expression, for_statement, global_declaration, guard_statement, repeat_while_statement, statement_label, throw_keyword, while_statement] @@ -634,7 +644,7 @@ named: type_parameters?: type_parameters value: type user_type: - part+: [type_arguments, type_identifier] + part+: simple_user_type value_argument: name?: value_argument_label reference_specifier*: value_argument_label From 6e5e650b426351f18d7ac38edf43aae449a319cd Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 15:03:29 +0000 Subject: [PATCH 039/226] unified: Add fields for macro_declaration --- unified/extractor/tree-sitter-swift/grammar.js | 10 +++++----- unified/extractor/tree-sitter-swift/node-types.yml | 6 +++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 93af35f6344..6566c32b8b7 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1497,17 +1497,17 @@ module.exports = grammar({ macro_declaration: ($) => seq( $._macro_head, - $.simple_identifier, - optional($.type_parameters), + field("name", $.simple_identifier), + field("type_parameters", optional($.type_parameters)), $._macro_signature, optional(field("definition", $.macro_definition)), - optional($.type_constraints) + field("type_constraints", optional($.type_constraints)) ), - _macro_head: ($) => seq(optional($.modifiers), "macro"), + _macro_head: ($) => seq(field("modifiers", optional($.modifiers)), "macro"), _macro_signature: ($) => seq( $._function_value_parameters, - optional(seq($._arrow_operator, $.unannotated_type)) + optional(seq($._arrow_operator, field("return_type", $.unannotated_type))) ), macro_definition: ($) => seq( diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index da077b13a63..f6718deef18 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -404,11 +404,15 @@ named: interpolation*: interpolated_expression text*: [line_str_text, str_escaped_char] macro_declaration: - $children+: [modifiers, simple_identifier, type_constraints, type_parameters, unannotated_type] attribute*: attribute default_value*: expression definition?: macro_definition + modifiers?: modifiers + name: simple_identifier parameter*: parameter + return_type?: unannotated_type + type_constraints?: type_constraints + type_parameters?: type_parameters macro_definition: body: [expression, external_macro_definition] macro_invocation: From 406a02fa49a7835336b029814baf02ef36514eb5 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 15:05:27 +0000 Subject: [PATCH 040/226] unified: Add fields to switch_entry Of note: this involved un-inlining where_clause. --- unified/extractor/tree-sitter-swift/grammar.js | 14 ++++++-------- unified/extractor/tree-sitter-swift/node-types.yml | 6 +++++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 6566c32b8b7..1f79aedeacf 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1078,20 +1078,18 @@ module.exports = grammar({ ), switch_entry: ($) => seq( - optional($.modifiers), + field("modifiers", optional($.modifiers)), choice( seq( "case", - seq( - $.switch_pattern, - optional(seq($.where_keyword, $.expression)) - ), - repeat(seq(",", $.switch_pattern)) + field("pattern", $.switch_pattern), + field("where", optional($.where_clause)), + repeat(seq(",", field("pattern", $.switch_pattern))) ), - $.default_keyword + field("default", $.default_keyword) ), ":", - $.statements, + field("body", $.statements), optional("fallthrough") ), switch_pattern: ($) => field("pattern", alias($._binding_pattern_with_expr, $.pattern)), diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index f6718deef18..defb9522670 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -586,7 +586,11 @@ named: suppressed_constraint: suppressed: type_identifier switch_entry: - $children+: [default_keyword, expression, modifiers, statements, switch_pattern, where_keyword] + body: statements + default?: default_keyword + modifiers?: modifiers + pattern*: switch_pattern + where?: where_clause switch_pattern: pattern: pattern switch_statement: From 2010844b1eb531e44fcc9c474a4c498f03bf1a17 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 15:14:35 +0000 Subject: [PATCH 041/226] unified: Add fields to property_declaration Not entirely sure about the `binding?` field on `pattern`, but it looks like that might actually be useful. --- unified/extractor/tree-sitter-swift/grammar.js | 10 +++++----- unified/extractor/tree-sitter-swift/node-types.yml | 6 +++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 1f79aedeacf..3af1017a109 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1405,13 +1405,13 @@ module.exports = grammar({ prec.left( seq( field("name", alias($._no_expr_pattern_already_bound, $.pattern)), - optional($.type_annotation), - optional($.type_constraints), + field("type", optional($.type_annotation)), + field("type_constraints", optional($.type_constraints)), optional( choice( $._expression_with_willset_didset, $._expression_without_willset_didset, - $.willset_didset_block, + field("observers", $.willset_didset_block), field("computed_value", $.computed_property) ) ) @@ -1423,7 +1423,7 @@ module.exports = grammar({ seq( $._equal_sign, field("value", $.expression), - $.willset_didset_block + field("observers", $.willset_didset_block) ) ), _expression_without_willset_didset: ($) => @@ -1909,7 +1909,7 @@ module.exports = grammar({ ), value_binding_pattern: ($) => field("mutability", choice("var", "let")), _possibly_async_binding_pattern_kind: ($) => - seq(optional($._async_modifier), $.value_binding_pattern), + seq(optional($._async_modifier), field("binding", $.value_binding_pattern)), _binding_kind_and_pattern: ($) => seq( $._possibly_async_binding_pattern_kind, diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index defb9522670..981a9fede3b 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -474,6 +474,7 @@ named: modifier+: parameter_modifier pattern: $children*: [expression, pattern, type, user_type, value_binding_pattern, wildcard_pattern] + binding?: value_binding_pattern bound_identifier?: simple_identifier playground_literal: name+: simple_identifier @@ -494,10 +495,13 @@ named: target: expression property_behavior_modifier: property_declaration: - $children*: [type_annotation, type_constraints, value_binding_pattern, willset_didset_block] + binding: value_binding_pattern computed_value*: computed_property modifiers*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier] name+: pattern + observers*: willset_didset_block + type*: type_annotation + type_constraints*: type_constraints value*: expression property_modifier: protocol_body: From 2eee2e50dc3829a91500eea2fd62f9e0721b2556 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 15:23:26 +0000 Subject: [PATCH 042/226] unified: clean up patterns Mostly by materialising a bunch of (useful) intermediate nodes. --- .../extractor/tree-sitter-swift/grammar.js | 55 ++++++++++--------- .../tree-sitter-swift/node-types.yml | 17 +++++- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 3af1017a109..0616522ab4c 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -146,7 +146,7 @@ module.exports = grammar({ [$._bodyless_function_declaration, $.property_modifier], [$.init_declaration, $.property_modifier], // Patterns, man - [$._navigable_type_expression, $._case_pattern], + [$._navigable_type_expression, $.case_pattern], [$._no_expr_pattern_already_bound, $._binding_pattern_no_expr], // On encountering a closure starting with `{ @Foo ...`, we don't yet know if that attribute applies to the closure @@ -1865,38 +1865,38 @@ module.exports = grammar({ _universally_allowed_pattern: ($) => choice( $.wildcard_pattern, - $._tuple_pattern, - $._type_casting_pattern, - $._case_pattern + $.tuple_pattern, + $.type_casting_pattern, + $.case_pattern ), _bound_identifier: ($) => field("bound_identifier", $.simple_identifier), _binding_pattern_no_expr: ($) => seq( - choice( + field("kind", choice( $._universally_allowed_pattern, - $._binding_pattern, + $.binding_pattern, $._bound_identifier - ), + )), optional($._quest) ), _no_expr_pattern_already_bound: ($) => seq( - choice($._universally_allowed_pattern, $._bound_identifier), + field("kind", choice($._universally_allowed_pattern, $._bound_identifier)), optional($._quest) ), _binding_pattern_with_expr: ($) => seq( - choice( + field("kind", choice( $._universally_allowed_pattern, - $._binding_pattern, + $.binding_pattern, $.expression - ), + )), optional($._quest) ), _non_binding_pattern_with_expr: ($) => seq( - choice($._universally_allowed_pattern, $.expression), + field("kind", choice($._universally_allowed_pattern, $.expression)), optional($._quest) ), _direct_or_indirect_binding: ($) => @@ -1916,32 +1916,33 @@ module.exports = grammar({ $._no_expr_pattern_already_bound ), wildcard_pattern: ($) => "_", - _tuple_pattern_item: ($) => + tuple_pattern_item: ($) => choice( seq( - $.simple_identifier, - seq(":", alias($._binding_pattern_with_expr, $.pattern)) + field("name", $.simple_identifier), + ":", + field("pattern", alias($._binding_pattern_with_expr, $.pattern)) ), - alias($._binding_pattern_with_expr, $.pattern) + field("pattern", alias($._binding_pattern_with_expr, $.pattern)) ), - _tuple_pattern: ($) => seq("(", sep1Opt($._tuple_pattern_item, ","), ")"), - _case_pattern: ($) => + tuple_pattern: ($) => seq("(", sep1Opt(field("item", $.tuple_pattern_item), ","), ")"), + case_pattern: ($) => seq( optional("case"), - optional($.user_type), // XXX this should just be _type but that creates ambiguity + optional(field("type", $.user_type)), // XXX this should just be _type but that creates ambiguity $._dot, - $.simple_identifier, - optional($._tuple_pattern) + field("name", $.simple_identifier), + optional(field("arguments", $.tuple_pattern)) ), - _type_casting_pattern: ($) => + type_casting_pattern: ($) => choice( - seq("is", $.type), - seq(alias($._binding_pattern_no_expr, $.pattern), $._as, $.type) + seq("is", field("type", $.type)), + seq(field("pattern", alias($._binding_pattern_no_expr, $.pattern)), $._as, field("type", $.type)) ), - _binding_pattern: ($) => + binding_pattern: ($) => seq( - seq(optional("case"), $.value_binding_pattern), - $._no_expr_pattern_already_bound + seq(optional("case"), field("binding", $.value_binding_pattern)), + field("pattern", alias($._no_expr_pattern_already_bound, $.pattern)) ), // ========== diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 981a9fede3b..223c16e43ec 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -148,6 +148,9 @@ named: expr: expression bang: bin_literal: + binding_pattern: + binding: value_binding_pattern + pattern: pattern bitwise_operation: lhs: expression op: ["&", "<<", ">>", "^", "|"] @@ -166,6 +169,10 @@ named: name: [self_expression, simple_identifier] ownership?: ownership_modifier value?: expression + case_pattern: + arguments?: tuple_pattern + name: simple_identifier + type?: user_type catch_block: body?: statements error?: pattern @@ -473,9 +480,9 @@ named: parameter_modifiers: modifier+: parameter_modifier pattern: - $children*: [expression, pattern, type, user_type, value_binding_pattern, wildcard_pattern] binding?: value_binding_pattern bound_identifier?: simple_identifier + kind: [binding_pattern, case_pattern, expression, tuple_pattern, type_casting_pattern, wildcard_pattern] playground_literal: name+: simple_identifier value+: expression @@ -615,6 +622,11 @@ named: tuple_expression: name*: simple_identifier value+: expression + tuple_pattern: + item+: tuple_pattern_item + tuple_pattern_item: + name?: simple_identifier + pattern: pattern tuple_type: element*: tuple_type_item tuple_type_item: @@ -629,6 +641,9 @@ named: type: [implicitly_unwrapped_type, type] type_arguments: argument+: type + type_casting_pattern: + pattern?: pattern + type: type type_constraint: constraint: [equality_constraint, inheritance_constraint] type_constraints: From 1ef557c972f0ce7ca13f3dd05ad524b19330465f Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 15:27:14 +0000 Subject: [PATCH 043/226] Python: Address Copilot's comments --- .../ControlFlow/evaluation-order/TimerUtils.qll | 7 ++++--- .../ControlFlow/evaluation-order/test_basic.py | 2 +- .../library-tests/ControlFlow/evaluation-order/timer.py | 7 ++++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/TimerUtils.qll b/python/ql/test/library-tests/ControlFlow/evaluation-order/TimerUtils.qll index 9782152b8cf..23f8f3a50a0 100644 --- a/python/ql/test/library-tests/ControlFlow/evaluation-order/TimerUtils.qll +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/TimerUtils.qll @@ -1,9 +1,10 @@ /** * Utility library for identifying timer annotations in evaluation-order tests. * - * Identifies `expr @ t[n]` (matmul), `t(expr, n)` (call), and - * `expr @ t.dead[n]` (dead-code) patterns, extracts timestamp values, - * and provides predicates for traversing consecutive annotated CFG nodes. + * Identifies `expr @ t[n]` (matmul) and `t(expr, n)` (call) patterns, + * including `dead(n)` and `never` markers within subscripts, extracts + * timestamp values, and provides predicates for traversing consecutive + * annotated CFG nodes. */ import python diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py index 3e8ee925d91..b98ebe7b95c 100644 --- a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py @@ -5,7 +5,7 @@ are evaluated in the expected order (typically left to right for operands of binary operators, elements of collection literals, etc.) Every evaluated expression has a timestamp annotation, except the -timer mechanism itself (t[n], t.dead[n]). +timer mechanism itself (t[n], t[dead(n)], t[never]). """ from timer import test, never diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/timer.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/timer.py index e10dde2592a..ccec5d64f7c 100644 --- a/python/ql/test/library-tests/ControlFlow/evaluation-order/timer.py +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/timer.py @@ -26,6 +26,7 @@ Run a test file directly to self-validate: python test_file.py """ import atexit +import os import sys _results = [] @@ -53,6 +54,10 @@ class _Check: self._dead.add(e.timestamp) elif isinstance(e, _NeverSentinel): self._never = True + else: + raise TypeError( + f"Unknown element in timer subscript: {e!r} (type {type(e).__name__})" + ) def __rmatmul__(self, value): ts = self._timer._tick() @@ -183,7 +188,7 @@ def _report(): print("---") print(f"{passed}/{total} tests passed") if passed < total: - sys.exit(1) + os._exit(1) atexit.register(_report) From eb480d1de47424e700692ccc4349b5ba7ecedab3 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 15:38:29 +0000 Subject: [PATCH 044/226] unified: Make parenthesized_type named I'm not entirely happy about this solution, but it seemed to be the most straightforward way of avoiding various kinds of token bleeding. --- unified/extractor/tree-sitter-swift/grammar.js | 10 +++++----- unified/extractor/tree-sitter-swift/node-types.yml | 8 +++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 0616522ab4c..1bcdc4fbdf1 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -452,7 +452,7 @@ module.exports = grammar({ optional(sep1Opt(field("element", $.tuple_type_item), ",")), ")" ), - field("element", alias($._parenthesized_type, $.tuple_type_item)) + field("element", alias($.parenthesized_type, $.tuple_type_item)) ), tuple_type_item: ($) => prec( @@ -467,7 +467,7 @@ module.exports = grammar({ prec( PRECS.expr, seq( - optional($.wildcard_pattern), + optional(field("external_name", $.wildcard_pattern)), field("name", $.simple_identifier), ":" ) @@ -571,10 +571,10 @@ module.exports = grammar({ field("suffix", $.constructor_suffix) ) ), - _parenthesized_type: ($) => + parenthesized_type: ($) => seq( "(", - choice($.opaque_type, $.existential_type, $.dictionary_type), + field("type", choice($.opaque_type, $.existential_type, $.dictionary_type)), ")" ), navigation_expression: ($) => @@ -586,7 +586,7 @@ module.exports = grammar({ choice( $._navigable_type_expression, $.expression, - $._parenthesized_type + $.parenthesized_type ) ), field("suffix", $.navigation_suffix) diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 223c16e43ec..3b3b5807e47 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -445,7 +445,7 @@ named: mutation_modifier: navigation_expression: suffix: navigation_suffix - target+: ["(", ")", array_type, dictionary_type, existential_type, expression, opaque_type, user_type] + target: [array_type, dictionary_type, expression, parenthesized_type, user_type] navigation_suffix: suffix: [integer_literal, simple_identifier] nested_type_identifier: @@ -479,6 +479,8 @@ named: parameter_modifier: parameter_modifiers: modifier+: parameter_modifier + parenthesized_type: + type: [dictionary_type, existential_type, opaque_type] pattern: binding?: value_binding_pattern bound_identifier?: simple_identifier @@ -630,10 +632,10 @@ named: tuple_type: element*: tuple_type_item tuple_type_item: - $children?: [dictionary_type, existential_type, opaque_type, wildcard_pattern] + external_name?: wildcard_pattern modifiers?: parameter_modifiers name?: simple_identifier - type?: type + type: [dictionary_type, existential_type, opaque_type, type] type: modifiers?: type_modifiers name: unannotated_type From 52d72836f904996278dc745ae96984f3f299ad6b Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 15:59:18 +0000 Subject: [PATCH 045/226] unified: Fix multiline_comment issue This named node (which is in fact emitted by the scanner as an `external`) was appearing as a child of `class_body` because of inlining via `_class_member_separator`. This, in itself, appears to be somewhat of a hack, to handle cases where a multiline comment signals the end of a class member. To fix this, we make the external node _unnamed_, but keep the `extras` node _named_ (so we can still extract it from the parse tree), and we add a new rule `multiline_comment` that mediates between the two. That way, the use inside `_class_member_separator` can use the unnamed variant, and no node is pushed into $children. --- unified/extractor/tree-sitter-swift/grammar.js | 9 +++++++-- unified/extractor/tree-sitter-swift/node-types.yml | 1 - 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 1bcdc4fbdf1..566b7d5567a 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -194,7 +194,7 @@ module.exports = grammar({ // `/*`, and decrement it whenever we see `*/`. A standard grammar would only be able to exit the comment at the // first `*/` (like C does). Similarly, when you start a string with `##"`, you're required to include the same // number of `#` symbols to end it. - $.multiline_comment, + $._multiline_comment, $.raw_str_part, $.raw_str_continuing_indicator, $.raw_str_end_part, @@ -270,6 +270,11 @@ module.exports = grammar({ // Lexical Structure - https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html //////////////////////////////// comment: ($) => token(prec(PRECS.comment, seq("//", /.*/))), + // Named wrapper for the unnamed `_multiline_comment` external token, so + // that multi-line comments still appear in the AST (e.g. as extras between + // top-level statements) without bleeding into class_body's $children when + // used as a class member separator. + multiline_comment: ($) => $._multiline_comment, // Identifiers simple_identifier: ($) => choice( @@ -1603,7 +1608,7 @@ module.exports = grammar({ field("base", $.unannotated_type), optional(seq(".", sep1(field("member", $.simple_identifier), "."))) ), - _class_member_separator: ($) => choice($._semi, $.multiline_comment), + _class_member_separator: ($) => choice($._semi, $._multiline_comment), _class_member_declarations: ($) => seq( sep1(field("member", $.type_level_declaration), $._class_member_separator), diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 3b3b5807e47..47f56435d03 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -184,7 +184,6 @@ named: target: expression type: type class_body: - $children*: multiline_comment member*: type_level_declaration class_declaration: attribute*: attribute From bfe5aa8d42e2f7b5064928e77c9ffa0791c98c2c Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 12 May 2026 16:01:32 +0000 Subject: [PATCH 046/226] unified: Regenerate files --- unified/ql/lib/codeql/unified/Ast.qll | 505 +++++++++++++++++++------ unified/ql/lib/unified.dbscheme | 511 ++++++++++++++++---------- 2 files changed, 718 insertions(+), 298 deletions(-) diff --git a/unified/ql/lib/codeql/unified/Ast.qll b/unified/ql/lib/codeql/unified/Ast.qll index bf3b98f582e..db2e73df01b 100644 --- a/unified/ql/lib/codeql/unified/Ast.qll +++ b/unified/ql/lib/codeql/unified/Ast.qll @@ -277,12 +277,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "AvailabilityCondition" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_availability_condition_child(this, i, result) } + /** Gets the node corresponding to the field `platform`. */ + final Identifier getPlatform(int i) { swift_availability_condition_platform(this, i, result) } + + /** Gets the node corresponding to the field `version`. */ + final IntegerLiteral getVersion(int i) { swift_availability_condition_version(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_availability_condition_child(this, _, result) + swift_availability_condition_platform(this, _, result) or + swift_availability_condition_version(this, _, result) } } @@ -292,15 +296,10 @@ module Swift { final override string getAPrimaryQlClass() { result = "AwaitExpression" } /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_await_expression_expr(this, result) } - - /** Gets the child of this node. */ - final Expression getChild() { swift_await_expression_child(this, result) } + final Expression getExpr() { swift_await_expression_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_await_expression_expr(this, result) or swift_await_expression_child(this, result) - } + final override AstNode getAFieldOrChild() { swift_await_expression_def(this, result) } } /** A class representing `bang` tokens. */ @@ -315,6 +314,23 @@ module Swift { final override string getAPrimaryQlClass() { result = "BinLiteral" } } + /** A class representing `binding_pattern` nodes. */ + class BindingPattern extends @swift_binding_pattern, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "BindingPattern" } + + /** Gets the node corresponding to the field `binding`. */ + final ValueBindingPattern getBinding() { swift_binding_pattern_def(this, result, _) } + + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { swift_binding_pattern_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_binding_pattern_def(this, result, _) or swift_binding_pattern_def(this, _, result) + } + } + /** A class representing `bitwise_operation` nodes. */ class BitwiseOperation extends @swift_bitwise_operation, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -360,19 +376,14 @@ module Swift { final override string getAPrimaryQlClass() { result = "CallExpression" } /** Gets the node corresponding to the field `function`. */ - final Expression getFunction() { swift_call_expression_function(this, result) } + final Expression getFunction() { swift_call_expression_def(this, result, _) } /** Gets the node corresponding to the field `suffix`. */ - final CallSuffix getSuffix() { swift_call_expression_suffix(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_call_expression_child(this, i, result) } + final CallSuffix getSuffix() { swift_call_expression_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_call_expression_function(this, result) or - swift_call_expression_suffix(this, result) or - swift_call_expression_child(this, _, result) + swift_call_expression_def(this, result, _) or swift_call_expression_def(this, _, result) } } @@ -381,15 +392,20 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "CallSuffix" } + /** Gets the node corresponding to the field `arguments`. */ + final ValueArguments getArguments() { swift_call_suffix_arguments(this, result) } + + /** Gets the node corresponding to the field `lambda`. */ + final LambdaLiteral getLambda(int i) { swift_call_suffix_lambda(this, i, result) } + /** Gets the node corresponding to the field `name`. */ final SimpleIdentifier getName(int i) { swift_call_suffix_name(this, i, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_call_suffix_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_call_suffix_name(this, _, result) or swift_call_suffix_child(this, _, result) + swift_call_suffix_arguments(this, result) or + swift_call_suffix_lambda(this, _, result) or + swift_call_suffix_name(this, _, result) } } @@ -427,6 +443,28 @@ module Swift { } } + /** A class representing `case_pattern` nodes. */ + class CasePattern extends @swift_case_pattern, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "CasePattern" } + + /** Gets the node corresponding to the field `arguments`. */ + final TuplePattern getArguments() { swift_case_pattern_arguments(this, result) } + + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_case_pattern_def(this, result) } + + /** Gets the node corresponding to the field `type`. */ + final UserType getType() { swift_case_pattern_type(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_case_pattern_arguments(this, result) or + swift_case_pattern_def(this, result) or + swift_case_pattern_type(this, result) + } + } + /** A class representing `catch_block` nodes. */ class CatchBlock extends @swift_catch_block, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -492,13 +530,8 @@ module Swift { /** Gets the node corresponding to the field `member`. */ final TypeLevelDeclaration getMember(int i) { swift_class_body_member(this, i, result) } - /** Gets the `i`th child of this node. */ - final MultilineComment getChild(int i) { swift_class_body_child(this, i, result) } - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_class_body_member(this, _, result) or swift_class_body_child(this, _, result) - } + final override AstNode getAFieldOrChild() { swift_class_body_member(this, _, result) } } /** A class representing `class_declaration` nodes. */ @@ -527,6 +560,11 @@ module Swift { ) } + /** Gets the node corresponding to the field `inherits`. */ + final InheritanceSpecifier getInherits(int i) { + swift_class_declaration_inherits(this, i, result) + } + /** Gets the node corresponding to the field `modifiers`. */ final AstNode getModifiers(int i) { swift_class_declaration_modifiers(this, i, result) } @@ -543,18 +581,15 @@ module Swift { swift_class_declaration_type_parameters(this, result) } - /** Gets the `i`th child of this node. */ - final InheritanceSpecifier getChild(int i) { swift_class_declaration_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_class_declaration_attribute(this, _, result) or swift_class_declaration_def(this, result, _, _) or + swift_class_declaration_inherits(this, _, result) or swift_class_declaration_modifiers(this, _, result) or swift_class_declaration_def(this, _, _, result) or swift_class_declaration_type_constraints(this, result) or - swift_class_declaration_type_parameters(this, result) or - swift_class_declaration_child(this, _, result) + swift_class_declaration_type_parameters(this, result) } } @@ -595,6 +630,44 @@ module Swift { } } + /** A class representing `compilation_condition` nodes. */ + class CompilationCondition extends @swift_compilation_condition, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "CompilationCondition" } + + /** Gets the node corresponding to the field `inner`. */ + final CompilationCondition getInner() { swift_compilation_condition_inner(this, result) } + + /** Gets the node corresponding to the field `lhs`. */ + final CompilationCondition getLhs() { swift_compilation_condition_lhs(this, result) } + + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName(int i) { swift_compilation_condition_name(this, i, result) } + + /** Gets the node corresponding to the field `operand`. */ + final CompilationCondition getOperand() { swift_compilation_condition_operand(this, result) } + + /** Gets the node corresponding to the field `rhs`. */ + final CompilationCondition getRhs() { swift_compilation_condition_rhs(this, result) } + + /** Gets the node corresponding to the field `value`. */ + final BooleanLiteral getValue() { swift_compilation_condition_value(this, result) } + + /** Gets the node corresponding to the field `version`. */ + final IntegerLiteral getVersion(int i) { swift_compilation_condition_version(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_compilation_condition_inner(this, result) or + swift_compilation_condition_lhs(this, result) or + swift_compilation_condition_name(this, _, result) or + swift_compilation_condition_operand(this, result) or + swift_compilation_condition_rhs(this, result) or + swift_compilation_condition_value(this, result) or + swift_compilation_condition_version(this, _, result) + } + } + /** A class representing `computed_getter` nodes. */ class ComputedGetter extends @swift_computed_getter, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -731,16 +804,20 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ConstructorSuffix" } + /** Gets the node corresponding to the field `arguments`. */ + final ValueArguments getArguments() { swift_constructor_suffix_arguments(this, result) } + + /** Gets the node corresponding to the field `lambda`. */ + final LambdaLiteral getLambda(int i) { swift_constructor_suffix_lambda(this, i, result) } + /** Gets the node corresponding to the field `name`. */ final SimpleIdentifier getName(int i) { swift_constructor_suffix_name(this, i, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_constructor_suffix_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_constructor_suffix_name(this, _, result) or - swift_constructor_suffix_child(this, _, result) + swift_constructor_suffix_arguments(this, result) or + swift_constructor_suffix_lambda(this, _, result) or + swift_constructor_suffix_name(this, _, result) } } @@ -750,19 +827,15 @@ module Swift { final override string getAPrimaryQlClass() { result = "ControlTransferStatement" } /** Gets the node corresponding to the field `kind`. */ - final AstNode getKind() { swift_control_transfer_statement_kind(this, result) } + final AstNode getKind() { swift_control_transfer_statement_def(this, result) } /** Gets the node corresponding to the field `result`. */ final Expression getResult() { swift_control_transfer_statement_result(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_control_transfer_statement_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_control_transfer_statement_kind(this, result) or - swift_control_transfer_statement_result(this, result) or - swift_control_transfer_statement_child(this, _, result) + swift_control_transfer_statement_def(this, result) or + swift_control_transfer_statement_result(this, result) } } @@ -802,14 +875,14 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "DeprecatedOperatorDeclarationBody" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { - swift_deprecated_operator_declaration_body_child(this, i, result) + /** Gets the node corresponding to the field `entry`. */ + final AstNode getEntry(int i) { + swift_deprecated_operator_declaration_body_entry(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_deprecated_operator_declaration_body_child(this, _, result) + swift_deprecated_operator_declaration_body_entry(this, _, result) } } @@ -881,11 +954,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Directive" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_directive_child(this, i, result) } + /** Gets the node corresponding to the field `condition`. */ + final CompilationCondition getCondition() { swift_directive_condition(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_directive_child(this, _, result) } + final override AstNode getAFieldOrChild() { swift_directive_condition(this, result) } } /** A class representing `directly_assignable_expression` nodes. */ @@ -990,16 +1063,48 @@ module Swift { } } + /** A class representing `enum_type_parameter` nodes. */ + class EnumTypeParameter extends @swift_enum_type_parameter, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "EnumTypeParameter" } + + /** Gets the node corresponding to the field `default_value`. */ + final Expression getDefaultValue() { swift_enum_type_parameter_default_value(this, result) } + + /** Gets the node corresponding to the field `external_name`. */ + final WildcardPattern getExternalName() { + swift_enum_type_parameter_external_name(this, result) + } + + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_enum_type_parameter_name(this, result) } + + /** Gets the node corresponding to the field `type`. */ + final Type getType() { swift_enum_type_parameter_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_enum_type_parameter_default_value(this, result) or + swift_enum_type_parameter_external_name(this, result) or + swift_enum_type_parameter_name(this, result) or + swift_enum_type_parameter_def(this, result) + } + } + /** A class representing `enum_type_parameters` nodes. */ class EnumTypeParameters extends @swift_enum_type_parameters, AstNode { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "EnumTypeParameters" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_enum_type_parameters_child(this, i, result) } + /** Gets the node corresponding to the field `parameter`. */ + final EnumTypeParameter getParameter(int i) { + swift_enum_type_parameters_parameter(this, i, result) + } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_enum_type_parameters_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_enum_type_parameters_parameter(this, _, result) + } } /** A class representing `equality_constraint` nodes. */ @@ -1139,7 +1244,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "FunctionDeclaration" } /** Gets the node corresponding to the field `async`. */ - final AsyncKeyword getAsync() { swift_function_declaration_async(this, result) } + final ReservedWord getAsync() { swift_function_declaration_async(this, result) } /** Gets the node corresponding to the field `attribute`. */ final Attribute getAttribute(int i) { swift_function_declaration_attribute(this, i, result) } @@ -1205,7 +1310,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "FunctionType" } /** Gets the node corresponding to the field `async`. */ - final AsyncKeyword getAsync() { swift_function_type_async(this, result) } + final ReservedWord getAsync() { swift_function_type_async(this, result) } /** Gets the node corresponding to the field `params`. */ final UnannotatedType getParams() { swift_function_type_def(this, result, _) } @@ -1302,10 +1407,11 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "IfLetBinding" } - /** Gets the node corresponding to the field `bound_identifier`. */ - final SimpleIdentifier getBoundIdentifier() { - swift_if_let_binding_bound_identifier(this, result) - } + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { swift_if_let_binding_def(this, result) } + + /** Gets the node corresponding to the field `type`. */ + final TypeAnnotation getType() { swift_if_let_binding_type(this, result) } /** Gets the node corresponding to the field `value`. */ final Expression getValue() { swift_if_let_binding_value(this, result) } @@ -1313,15 +1419,12 @@ module Swift { /** Gets the node corresponding to the field `where`. */ final WhereClause getWhere() { swift_if_let_binding_where(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_if_let_binding_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_if_let_binding_bound_identifier(this, result) or + swift_if_let_binding_def(this, result) or + swift_if_let_binding_type(this, result) or swift_if_let_binding_value(this, result) or - swift_if_let_binding_where(this, result) or - swift_if_let_binding_child(this, _, result) + swift_if_let_binding_where(this, result) } } @@ -1448,7 +1551,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "InitDeclaration" } /** Gets the node corresponding to the field `async`. */ - final AsyncKeyword getAsync() { swift_init_declaration_async(this, result) } + final ReservedWord getAsync() { swift_init_declaration_async(this, result) } /** Gets the node corresponding to the field `attribute`. */ final Attribute getAttribute(int i) { swift_init_declaration_attribute(this, i, result) } @@ -1539,16 +1642,60 @@ module Swift { } } + /** A class representing `key_path_component` nodes. */ + class KeyPathComponent extends @swift_key_path_component, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "KeyPathComponent" } + + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_key_path_component_name(this, result) } + + /** Gets the node corresponding to the field `postfix`. */ + final KeyPathPostfix getPostfix(int i) { swift_key_path_component_postfix(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_key_path_component_name(this, result) or + swift_key_path_component_postfix(this, _, result) + } + } + /** A class representing `key_path_expression` nodes. */ class KeyPathExpression extends @swift_key_path_expression, AstNode { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "KeyPathExpression" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_key_path_expression_child(this, i, result) } + /** Gets the node corresponding to the field `component`. */ + final KeyPathComponent getComponent(int i) { + swift_key_path_expression_component(this, i, result) + } + + /** Gets the node corresponding to the field `type`. */ + final AstNode getType() { swift_key_path_expression_type(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_key_path_expression_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_key_path_expression_component(this, _, result) or + swift_key_path_expression_type(this, result) + } + } + + /** A class representing `key_path_postfix` nodes. */ + class KeyPathPostfix extends @swift_key_path_postfix, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "KeyPathPostfix" } + + /** Gets the node corresponding to the field `argument`. */ + final ValueArgument getArgument(int i) { swift_key_path_postfix_argument(this, i, result) } + + /** Gets the node corresponding to the field `force_unwrap`. */ + final Bang getForceUnwrap() { swift_key_path_postfix_force_unwrap(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_key_path_postfix_argument(this, _, result) or + swift_key_path_postfix_force_unwrap(this, result) + } } /** A class representing `key_path_string_expression` nodes. */ @@ -1569,7 +1716,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "LambdaFunctionType" } /** Gets the node corresponding to the field `async`. */ - final AsyncKeyword getAsync() { swift_lambda_function_type_async(this, result) } + final ReservedWord getAsync() { swift_lambda_function_type_async(this, result) } /** Gets the node corresponding to the field `params`. */ final LambdaFunctionTypeParameters getParams() { @@ -1703,19 +1850,39 @@ module Swift { /** Gets the node corresponding to the field `definition`. */ final MacroDefinition getDefinition() { swift_macro_declaration_definition(this, result) } + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_macro_declaration_modifiers(this, result) } + + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_macro_declaration_def(this, result) } + /** Gets the node corresponding to the field `parameter`. */ final Parameter getParameter(int i) { swift_macro_declaration_parameter(this, i, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_macro_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `return_type`. */ + final UnannotatedType getReturnType() { swift_macro_declaration_return_type(this, result) } + + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_macro_declaration_type_constraints(this, result) + } + + /** Gets the node corresponding to the field `type_parameters`. */ + final TypeParameters getTypeParameters() { + swift_macro_declaration_type_parameters(this, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_macro_declaration_attribute(this, _, result) or swift_macro_declaration_default_value(this, _, result) or swift_macro_declaration_definition(this, result) or + swift_macro_declaration_modifiers(this, result) or + swift_macro_declaration_def(this, result) or swift_macro_declaration_parameter(this, _, result) or - swift_macro_declaration_child(this, _, result) + swift_macro_declaration_return_type(this, result) or + swift_macro_declaration_type_constraints(this, result) or + swift_macro_declaration_type_parameters(this, result) } } @@ -1870,15 +2037,15 @@ module Swift { final override string getAPrimaryQlClass() { result = "NavigationExpression" } /** Gets the node corresponding to the field `suffix`. */ - final NavigationSuffix getSuffix() { swift_navigation_expression_def(this, result) } + final NavigationSuffix getSuffix() { swift_navigation_expression_def(this, result, _) } /** Gets the node corresponding to the field `target`. */ - final AstNode getTarget(int i) { swift_navigation_expression_target(this, i, result) } + final AstNode getTarget() { swift_navigation_expression_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_navigation_expression_def(this, result) or - swift_navigation_expression_target(this, _, result) + swift_navigation_expression_def(this, result, _) or + swift_navigation_expression_def(this, _, result) } } @@ -2089,20 +2256,37 @@ module Swift { } } + /** A class representing `parenthesized_type` nodes. */ + class ParenthesizedType extends @swift_parenthesized_type, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ParenthesizedType" } + + /** Gets the node corresponding to the field `type`. */ + final AstNode getType() { swift_parenthesized_type_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_parenthesized_type_def(this, result) } + } + /** A class representing `pattern` nodes. */ class Pattern extends @swift_pattern, AstNode { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Pattern" } + /** Gets the node corresponding to the field `binding`. */ + final ValueBindingPattern getBinding() { swift_pattern_binding(this, result) } + /** Gets the node corresponding to the field `bound_identifier`. */ final SimpleIdentifier getBoundIdentifier() { swift_pattern_bound_identifier(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_pattern_child(this, i, result) } + /** Gets the node corresponding to the field `kind`. */ + final AstNode getKind() { swift_pattern_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_pattern_bound_identifier(this, result) or swift_pattern_child(this, _, result) + swift_pattern_binding(this, result) or + swift_pattern_bound_identifier(this, result) or + swift_pattern_def(this, result) } } @@ -2223,6 +2407,9 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "PropertyDeclaration" } + /** Gets the node corresponding to the field `binding`. */ + final ValueBindingPattern getBinding() { swift_property_declaration_def(this, result) } + /** Gets the node corresponding to the field `computed_value`. */ final ComputedProperty getComputedValue(int i) { swift_property_declaration_computed_value(this, i, result) @@ -2234,19 +2421,32 @@ module Swift { /** Gets the node corresponding to the field `name`. */ final Pattern getName(int i) { swift_property_declaration_name(this, i, result) } + /** Gets the node corresponding to the field `observers`. */ + final WillsetDidsetBlock getObservers(int i) { + swift_property_declaration_observers(this, i, result) + } + + /** Gets the node corresponding to the field `type`. */ + final TypeAnnotation getType(int i) { swift_property_declaration_type(this, i, result) } + + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints(int i) { + swift_property_declaration_type_constraints(this, i, result) + } + /** Gets the node corresponding to the field `value`. */ final Expression getValue(int i) { swift_property_declaration_value(this, i, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_property_declaration_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_property_declaration_def(this, result) or swift_property_declaration_computed_value(this, _, result) or swift_property_declaration_modifiers(this, _, result) or swift_property_declaration_name(this, _, result) or - swift_property_declaration_value(this, _, result) or - swift_property_declaration_child(this, _, result) + swift_property_declaration_observers(this, _, result) or + swift_property_declaration_type(this, _, result) or + swift_property_declaration_type_constraints(this, _, result) or + swift_property_declaration_value(this, _, result) } } @@ -2300,6 +2500,11 @@ module Swift { ) } + /** Gets the node corresponding to the field `inherits`. */ + final InheritanceSpecifier getInherits(int i) { + swift_protocol_declaration_inherits(this, i, result) + } + /** Gets the node corresponding to the field `modifiers`. */ final Modifiers getModifiers() { swift_protocol_declaration_modifiers(this, result) } @@ -2316,18 +2521,15 @@ module Swift { swift_protocol_declaration_type_parameters(this, result) } - /** Gets the `i`th child of this node. */ - final InheritanceSpecifier getChild(int i) { swift_protocol_declaration_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_protocol_declaration_attribute(this, _, result) or swift_protocol_declaration_def(this, result, _, _) or + swift_protocol_declaration_inherits(this, _, result) or swift_protocol_declaration_modifiers(this, result) or swift_protocol_declaration_def(this, _, _, result) or swift_protocol_declaration_type_constraints(this, result) or - swift_protocol_declaration_type_parameters(this, result) or - swift_protocol_declaration_child(this, _, result) + swift_protocol_declaration_type_parameters(this, result) } } @@ -2337,7 +2539,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "ProtocolFunctionDeclaration" } /** Gets the node corresponding to the field `async`. */ - final AsyncKeyword getAsync() { swift_protocol_function_declaration_async(this, result) } + final ReservedWord getAsync() { swift_protocol_function_declaration_async(this, result) } /** Gets the node corresponding to the field `attribute`. */ final Attribute getAttribute(int i) { @@ -2630,6 +2832,23 @@ module Swift { final override string getAPrimaryQlClass() { result = "SimpleIdentifier" } } + /** A class representing `simple_user_type` nodes. */ + class SimpleUserType extends @swift_simple_user_type, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "SimpleUserType" } + + /** Gets the node corresponding to the field `arguments`. */ + final TypeArguments getArguments() { swift_simple_user_type_arguments(this, result) } + + /** Gets the node corresponding to the field `name`. */ + final TypeIdentifier getName() { swift_simple_user_type_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_simple_user_type_arguments(this, result) or swift_simple_user_type_def(this, result) + } + } + /** A class representing `source_file` nodes. */ class SourceFile extends @swift_source_file, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -2748,11 +2967,29 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SwitchEntry" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_switch_entry_child(this, i, result) } + /** Gets the node corresponding to the field `body`. */ + final Statements getBody() { swift_switch_entry_def(this, result) } + + /** Gets the node corresponding to the field `default`. */ + final DefaultKeyword getDefault() { swift_switch_entry_default(this, result) } + + /** Gets the node corresponding to the field `modifiers`. */ + final Modifiers getModifiers() { swift_switch_entry_modifiers(this, result) } + + /** Gets the node corresponding to the field `pattern`. */ + final SwitchPattern getPattern(int i) { swift_switch_entry_pattern(this, i, result) } + + /** Gets the node corresponding to the field `where`. */ + final WhereClause getWhere() { swift_switch_entry_where(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_switch_entry_child(this, _, result) } + final override AstNode getAFieldOrChild() { + swift_switch_entry_def(this, result) or + swift_switch_entry_default(this, result) or + swift_switch_entry_modifiers(this, result) or + swift_switch_entry_pattern(this, _, result) or + swift_switch_entry_where(this, result) + } } /** A class representing `switch_pattern` nodes. */ @@ -2760,8 +2997,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SwitchPattern" } - /** Gets the child of this node. */ - final Pattern getChild() { swift_switch_pattern_def(this, result) } + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { swift_switch_pattern_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_switch_pattern_def(this, result) } @@ -2870,6 +3107,35 @@ module Swift { } } + /** A class representing `tuple_pattern` nodes. */ + class TuplePattern extends @swift_tuple_pattern, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TuplePattern" } + + /** Gets the node corresponding to the field `item`. */ + final TuplePatternItem getItem(int i) { swift_tuple_pattern_item(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_tuple_pattern_item(this, _, result) } + } + + /** A class representing `tuple_pattern_item` nodes. */ + class TuplePatternItem extends @swift_tuple_pattern_item, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TuplePatternItem" } + + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_tuple_pattern_item_name(this, result) } + + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { swift_tuple_pattern_item_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_tuple_pattern_item_name(this, result) or swift_tuple_pattern_item_def(this, result) + } + } + /** A class representing `tuple_type` nodes. */ class TupleType extends @swift_tuple_type, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -2878,13 +3144,8 @@ module Swift { /** Gets the node corresponding to the field `element`. */ final TupleTypeItem getElement(int i) { swift_tuple_type_element(this, i, result) } - /** Gets the child of this node. */ - final TupleTypeItem getChild() { swift_tuple_type_child(this, result) } - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_tuple_type_element(this, _, result) or swift_tuple_type_child(this, result) - } + final override AstNode getAFieldOrChild() { swift_tuple_type_element(this, _, result) } } /** A class representing `tuple_type_item` nodes. */ @@ -2892,6 +3153,9 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TupleTypeItem" } + /** Gets the node corresponding to the field `external_name`. */ + final WildcardPattern getExternalName() { swift_tuple_type_item_external_name(this, result) } + /** Gets the node corresponding to the field `modifiers`. */ final ParameterModifiers getModifiers() { swift_tuple_type_item_modifiers(this, result) } @@ -2899,17 +3163,14 @@ module Swift { final SimpleIdentifier getName() { swift_tuple_type_item_name(this, result) } /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_tuple_type_item_type(this, result) } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_tuple_type_item_child(this, result) } + final AstNode getType() { swift_tuple_type_item_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + swift_tuple_type_item_external_name(this, result) or swift_tuple_type_item_modifiers(this, result) or swift_tuple_type_item_name(this, result) or - swift_tuple_type_item_type(this, result) or - swift_tuple_type_item_child(this, result) + swift_tuple_type_item_def(this, result) } } @@ -2954,6 +3215,24 @@ module Swift { final override AstNode getAFieldOrChild() { swift_type_arguments_argument(this, _, result) } } + /** A class representing `type_casting_pattern` nodes. */ + class TypeCastingPattern extends @swift_type_casting_pattern, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TypeCastingPattern" } + + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { swift_type_casting_pattern_pattern(this, result) } + + /** Gets the node corresponding to the field `type`. */ + final Type getType() { swift_type_casting_pattern_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_type_casting_pattern_pattern(this, result) or + swift_type_casting_pattern_def(this, result) + } + } + /** A class representing `type_constraint` nodes. */ class TypeConstraint extends @swift_type_constraint, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -3119,7 +3398,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "UserType" } /** Gets the node corresponding to the field `part`. */ - final AstNode getPart(int i) { swift_user_type_part(this, i, result) } + final SimpleUserType getPart(int i) { swift_user_type_part(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_user_type_part(this, _, result) } @@ -3158,8 +3437,8 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "ValueArgumentLabel" } - /** Gets the child of this node. */ - final SimpleIdentifier getChild() { swift_value_argument_label_def(this, result) } + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_value_argument_label_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_value_argument_label_def(this, result) } diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme index 1dfd0395e21..0c3f023b001 100644 --- a/unified/ql/lib/unified.dbscheme +++ b/unified/ql/lib/unified.dbscheme @@ -250,31 +250,33 @@ swift_attribute_def( int name: @swift_user_type ref ); -@swift_availability_condition_child_type = @swift_identifier | @swift_token_integer_literal - #keyset[swift_availability_condition, index] -swift_availability_condition_child( +swift_availability_condition_platform( int swift_availability_condition: @swift_availability_condition ref, int index: int ref, - unique int child: @swift_availability_condition_child_type ref + unique int platform: @swift_identifier ref +); + +#keyset[swift_availability_condition, index] +swift_availability_condition_version( + int swift_availability_condition: @swift_availability_condition ref, + int index: int ref, + unique int version: @swift_token_integer_literal ref ); swift_availability_condition_def( unique int id: @swift_availability_condition ); -swift_await_expression_expr( - unique int swift_await_expression: @swift_await_expression ref, - unique int expr: @swift_expression ref -); - -swift_await_expression_child( - unique int swift_await_expression: @swift_await_expression ref, - unique int child: @swift_expression ref -); - swift_await_expression_def( - unique int id: @swift_await_expression + unique int id: @swift_await_expression, + int expr: @swift_expression ref +); + +swift_binding_pattern_def( + unique int id: @swift_binding_pattern, + int binding: @swift_value_binding_pattern ref, + int pattern: @swift_pattern ref ); case @swift_bitwise_operation.op of @@ -293,27 +295,22 @@ swift_bitwise_operation_def( int rhs: @swift_expression ref ); -swift_call_expression_function( - unique int swift_call_expression: @swift_call_expression ref, - unique int function: @swift_expression ref -); - -swift_call_expression_suffix( - unique int swift_call_expression: @swift_call_expression ref, - unique int suffix: @swift_call_suffix ref -); - -@swift_call_expression_child_type = @swift_call_suffix | @swift_expression - -#keyset[swift_call_expression, index] -swift_call_expression_child( - int swift_call_expression: @swift_call_expression ref, - int index: int ref, - unique int child: @swift_call_expression_child_type ref -); - swift_call_expression_def( - unique int id: @swift_call_expression + unique int id: @swift_call_expression, + int function: @swift_expression ref, + int suffix: @swift_call_suffix ref +); + +swift_call_suffix_arguments( + unique int swift_call_suffix: @swift_call_suffix ref, + unique int arguments: @swift_value_arguments ref +); + +#keyset[swift_call_suffix, index] +swift_call_suffix_lambda( + int swift_call_suffix: @swift_call_suffix ref, + int index: int ref, + unique int lambda: @swift_lambda_literal ref ); #keyset[swift_call_suffix, index] @@ -323,15 +320,6 @@ swift_call_suffix_name( unique int name: @swift_token_simple_identifier ref ); -@swift_call_suffix_child_type = @swift_lambda_literal | @swift_value_arguments - -#keyset[swift_call_suffix, index] -swift_call_suffix_child( - int swift_call_suffix: @swift_call_suffix ref, - int index: int ref, - unique int child: @swift_call_suffix_child_type ref -); - swift_call_suffix_def( unique int id: @swift_call_suffix ); @@ -364,6 +352,21 @@ swift_capture_list_item_def( int name: @swift_capture_list_item_name_type ref ); +swift_case_pattern_arguments( + unique int swift_case_pattern: @swift_case_pattern ref, + unique int arguments: @swift_tuple_pattern ref +); + +swift_case_pattern_type( + unique int swift_case_pattern: @swift_case_pattern ref, + unique int type__: @swift_user_type ref +); + +swift_case_pattern_def( + unique int id: @swift_case_pattern, + int name: @swift_token_simple_identifier ref +); + swift_catch_block_body( unique int swift_catch_block: @swift_catch_block ref, unique int body: @swift_statements ref @@ -403,13 +406,6 @@ swift_class_body_member( unique int member: @swift_type_level_declaration ref ); -#keyset[swift_class_body, index] -swift_class_body_child( - int swift_class_body: @swift_class_body ref, - int index: int ref, - unique int child: @swift_token_multiline_comment ref -); - swift_class_body_def( unique int id: @swift_class_body ); @@ -432,6 +428,13 @@ case @swift_class_declaration.declaration_kind of ; +#keyset[swift_class_declaration, index] +swift_class_declaration_inherits( + int swift_class_declaration: @swift_class_declaration ref, + int index: int ref, + unique int inherits: @swift_inheritance_specifier ref +); + @swift_class_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier #keyset[swift_class_declaration, index] @@ -453,13 +456,6 @@ swift_class_declaration_type_parameters( unique int type_parameters: @swift_type_parameters ref ); -#keyset[swift_class_declaration, index] -swift_class_declaration_child( - int swift_class_declaration: @swift_class_declaration ref, - int index: int ref, - unique int child: @swift_inheritance_specifier ref -); - swift_class_declaration_def( unique int id: @swift_class_declaration, int body: @swift_class_declaration_body_type ref, @@ -482,6 +478,49 @@ swift_comparison_expression_def( int rhs: @swift_expression ref ); +swift_compilation_condition_inner( + unique int swift_compilation_condition: @swift_compilation_condition ref, + unique int inner: @swift_compilation_condition ref +); + +swift_compilation_condition_lhs( + unique int swift_compilation_condition: @swift_compilation_condition ref, + unique int lhs: @swift_compilation_condition ref +); + +#keyset[swift_compilation_condition, index] +swift_compilation_condition_name( + int swift_compilation_condition: @swift_compilation_condition ref, + int index: int ref, + unique int name: @swift_token_simple_identifier ref +); + +swift_compilation_condition_operand( + unique int swift_compilation_condition: @swift_compilation_condition ref, + unique int operand: @swift_compilation_condition ref +); + +swift_compilation_condition_rhs( + unique int swift_compilation_condition: @swift_compilation_condition ref, + unique int rhs: @swift_compilation_condition ref +); + +swift_compilation_condition_value( + unique int swift_compilation_condition: @swift_compilation_condition ref, + unique int value: @swift_token_boolean_literal ref +); + +#keyset[swift_compilation_condition, index] +swift_compilation_condition_version( + int swift_compilation_condition: @swift_compilation_condition ref, + int index: int ref, + unique int version: @swift_token_integer_literal ref +); + +swift_compilation_condition_def( + unique int id: @swift_compilation_condition +); + #keyset[swift_computed_getter, index] swift_computed_getter_attribute( int swift_computed_getter: @swift_computed_getter ref, @@ -576,6 +615,18 @@ swift_constructor_expression_def( int suffix: @swift_constructor_suffix ref ); +swift_constructor_suffix_arguments( + unique int swift_constructor_suffix: @swift_constructor_suffix ref, + unique int arguments: @swift_value_arguments ref +); + +#keyset[swift_constructor_suffix, index] +swift_constructor_suffix_lambda( + int swift_constructor_suffix: @swift_constructor_suffix ref, + int index: int ref, + unique int lambda: @swift_lambda_literal ref +); + #keyset[swift_constructor_suffix, index] swift_constructor_suffix_name( int swift_constructor_suffix: @swift_constructor_suffix ref, @@ -583,42 +634,20 @@ swift_constructor_suffix_name( unique int name: @swift_token_simple_identifier ref ); -@swift_constructor_suffix_child_type = @swift_lambda_literal | @swift_value_arguments - -#keyset[swift_constructor_suffix, index] -swift_constructor_suffix_child( - int swift_constructor_suffix: @swift_constructor_suffix ref, - int index: int ref, - unique int child: @swift_constructor_suffix_child_type ref -); - swift_constructor_suffix_def( unique int id: @swift_constructor_suffix ); -@swift_control_transfer_statement_kind_type = @swift_reserved_word - -swift_control_transfer_statement_kind( - unique int swift_control_transfer_statement: @swift_control_transfer_statement ref, - unique int kind: @swift_control_transfer_statement_kind_type ref -); +@swift_control_transfer_statement_kind_type = @swift_reserved_word | @swift_token_throw_keyword swift_control_transfer_statement_result( unique int swift_control_transfer_statement: @swift_control_transfer_statement ref, unique int result: @swift_expression ref ); -@swift_control_transfer_statement_child_type = @swift_expression | @swift_token_throw_keyword - -#keyset[swift_control_transfer_statement, index] -swift_control_transfer_statement_child( - int swift_control_transfer_statement: @swift_control_transfer_statement ref, - int index: int ref, - unique int child: @swift_control_transfer_statement_child_type ref -); - swift_control_transfer_statement_def( - unique int id: @swift_control_transfer_statement + unique int id: @swift_control_transfer_statement, + int kind: @swift_control_transfer_statement_kind_type ref ); swift_deinit_declaration_modifiers( @@ -631,13 +660,13 @@ swift_deinit_declaration_def( int body: @swift_function_body ref ); -@swift_deprecated_operator_declaration_body_child_type = @swift_line_string_literal | @swift_multi_line_string_literal | @swift_raw_string_literal | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_simple_identifier +@swift_deprecated_operator_declaration_body_entry_type = @swift_line_string_literal | @swift_multi_line_string_literal | @swift_raw_string_literal | @swift_reserved_word | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_simple_identifier #keyset[swift_deprecated_operator_declaration_body, index] -swift_deprecated_operator_declaration_body_child( +swift_deprecated_operator_declaration_body_entry( int swift_deprecated_operator_declaration_body: @swift_deprecated_operator_declaration_body ref, int index: int ref, - unique int child: @swift_deprecated_operator_declaration_body_child_type ref + unique int entry: @swift_deprecated_operator_declaration_body_entry_type ref ); swift_deprecated_operator_declaration_body_def( @@ -687,13 +716,9 @@ swift_didset_clause_def( unique int id: @swift_didset_clause ); -@swift_directive_child_type = @swift_token_boolean_literal | @swift_token_integer_literal | @swift_token_simple_identifier - -#keyset[swift_directive, index] -swift_directive_child( - int swift_directive: @swift_directive ref, - int index: int ref, - unique int child: @swift_directive_child_type ref +swift_directive_condition( + unique int swift_directive: @swift_directive ref, + unique int condition: @swift_compilation_condition ref ); swift_directive_def( @@ -776,13 +801,31 @@ swift_enum_entry_def( unique int id: @swift_enum_entry ); -@swift_enum_type_parameters_child_type = @swift_expression | @swift_token_wildcard_pattern | @swift_type__ +swift_enum_type_parameter_default_value( + unique int swift_enum_type_parameter: @swift_enum_type_parameter ref, + unique int default_value: @swift_expression ref +); + +swift_enum_type_parameter_external_name( + unique int swift_enum_type_parameter: @swift_enum_type_parameter ref, + unique int external_name: @swift_token_wildcard_pattern ref +); + +swift_enum_type_parameter_name( + unique int swift_enum_type_parameter: @swift_enum_type_parameter ref, + unique int name: @swift_token_simple_identifier ref +); + +swift_enum_type_parameter_def( + unique int id: @swift_enum_type_parameter, + int type__: @swift_type__ ref +); #keyset[swift_enum_type_parameters, index] -swift_enum_type_parameters_child( +swift_enum_type_parameters_parameter( int swift_enum_type_parameters: @swift_enum_type_parameters ref, int index: int ref, - unique int child: @swift_enum_type_parameters_child_type ref + unique int parameter: @swift_enum_type_parameter ref ); swift_enum_type_parameters_def( @@ -868,7 +911,7 @@ swift_function_body_def( swift_function_declaration_async( unique int swift_function_declaration: @swift_function_declaration ref, - unique int async: @swift_token_async_keyword ref + unique int async: @swift_reserved_word ref ); #keyset[swift_function_declaration, index] @@ -935,7 +978,7 @@ swift_function_declaration_def( swift_function_type_async( unique int swift_function_type: @swift_function_type ref, - unique int async: @swift_token_async_keyword ref + unique int async: @swift_reserved_word ref ); @swift_function_type_throws_type = @swift_throws_clause | @swift_token_throws @@ -1006,9 +1049,9 @@ swift_if_condition_def( int kind: @swift_if_condition_kind_type ref ); -swift_if_let_binding_bound_identifier( +swift_if_let_binding_type( unique int swift_if_let_binding: @swift_if_let_binding ref, - unique int bound_identifier: @swift_token_simple_identifier ref + unique int type__: @swift_type_annotation ref ); swift_if_let_binding_value( @@ -1021,17 +1064,9 @@ swift_if_let_binding_where( unique int where: @swift_where_clause ref ); -@swift_if_let_binding_child_type = @swift_pattern | @swift_token_simple_identifier | @swift_token_wildcard_pattern | @swift_type__ | @swift_type_annotation | @swift_user_type | @swift_value_binding_pattern - -#keyset[swift_if_let_binding, index] -swift_if_let_binding_child( - int swift_if_let_binding: @swift_if_let_binding ref, - int index: int ref, - unique int child: @swift_if_let_binding_child_type ref -); - swift_if_let_binding_def( - unique int id: @swift_if_let_binding + unique int id: @swift_if_let_binding, + int pattern: @swift_pattern ref ); #keyset[swift_if_statement, index] @@ -1110,7 +1145,7 @@ swift_inheritance_specifier_def( swift_init_declaration_async( unique int swift_init_declaration: @swift_init_declaration ref, - unique int async: @swift_token_async_keyword ref + unique int async: @swift_reserved_word ref ); #keyset[swift_init_declaration, index] @@ -1202,19 +1237,56 @@ swift_interpolated_expression_def( unique int id: @swift_interpolated_expression ); -@swift_key_path_expression_child_type = @swift_array_type | @swift_dictionary_type | @swift_token_bang | @swift_token_simple_identifier | @swift_token_type_identifier | @swift_type_arguments | @swift_value_argument +swift_key_path_component_name( + unique int swift_key_path_component: @swift_key_path_component ref, + unique int name: @swift_token_simple_identifier ref +); + +#keyset[swift_key_path_component, index] +swift_key_path_component_postfix( + int swift_key_path_component: @swift_key_path_component ref, + int index: int ref, + unique int postfix: @swift_key_path_postfix ref +); + +swift_key_path_component_def( + unique int id: @swift_key_path_component +); #keyset[swift_key_path_expression, index] -swift_key_path_expression_child( +swift_key_path_expression_component( int swift_key_path_expression: @swift_key_path_expression ref, int index: int ref, - unique int child: @swift_key_path_expression_child_type ref + unique int component: @swift_key_path_component ref +); + +@swift_key_path_expression_type_type = @swift_array_type | @swift_dictionary_type | @swift_simple_user_type + +swift_key_path_expression_type( + unique int swift_key_path_expression: @swift_key_path_expression ref, + unique int type__: @swift_key_path_expression_type_type ref ); swift_key_path_expression_def( unique int id: @swift_key_path_expression ); +#keyset[swift_key_path_postfix, index] +swift_key_path_postfix_argument( + int swift_key_path_postfix: @swift_key_path_postfix ref, + int index: int ref, + unique int argument: @swift_value_argument ref +); + +swift_key_path_postfix_force_unwrap( + unique int swift_key_path_postfix: @swift_key_path_postfix ref, + unique int force_unwrap: @swift_token_bang ref +); + +swift_key_path_postfix_def( + unique int id: @swift_key_path_postfix +); + swift_key_path_string_expression_def( unique int id: @swift_key_path_string_expression, int expr: @swift_expression ref @@ -1222,7 +1294,7 @@ swift_key_path_string_expression_def( swift_lambda_function_type_async( unique int swift_lambda_function_type: @swift_lambda_function_type ref, - unique int async: @swift_token_async_keyword ref + unique int async: @swift_reserved_word ref ); swift_lambda_function_type_params( @@ -1350,6 +1422,11 @@ swift_macro_declaration_definition( unique int definition: @swift_macro_definition ref ); +swift_macro_declaration_modifiers( + unique int swift_macro_declaration: @swift_macro_declaration ref, + unique int modifiers: @swift_modifiers ref +); + #keyset[swift_macro_declaration, index] swift_macro_declaration_parameter( int swift_macro_declaration: @swift_macro_declaration ref, @@ -1357,17 +1434,24 @@ swift_macro_declaration_parameter( unique int parameter: @swift_parameter ref ); -@swift_macro_declaration_child_type = @swift_modifiers | @swift_token_simple_identifier | @swift_type_constraints | @swift_type_parameters | @swift_unannotated_type +swift_macro_declaration_return_type( + unique int swift_macro_declaration: @swift_macro_declaration ref, + unique int return_type: @swift_unannotated_type ref +); -#keyset[swift_macro_declaration, index] -swift_macro_declaration_child( - int swift_macro_declaration: @swift_macro_declaration ref, - int index: int ref, - unique int child: @swift_macro_declaration_child_type ref +swift_macro_declaration_type_constraints( + unique int swift_macro_declaration: @swift_macro_declaration ref, + unique int type_constraints: @swift_type_constraints ref +); + +swift_macro_declaration_type_parameters( + unique int swift_macro_declaration: @swift_macro_declaration ref, + unique int type_parameters: @swift_type_parameters ref ); swift_macro_declaration_def( - unique int id: @swift_macro_declaration + unique int id: @swift_macro_declaration, + int name: @swift_token_simple_identifier ref ); @swift_macro_definition_body_type = @swift_expression | @swift_external_macro_definition @@ -1449,18 +1533,12 @@ swift_multiplicative_expression_def( int rhs: @swift_expression ref ); -@swift_navigation_expression_target_type = @swift_array_type | @swift_dictionary_type | @swift_existential_type | @swift_expression | @swift_opaque_type | @swift_reserved_word | @swift_user_type - -#keyset[swift_navigation_expression, index] -swift_navigation_expression_target( - int swift_navigation_expression: @swift_navigation_expression ref, - int index: int ref, - unique int target: @swift_navigation_expression_target_type ref -); +@swift_navigation_expression_target_type = @swift_array_type | @swift_dictionary_type | @swift_expression | @swift_parenthesized_type | @swift_user_type swift_navigation_expression_def( unique int id: @swift_navigation_expression, - int suffix: @swift_navigation_suffix ref + int suffix: @swift_navigation_suffix ref, + int target: @swift_navigation_expression_target_type ref ); @swift_navigation_suffix_suffix_type = @swift_token_integer_literal | @swift_token_simple_identifier @@ -1567,22 +1645,28 @@ swift_parameter_modifiers_def( unique int id: @swift_parameter_modifiers ); +@swift_parenthesized_type_type_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type + +swift_parenthesized_type_def( + unique int id: @swift_parenthesized_type, + int type__: @swift_parenthesized_type_type_type ref +); + +swift_pattern_binding( + unique int swift_pattern: @swift_pattern ref, + unique int binding: @swift_value_binding_pattern ref +); + swift_pattern_bound_identifier( unique int swift_pattern: @swift_pattern ref, unique int bound_identifier: @swift_token_simple_identifier ref ); -@swift_pattern_child_type = @swift_expression | @swift_pattern | @swift_token_wildcard_pattern | @swift_type__ | @swift_user_type | @swift_value_binding_pattern - -#keyset[swift_pattern, index] -swift_pattern_child( - int swift_pattern: @swift_pattern ref, - int index: int ref, - unique int child: @swift_pattern_child_type ref -); +@swift_pattern_kind_type = @swift_binding_pattern | @swift_case_pattern | @swift_expression | @swift_token_wildcard_pattern | @swift_tuple_pattern | @swift_type_casting_pattern swift_pattern_def( - unique int id: @swift_pattern + unique int id: @swift_pattern, + int kind: @swift_pattern_kind_type ref ); #keyset[swift_playground_literal, index] @@ -1671,6 +1755,27 @@ swift_property_declaration_name( unique int name: @swift_pattern ref ); +#keyset[swift_property_declaration, index] +swift_property_declaration_observers( + int swift_property_declaration: @swift_property_declaration ref, + int index: int ref, + unique int observers: @swift_willset_didset_block ref +); + +#keyset[swift_property_declaration, index] +swift_property_declaration_type( + int swift_property_declaration: @swift_property_declaration ref, + int index: int ref, + unique int type__: @swift_type_annotation ref +); + +#keyset[swift_property_declaration, index] +swift_property_declaration_type_constraints( + int swift_property_declaration: @swift_property_declaration ref, + int index: int ref, + unique int type_constraints: @swift_type_constraints ref +); + #keyset[swift_property_declaration, index] swift_property_declaration_value( int swift_property_declaration: @swift_property_declaration ref, @@ -1678,17 +1783,9 @@ swift_property_declaration_value( unique int value: @swift_expression ref ); -@swift_property_declaration_child_type = @swift_type_annotation | @swift_type_constraints | @swift_value_binding_pattern | @swift_willset_didset_block - -#keyset[swift_property_declaration, index] -swift_property_declaration_child( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int child: @swift_property_declaration_child_type ref -); - swift_property_declaration_def( - unique int id: @swift_property_declaration + unique int id: @swift_property_declaration, + int binding: @swift_value_binding_pattern ref ); #keyset[swift_protocol_body, index] @@ -1725,6 +1822,13 @@ case @swift_protocol_declaration.declaration_kind of ; +#keyset[swift_protocol_declaration, index] +swift_protocol_declaration_inherits( + int swift_protocol_declaration: @swift_protocol_declaration ref, + int index: int ref, + unique int inherits: @swift_inheritance_specifier ref +); + swift_protocol_declaration_modifiers( unique int swift_protocol_declaration: @swift_protocol_declaration ref, unique int modifiers: @swift_modifiers ref @@ -1740,13 +1844,6 @@ swift_protocol_declaration_type_parameters( unique int type_parameters: @swift_type_parameters ref ); -#keyset[swift_protocol_declaration, index] -swift_protocol_declaration_child( - int swift_protocol_declaration: @swift_protocol_declaration ref, - int index: int ref, - unique int child: @swift_inheritance_specifier ref -); - swift_protocol_declaration_def( unique int id: @swift_protocol_declaration, int body: @swift_protocol_body ref, @@ -1756,7 +1853,7 @@ swift_protocol_declaration_def( swift_protocol_function_declaration_async( unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int async: @swift_token_async_keyword ref + unique int async: @swift_reserved_word ref ); #keyset[swift_protocol_function_declaration, index] @@ -1946,6 +2043,16 @@ swift_setter_specifier_def( unique int id: @swift_setter_specifier ); +swift_simple_user_type_arguments( + unique int swift_simple_user_type: @swift_simple_user_type ref, + unique int arguments: @swift_type_arguments ref +); + +swift_simple_user_type_def( + unique int id: @swift_simple_user_type, + int name: @swift_token_type_identifier ref +); + swift_source_file_shebang( unique int swift_source_file: @swift_source_file ref, unique int shebang: @swift_token_shebang_line ref @@ -2030,22 +2137,36 @@ swift_suppressed_constraint_def( int suppressed: @swift_token_type_identifier ref ); -@swift_switch_entry_child_type = @swift_expression | @swift_modifiers | @swift_statements | @swift_switch_pattern | @swift_token_default_keyword | @swift_token_where_keyword +swift_switch_entry_default( + unique int swift_switch_entry: @swift_switch_entry ref, + unique int default: @swift_token_default_keyword ref +); + +swift_switch_entry_modifiers( + unique int swift_switch_entry: @swift_switch_entry ref, + unique int modifiers: @swift_modifiers ref +); #keyset[swift_switch_entry, index] -swift_switch_entry_child( +swift_switch_entry_pattern( int swift_switch_entry: @swift_switch_entry ref, int index: int ref, - unique int child: @swift_switch_entry_child_type ref + unique int pattern: @swift_switch_pattern ref +); + +swift_switch_entry_where( + unique int swift_switch_entry: @swift_switch_entry ref, + unique int where: @swift_where_clause ref ); swift_switch_entry_def( - unique int id: @swift_switch_entry + unique int id: @swift_switch_entry, + int body: @swift_statements ref ); swift_switch_pattern_def( unique int id: @swift_switch_pattern, - int child: @swift_pattern ref + int pattern: @swift_pattern ref ); #keyset[swift_switch_statement, index] @@ -2096,6 +2217,27 @@ swift_tuple_expression_def( unique int id: @swift_tuple_expression ); +#keyset[swift_tuple_pattern, index] +swift_tuple_pattern_item( + int swift_tuple_pattern: @swift_tuple_pattern ref, + int index: int ref, + unique int item: @swift_tuple_pattern_item ref +); + +swift_tuple_pattern_def( + unique int id: @swift_tuple_pattern +); + +swift_tuple_pattern_item_name( + unique int swift_tuple_pattern_item: @swift_tuple_pattern_item ref, + unique int name: @swift_token_simple_identifier ref +); + +swift_tuple_pattern_item_def( + unique int id: @swift_tuple_pattern_item, + int pattern: @swift_pattern ref +); + #keyset[swift_tuple_type, index] swift_tuple_type_element( int swift_tuple_type: @swift_tuple_type ref, @@ -2103,15 +2245,15 @@ swift_tuple_type_element( unique int element: @swift_tuple_type_item ref ); -swift_tuple_type_child( - unique int swift_tuple_type: @swift_tuple_type ref, - unique int child: @swift_tuple_type_item ref -); - swift_tuple_type_def( unique int id: @swift_tuple_type ); +swift_tuple_type_item_external_name( + unique int swift_tuple_type_item: @swift_tuple_type_item ref, + unique int external_name: @swift_token_wildcard_pattern ref +); + swift_tuple_type_item_modifiers( unique int swift_tuple_type_item: @swift_tuple_type_item ref, unique int modifiers: @swift_parameter_modifiers ref @@ -2122,20 +2264,11 @@ swift_tuple_type_item_name( unique int name: @swift_token_simple_identifier ref ); -swift_tuple_type_item_type( - unique int swift_tuple_type_item: @swift_tuple_type_item ref, - unique int type__: @swift_type__ ref -); - -@swift_tuple_type_item_child_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type | @swift_token_wildcard_pattern - -swift_tuple_type_item_child( - unique int swift_tuple_type_item: @swift_tuple_type_item ref, - unique int child: @swift_tuple_type_item_child_type ref -); +@swift_tuple_type_item_type_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type | @swift_type__ swift_tuple_type_item_def( - unique int id: @swift_tuple_type_item + unique int id: @swift_tuple_type_item, + int type__: @swift_tuple_type_item_type_type ref ); swift_type_modifiers( @@ -2166,6 +2299,16 @@ swift_type_arguments_def( unique int id: @swift_type_arguments ); +swift_type_casting_pattern_pattern( + unique int swift_type_casting_pattern: @swift_type_casting_pattern ref, + unique int pattern: @swift_pattern ref +); + +swift_type_casting_pattern_def( + unique int id: @swift_type_casting_pattern, + int type__: @swift_type__ ref +); + @swift_type_constraint_constraint_type = @swift_equality_constraint | @swift_inheritance_constraint swift_type_constraint_def( @@ -2274,13 +2417,11 @@ swift_typealias_declaration_def( @swift_unannotated_type = @swift_array_type | @swift_dictionary_type | @swift_existential_type | @swift_function_type | @swift_metatype | @swift_opaque_type | @swift_optional_type | @swift_protocol_composition_type | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type -@swift_user_type_part_type = @swift_token_type_identifier | @swift_type_arguments - #keyset[swift_user_type, index] swift_user_type_part( int swift_user_type: @swift_user_type ref, int index: int ref, - unique int part: @swift_user_type_part_type ref + unique int part: @swift_simple_user_type ref ); swift_user_type_def( @@ -2315,7 +2456,7 @@ swift_value_argument_def( swift_value_argument_label_def( unique int id: @swift_value_argument_label, - int child: @swift_token_simple_identifier ref + int name: @swift_token_simple_identifier ref ); #keyset[swift_value_arguments, index] @@ -2462,7 +2603,7 @@ case @swift_token.kind of ; -@swift_ast_node = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_associatedtype_declaration | @swift_attribute | @swift_availability_condition | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_call_suffix | @swift_capture_list | @swift_capture_list_item | @swift_catch_block | @swift_check_expression | @swift_class_body | @swift_class_declaration | @swift_comparison_expression | @swift_computed_getter | @swift_computed_modify | @swift_computed_property | @swift_computed_setter | @swift_conjunction_expression | @swift_constructor_expression | @swift_constructor_suffix | @swift_control_transfer_statement | @swift_deinit_declaration | @swift_deprecated_operator_declaration_body | @swift_dictionary_literal | @swift_dictionary_type | @swift_didset_clause | @swift_directive | @swift_directly_assignable_expression | @swift_disjunction_expression | @swift_do_statement | @swift_enum_class_body | @swift_enum_entry | @swift_enum_type_parameters | @swift_equality_constraint | @swift_equality_expression | @swift_existential_type | @swift_external_macro_definition | @swift_for_statement | @swift_function_body | @swift_function_declaration | @swift_function_type | @swift_getter_specifier | @swift_guard_statement | @swift_identifier | @swift_if_condition | @swift_if_let_binding | @swift_if_statement | @swift_implicitly_unwrapped_type | @swift_import_declaration | @swift_infix_expression | @swift_inheritance_constraint | @swift_inheritance_specifier | @swift_init_declaration | @swift_interpolated_expression | @swift_key_path_expression | @swift_key_path_string_expression | @swift_lambda_function_type | @swift_lambda_function_type_parameters | @swift_lambda_literal | @swift_lambda_parameter | @swift_line_string_literal | @swift_macro_declaration | @swift_macro_definition | @swift_macro_invocation | @swift_metatype | @swift_modifiers | @swift_modify_specifier | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_navigation_suffix | @swift_nested_type_identifier | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_operator_declaration | @swift_optional_chain_marker | @swift_optional_type | @swift_parameter | @swift_parameter_modifiers | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_precedence_group_attribute | @swift_precedence_group_attributes | @swift_precedence_group_declaration | @swift_prefix_expression | @swift_property_declaration | @swift_protocol_body | @swift_protocol_composition_type | @swift_protocol_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_protocol_property_requirements | @swift_range_expression | @swift_raw_str_interpolation | @swift_raw_string_literal | @swift_referenceable_operator | @swift_repeat_while_statement | @swift_selector_expression | @swift_setter_specifier | @swift_source_file | @swift_statements | @swift_subscript_declaration | @swift_suppressed_constraint | @swift_switch_entry | @swift_switch_pattern | @swift_switch_statement | @swift_ternary_expression | @swift_throws_clause | @swift_token | @swift_try_expression | @swift_tuple_expression | @swift_tuple_type | @swift_tuple_type_item | @swift_type__ | @swift_type_annotation | @swift_type_arguments | @swift_type_constraint | @swift_type_constraints | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter | @swift_type_parameter_modifiers | @swift_type_parameter_pack | @swift_type_parameters | @swift_typealias_declaration | @swift_user_type | @swift_value_argument | @swift_value_argument_label | @swift_value_arguments | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause | @swift_while_statement | @swift_willset_clause | @swift_willset_didset_block +@swift_ast_node = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_associatedtype_declaration | @swift_attribute | @swift_availability_condition | @swift_await_expression | @swift_binding_pattern | @swift_bitwise_operation | @swift_call_expression | @swift_call_suffix | @swift_capture_list | @swift_capture_list_item | @swift_case_pattern | @swift_catch_block | @swift_check_expression | @swift_class_body | @swift_class_declaration | @swift_comparison_expression | @swift_compilation_condition | @swift_computed_getter | @swift_computed_modify | @swift_computed_property | @swift_computed_setter | @swift_conjunction_expression | @swift_constructor_expression | @swift_constructor_suffix | @swift_control_transfer_statement | @swift_deinit_declaration | @swift_deprecated_operator_declaration_body | @swift_dictionary_literal | @swift_dictionary_type | @swift_didset_clause | @swift_directive | @swift_directly_assignable_expression | @swift_disjunction_expression | @swift_do_statement | @swift_enum_class_body | @swift_enum_entry | @swift_enum_type_parameter | @swift_enum_type_parameters | @swift_equality_constraint | @swift_equality_expression | @swift_existential_type | @swift_external_macro_definition | @swift_for_statement | @swift_function_body | @swift_function_declaration | @swift_function_type | @swift_getter_specifier | @swift_guard_statement | @swift_identifier | @swift_if_condition | @swift_if_let_binding | @swift_if_statement | @swift_implicitly_unwrapped_type | @swift_import_declaration | @swift_infix_expression | @swift_inheritance_constraint | @swift_inheritance_specifier | @swift_init_declaration | @swift_interpolated_expression | @swift_key_path_component | @swift_key_path_expression | @swift_key_path_postfix | @swift_key_path_string_expression | @swift_lambda_function_type | @swift_lambda_function_type_parameters | @swift_lambda_literal | @swift_lambda_parameter | @swift_line_string_literal | @swift_macro_declaration | @swift_macro_definition | @swift_macro_invocation | @swift_metatype | @swift_modifiers | @swift_modify_specifier | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_navigation_suffix | @swift_nested_type_identifier | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_operator_declaration | @swift_optional_chain_marker | @swift_optional_type | @swift_parameter | @swift_parameter_modifiers | @swift_parenthesized_type | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_precedence_group_attribute | @swift_precedence_group_attributes | @swift_precedence_group_declaration | @swift_prefix_expression | @swift_property_declaration | @swift_protocol_body | @swift_protocol_composition_type | @swift_protocol_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_protocol_property_requirements | @swift_range_expression | @swift_raw_str_interpolation | @swift_raw_string_literal | @swift_referenceable_operator | @swift_repeat_while_statement | @swift_selector_expression | @swift_setter_specifier | @swift_simple_user_type | @swift_source_file | @swift_statements | @swift_subscript_declaration | @swift_suppressed_constraint | @swift_switch_entry | @swift_switch_pattern | @swift_switch_statement | @swift_ternary_expression | @swift_throws_clause | @swift_token | @swift_try_expression | @swift_tuple_expression | @swift_tuple_pattern | @swift_tuple_pattern_item | @swift_tuple_type | @swift_tuple_type_item | @swift_type__ | @swift_type_annotation | @swift_type_arguments | @swift_type_casting_pattern | @swift_type_constraint | @swift_type_constraints | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter | @swift_type_parameter_modifiers | @swift_type_parameter_pack | @swift_type_parameters | @swift_typealias_declaration | @swift_user_type | @swift_value_argument | @swift_value_argument_label | @swift_value_arguments | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause | @swift_while_statement | @swift_willset_clause | @swift_willset_didset_block swift_ast_node_location( unique int node: @swift_ast_node ref, From f668b99d6df0d7ba7a334aa4c98469fd002c7788 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 7 May 2026 11:33:04 +0200 Subject: [PATCH 047/226] Unified: Add support for tree-sitter-style corpus tests This adds tests consisting of source code and a printout of its rewritten AST. --- unified/AGENTS.md | 11 +- unified/extractor/src/extractor.rs | 8 +- unified/extractor/src/languages/mod.rs | 8 + unified/extractor/src/main.rs | 1 + .../extractor/tests/corpus/swift/desugar.txt | 23 +++ unified/extractor/tests/corpus_tests.rs | 182 ++++++++++++++++++ unified/scripts/update-corpus.sh | 8 + 7 files changed, 232 insertions(+), 9 deletions(-) create mode 100644 unified/extractor/src/languages/mod.rs create mode 100644 unified/extractor/tests/corpus/swift/desugar.txt create mode 100644 unified/extractor/tests/corpus_tests.rs create mode 100755 unified/scripts/update-corpus.sh diff --git a/unified/AGENTS.md b/unified/AGENTS.md index 488a94f44bd..aa5007a5656 100644 --- a/unified/AGENTS.md +++ b/unified/AGENTS.md @@ -20,10 +20,15 @@ grammar source), run `scripts/regenerate-grammar.sh` to: it shows the impact of a grammar tweak on the named node kinds, fields, and child types in a form much easier to read than the raw JSON. -## Testing -- If you changed the extractor code, always rebuild it before running tests. +## Extractor Testing +- To run extractor tests, run `cargo test` in the `extractor` directory. -- To run all tests, run `codeql test run --search-path extractor-pack ql/test` +- Do not edit the printed ASTs in `extractor/test/corpus` directly. To regenerate the ASTs, run `scripts/update-corpus.sh`. + +## CodeQL Testing +- If you changed the extractor code, always rebuild it before running CodeQL tests. + +- To run all CodeQL tests, run `codeql test run --search-path extractor-pack ql/test` - Do not edit `.expected` files manually. To update the expected output, pass `--learn` to the `codeql test run` command. diff --git a/unified/extractor/src/extractor.rs b/unified/extractor/src/extractor.rs index eb6f06eb259..ae3c1e78715 100644 --- a/unified/extractor/src/extractor.rs +++ b/unified/extractor/src/extractor.rs @@ -3,9 +3,7 @@ use std::path::PathBuf; use codeql_extractor::extractor::simple; use codeql_extractor::trap; - -#[path = "languages/swift/swift.rs"] -mod swift; +use crate::languages; #[derive(Args)] pub struct Options { @@ -27,9 +25,7 @@ pub fn run(options: Options) -> std::io::Result<()> { let extractor = simple::Extractor { prefix: "unified".to_string(), - languages: vec![ - swift::language_spec(), - ], + languages: languages::all_language_specs(), trap_dir: options.output_dir, trap_compression: trap::Compression::from_env("CODEQL_EXTRACTOR_UNIFIED_OPTION_TRAP_COMPRESSION"), source_archive_dir: options.source_archive_dir, diff --git a/unified/extractor/src/languages/mod.rs b/unified/extractor/src/languages/mod.rs new file mode 100644 index 00000000000..4d5c945cb9b --- /dev/null +++ b/unified/extractor/src/languages/mod.rs @@ -0,0 +1,8 @@ +use codeql_extractor::extractor::simple; + +#[path = "swift/swift.rs"] +mod swift; + +pub fn all_language_specs() -> Vec { + vec![swift::language_spec()] +} diff --git a/unified/extractor/src/main.rs b/unified/extractor/src/main.rs index e6721d4e224..5a3407c37a2 100644 --- a/unified/extractor/src/main.rs +++ b/unified/extractor/src/main.rs @@ -3,6 +3,7 @@ use clap::Parser; mod autobuilder; mod extractor; mod generator; +mod languages; #[derive(Parser)] #[command(author, version, about)] diff --git a/unified/extractor/tests/corpus/swift/desugar.txt b/unified/extractor/tests/corpus/swift/desugar.txt new file mode 100644 index 00000000000..1ea0e260aad --- /dev/null +++ b/unified/extractor/tests/corpus/swift/desugar.txt @@ -0,0 +1,23 @@ +=== +Additive expression is desugared +=== + +1 + 2 + +--- + +source_file + simple_identifier "blah" + + +=== +Another additive expression is desugared +=== + +foo + bar + +--- + +source_file + simple_identifier "blah" + diff --git a/unified/extractor/tests/corpus_tests.rs b/unified/extractor/tests/corpus_tests.rs new file mode 100644 index 00000000000..2667647a589 --- /dev/null +++ b/unified/extractor/tests/corpus_tests.rs @@ -0,0 +1,182 @@ +use std::fs; +use std::path::Path; + +use codeql_extractor::extractor::simple; +use yeast::{dump::dump_ast, Runner}; + +#[path = "../src/languages/mod.rs"] +mod languages; + +#[derive(Debug)] +struct CorpusCase { + name: String, + input: String, + expected: String, +} + +fn update_mode_enabled() -> bool { + std::env::var("UNIFIED_UPDATE_CORPUS") + .map(|v| matches!(v.to_ascii_lowercase().as_str(), "1" | "true" | "yes" | "on")) + .unwrap_or(false) +} + +fn is_header_rule(line: &str) -> bool { + let trimmed = line.trim(); + trimmed.len() >= 3 && trimmed.chars().all(|c| c == '=') +} + +fn parse_corpus(content: &str) -> Vec { + let lines: Vec<&str> = content.lines().collect(); + let mut i = 0; + let mut cases = Vec::new(); + + while i < lines.len() { + while i < lines.len() && lines[i].trim().is_empty() { + i += 1; + } + if i >= lines.len() { + break; + } + + assert!( + is_header_rule(lines[i]), + "Expected header delimiter at line {}", + i + 1 + ); + i += 1; + + assert!(i < lines.len(), "Missing test name at line {}", i + 1); + let name = lines[i].trim().to_string(); + i += 1; + + assert!( + i < lines.len() && is_header_rule(lines[i]), + "Missing closing header delimiter for case {name}" + ); + i += 1; + + let input_start = i; + while i < lines.len() && lines[i].trim() != "---" { + i += 1; + } + assert!(i < lines.len(), "Missing --- separator for case {name}"); + let input = lines[input_start..i].join("\n").trim_end().to_string(); + i += 1; + + let expected_start = i; + while i < lines.len() { + if is_header_rule(lines[i]) + && i + 2 < lines.len() + && !lines[i + 1].trim().is_empty() + && is_header_rule(lines[i + 2]) + { + break; + } + i += 1; + } + let expected = lines[expected_start..i].join("\n").trim().to_string(); + + cases.push(CorpusCase { + name, + input, + expected, + }); + } + + cases +} + +fn render_corpus(cases: &[CorpusCase]) -> String { + let mut out = String::new(); + + for (idx, case) in cases.iter().enumerate() { + if idx > 0 { + out.push('\n'); + } + out.push_str("===\n"); + out.push_str(case.name.trim()); + out.push_str("\n===\n"); + out.push('\n'); + out.push_str(case.input.trim()); + out.push_str("\n\n---\n"); + out.push('\n'); + out.push_str(case.expected.trim()); + out.push_str("\n\n"); + } + + out +} + +fn run_desugaring(lang: &simple::LanguageSpec, input: &str) -> String { + let runner = match lang.desugar.as_ref() { + Some(config) => Runner::from_config(lang.ts_language.clone(), config) + .expect("Failed to create yeast runner from desugaring config"), + None => Runner::new(lang.ts_language.clone(), &[]), + }; + let ast = runner + .run(input) + .unwrap_or_else(|e| panic!("Failed to parse corpus input: {e}")); + dump_ast(&ast, ast.get_root(), input) +} + +#[test] +fn test_corpus() { + let update_mode = update_mode_enabled(); + let all_languages = languages::all_language_specs(); + let corpus_dir = Path::new("tests/corpus"); + + for lang in all_languages { + let lang_corpus_dir = corpus_dir.join(&lang.prefix); + if !lang_corpus_dir.exists() { + continue; + } + + let mut corpus_files: Vec<_> = fs::read_dir(&lang_corpus_dir) + .unwrap_or_else(|e| { + panic!( + "Failed to read corpus directory {}: {e}", + lang_corpus_dir.display() + ) + }) + .map(|entry| entry.expect("Failed to read corpus entry").path()) + .filter(|path| path.extension().is_some_and(|ext| ext == "txt")) + .collect(); + corpus_files.sort(); + + for corpus_path in corpus_files { + let content = fs::read_to_string(&corpus_path) + .unwrap_or_else(|e| panic!("Failed to read {}: {e}", corpus_path.display())); + let mut cases = parse_corpus(&content); + assert!( + !cases.is_empty(), + "No corpus cases found in {}", + corpus_path.display() + ); + + for case in &mut cases { + let actual = run_desugaring(&lang, &case.input); + if update_mode { + case.expected = actual.trim().to_string(); + } else { + assert_eq!( + case.expected.trim(), + actual.trim(), + "Corpus case failed in {}: {}", + corpus_path.display(), + case.name + ); + } + } + + if update_mode { + let updated = render_corpus(&cases); + fs::write(&corpus_path, updated).unwrap_or_else(|e| { + panic!( + "Failed to update corpus file {}: {e}", + corpus_path.display() + ) + }); + } + } + } +} diff --git a/unified/scripts/update-corpus.sh b/unified/scripts/update-corpus.sh new file mode 100755 index 00000000000..2f3ebade8cb --- /dev/null +++ b/unified/scripts/update-corpus.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +cd "$(dirname "$0")/.." + +cd extractor +UNIFIED_UPDATE_CORPUS=1 cargo test From 49f19092fb985c955913b2e6ea7565c4a45bbc98 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 7 May 2026 13:55:36 +0200 Subject: [PATCH 048/226] Yeast: add reachable_node_ids() --- shared/yeast/src/lib.rs | 33 +++++++++++++++++++++++++++++++++ shared/yeast/tests/test.rs | 22 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index 281f44a98b2..c06029a8626 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -193,10 +193,43 @@ impl Ast { AstCursor::new(self) } + /// Return all nodes currently allocated in the AST arena. + /// + /// This includes nodes that are no longer reachable from `get_root()` + /// after desugaring rewrites. Use `reachable_node_ids()` for output-level + /// validation/traversal semantics. pub fn nodes(&self) -> &[Node] { &self.nodes } + /// Return node ids reachable from `get_root()` by following child edges. + /// + /// This reflects the effective AST after desugaring and excludes orphaned + /// arena nodes left behind by rewrite operations. + pub fn reachable_node_ids(&self) -> Vec { + let mut reachable = Vec::new(); + let mut stack = vec![self.root]; + let mut seen = vec![false; self.nodes.len()]; + + while let Some(id) = stack.pop() { + if id >= self.nodes.len() || seen[id] { + continue; + } + seen[id] = true; + reachable.push(id); + + if let Some(node) = self.get_node(id) { + for children in node.fields.values() { + for &child in children { + stack.push(child); + } + } + } + } + + reachable + } + pub fn get_root(&self) -> Id { self.root } diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index ed4202493a4..e058e6b1eb0 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -166,6 +166,28 @@ fn test_query_no_match() { assert!(!matched); } +#[test] +fn test_reachable_nodes_excludes_orphaned_rewrite_nodes() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang) + .unwrap(); + let rules = vec![yeast::rule!((integer) => (identifier "replaced"))]; + let runner = Runner::with_schema(lang, &schema, &rules); + + let input = "x = 1"; + let ast = runner.run(input).unwrap(); + let reachable_ids = ast.reachable_node_ids(); + + assert!( + ast.nodes().len() > reachable_ids.len(), + "expected rewrite to leave orphaned arena nodes" + ); + + let dump = dump_ast(&ast, ast.get_root(), input); + assert!(dump.contains("identifier \"replaced\"")); + assert!(!dump.contains("integer \"1\"")); +} + #[test] fn test_query_repeated_capture() { let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); From a049850c51b54d4a65278a50ebbe13560ef155d9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 7 May 2026 22:50:30 +0200 Subject: [PATCH 049/226] Yeast: add type-checking errors in AST dump --- shared/yeast/src/dump.rs | 201 +++++++++++++++++++++++++++- shared/yeast/src/node_types_yaml.rs | 139 ++++++++++++------- shared/yeast/src/schema.rs | 76 ++++++++++- shared/yeast/tests/test.rs | 110 ++++++++++++++- 4 files changed, 467 insertions(+), 59 deletions(-) diff --git a/shared/yeast/src/dump.rs b/shared/yeast/src/dump.rs index 99ba019cc3e..07ee134e058 100644 --- a/shared/yeast/src/dump.rs +++ b/shared/yeast/src/dump.rs @@ -1,6 +1,6 @@ use std::fmt::Write; -use crate::{Ast, Node, NodeContent, CHILD_FIELD}; +use crate::{schema::Schema, Ast, Node, NodeContent, CHILD_FIELD}; /// Options for controlling AST dump output. pub struct DumpOptions { @@ -45,16 +45,143 @@ pub fn dump_ast_with_options( options: &DumpOptions, ) -> String { let mut out = String::new(); - dump_node(ast, root, source, options, 0, &mut out); + dump_node(ast, root, source, options, 0, None, &mut out); out } +/// Dump an AST and annotate type mismatches against a schema inline. +/// +/// Any node that does not match the expected type set for its parent field is +/// rendered with a trailing `" <-- ERROR: ..."` annotation on the same line. +pub fn dump_ast_with_type_errors( + ast: &Ast, + root: usize, + source: &str, + schema: &Schema, +) -> String { + dump_ast_with_type_errors_and_options(ast, root, source, schema, &DumpOptions::default()) +} + +/// Dump an AST and annotate type mismatches against a schema inline. +/// +/// Any node that does not match the expected type set for its parent field is +/// rendered with a trailing `" <-- ERROR: ..."` annotation on the same line. +pub fn dump_ast_with_type_errors_and_options( + ast: &Ast, + root: usize, + source: &str, + schema: &Schema, + options: &DumpOptions, +) -> String { + let mut out = String::new(); + dump_node(ast, root, source, options, 0, Some((schema, None, None)), &mut out); + out +} + +fn format_node_types(node_types: &[crate::schema::NodeType]) -> String { + node_types + .iter() + .map(|t| { + if t.named { + t.kind.clone() + } else { + format!("\"{}\"", t.kind) + } + }) + .collect::>() + .join(" | ") +} + +const EMPTY_NODE_TYPES: &[crate::schema::NodeType] = &[]; + +/// Generate a type-checking error message for a node if it doesn't match expected types. +/// +/// # Arguments +/// - `schema`: The AST schema to validate against. +/// - `node`: The node being checked. +/// - `expected`: The set of allowed types for this node, or `None` if type-checking is disabled. +/// - `parent_field`: Optional tuple of (parent_kind, field_name) for context in error messages. +/// +/// # Returns +/// `Some(error_message)` if the node violates the schema (e.g., wrong kind, missing field declaration). +/// `None` if the node matches the expected types or if type-checking is disabled. +fn type_error_for_node( + schema: &Schema, + node: &Node, + expected: Option<&[crate::schema::NodeType]>, + parent_field: Option<(&str, &str)>, +) -> Option { + if schema.id_for_node_kind(node.kind_name()).is_none() + && schema.id_for_unnamed_node_kind(node.kind_name()).is_none() + { + return Some(format!("node kind '{}' not in schema", node.kind_name())); + } + + let expected = expected?; + if expected.is_empty() { + if let Some((kind, field)) = parent_field { + return Some(format!("the node '{kind}' has no field '{field}'")); + } + return Some("field not declared in schema for this parent node".to_string()); + } + if schema.node_matches_types(node.kind_name(), node.is_named(), expected) { + None + } else { + let actual = if node.is_named() { + node.kind_name().to_string() + } else { + format!("\"{}\"", node.kind_name()) + }; + + if let Some((kind, field)) = parent_field { + Some(format!( + "The field {}.{} should contain {}, but got {}", + kind, + field, + format_node_types(expected), + actual + )) + } else { + Some(format!( + "expected {}, got {}", + format_node_types(expected), + actual + )) + } + } +} + +/// Look up the allowed types for a field in the schema. +/// +/// # Arguments +/// - `schema`: The AST schema to query. +/// - `parent_kind`: The node kind of the parent that contains this field. +/// - `field_id`: The field ID within that parent node. +/// +/// # Returns +/// `Some(&[NodeType])` if the field is declared in the schema and has type constraints. +/// `None` if the field is not declared or has no constraints (undeclared field). +fn expected_for_field<'a>( + schema: &'a Schema, + parent_kind: &str, + field_id: u16, +) -> Option<&'a [crate::schema::NodeType]> { + schema + .field_types(parent_kind, field_id) + .map(|v| v.as_slice()) +} + fn dump_node( ast: &Ast, id: usize, source: &str, options: &DumpOptions, indent: usize, + type_check: Option<( + &Schema, + Option<&[crate::schema::NodeType]>, + Option<(&str, &str)>, + )>, out: &mut String, ) { let node = match ast.get_node(id) { @@ -90,6 +217,12 @@ fn dump_node( } } + if let Some((schema, expected, parent_field)) = type_check { + if let Some(err) = type_error_for_node(schema, node, expected, parent_field) { + write!(out, " <-- ERROR: {err}").unwrap(); + } + } + writeln!(out).unwrap(); // Named fields first @@ -98,31 +231,68 @@ fn dump_node( continue; // Handle unnamed children last } let field_name = ast.field_name_for_id(field_id).unwrap_or("?"); + let child_type_check = type_check.map(|(schema, _, _)| { + let expected = expected_for_field(schema, node.kind_name(), field_id) + .or(Some(EMPTY_NODE_TYPES)); + let parent_field = Some((node.kind_name(), field_name)); + (schema, expected, parent_field) + }); + if children.len() == 1 { write!(out, "{prefix} {field_name}:").unwrap(); // Inline single child let child = ast.get_node(children[0]); if child.is_some_and(is_leaf) { write!(out, " ").unwrap(); - dump_node_inline(ast, children[0], source, options, out); + dump_node_inline(ast, children[0], source, options, child_type_check, out); } else { writeln!(out).unwrap(); - dump_node(ast, children[0], source, options, indent + 2, out); + dump_node( + ast, + children[0], + source, + options, + indent + 2, + child_type_check, + out, + ); } } else { writeln!(out, "{prefix} {field_name}:").unwrap(); for &child_id in children { - dump_node(ast, child_id, source, options, indent + 2, out); + dump_node( + ast, + child_id, + source, + options, + indent + 2, + child_type_check, + out, + ); } } } // Unnamed children — skip unnamed tokens (keywords, punctuation) if let Some(children) = node.fields.get(&CHILD_FIELD) { + let child_type_check = type_check.map(|(schema, _, _)| { + let expected = expected_for_field(schema, node.kind_name(), CHILD_FIELD) + .or(Some(EMPTY_NODE_TYPES)); + let parent_field = Some((node.kind_name(), "children")); + (schema, expected, parent_field) + }); for &child_id in children { if let Some(child) = ast.get_node(child_id) { if child.is_named() { - dump_node(ast, child_id, source, options, indent + 1, out); + dump_node( + ast, + child_id, + source, + options, + indent + 1, + child_type_check, + out, + ); } } } @@ -130,7 +300,18 @@ fn dump_node( } /// Dump a leaf node inline (no newline prefix, caller provides context). -fn dump_node_inline(ast: &Ast, id: usize, source: &str, options: &DumpOptions, out: &mut String) { +fn dump_node_inline( + ast: &Ast, + id: usize, + source: &str, + options: &DumpOptions, + type_check: Option<( + &Schema, + Option<&[crate::schema::NodeType]>, + Option<(&str, &str)>, + )>, + out: &mut String, +) { let node = match ast.get_node(id) { Some(n) => n, None => return, @@ -159,6 +340,12 @@ fn dump_node_inline(ast: &Ast, id: usize, source: &str, options: &DumpOptions, o } } + if let Some((schema, expected, parent_field)) = type_check { + if let Some(err) = type_error_for_node(schema, node, expected, parent_field) { + write!(out, " <-- ERROR: {err}").unwrap(); + } + } + writeln!(out).unwrap(); } diff --git a/shared/yeast/src/node_types_yaml.rs b/shared/yeast/src/node_types_yaml.rs index d321ba8a2cf..eb191076be4 100644 --- a/shared/yeast/src/node_types_yaml.rs +++ b/shared/yeast/src/node_types_yaml.rs @@ -23,6 +23,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::fmt::Write; +use crate::CHILD_FIELD; use serde::Deserialize; use serde_json::json; @@ -100,30 +101,36 @@ fn parse_field_name(raw: &str) -> FieldSpec { /// Resolve a TypeRef to a (type, named) pair, given the sets of known named /// and unnamed types. +fn resolve_type_ref_pair( + type_ref: &TypeRef, + named_types: &BTreeSet, + unnamed_types: &BTreeSet, +) -> (String, bool) { + match type_ref { + TypeRef::Explicit { unnamed } => (unnamed.clone(), false), + TypeRef::Name(name) => { + let is_named = named_types.contains(name); + let is_unnamed = unnamed_types.contains(name); + if is_named && is_unnamed { + (name.clone(), true) + } else if is_unnamed { + (name.clone(), false) + } else { + (name.clone(), true) + } + } + } +} + +/// Resolve a TypeRef to a {type, named} JSON record, given the sets of known named +/// and unnamed types. fn resolve_type_ref( type_ref: &TypeRef, named_types: &BTreeSet, unnamed_types: &BTreeSet, ) -> serde_json::Value { - match type_ref { - TypeRef::Explicit { unnamed } => { - json!({"type": unnamed, "named": false}) - } - TypeRef::Name(name) => { - let is_named = named_types.contains(name); - let is_unnamed = unnamed_types.contains(name); - - if is_named && is_unnamed { - // Ambiguous: default to named - json!({"type": name, "named": true}) - } else if is_unnamed { - json!({"type": name, "named": false}) - } else { - // Named, or unknown (assume named) - json!({"type": name, "named": true}) - } - } - } + let (kind, named) = resolve_type_ref_pair(type_ref, named_types, unnamed_types); + json!({"type": kind, "named": named}) } /// Convert YAML string to node-types JSON string. @@ -233,14 +240,12 @@ pub fn convert(yaml_input: &str) -> Result { serde_json::to_string_pretty(&output).map_err(|e| format!("Failed to serialize JSON: {e}")) } -/// Build a Schema from a YAML node-types string. -/// Registers all node kinds and field names found in the YAML. -pub fn schema_from_yaml(yaml_input: &str) -> Result { - let yaml: YamlNodeTypes = - serde_yaml::from_str(yaml_input).map_err(|e| format!("Failed to parse YAML: {e}"))?; - - let mut schema = crate::schema::Schema::new(); - +/// Apply YAML node-type definitions to a mutable Schema. +/// Registers all types, fields, and allowed types from the YAML into the schema. +fn apply_yaml_to_schema( + yaml: &YamlNodeTypes, + schema: &mut crate::schema::Schema, +) { // Register all supertypes as node kinds for name in yaml.supertypes.keys() { schema.register_kind(name); @@ -264,6 +269,62 @@ pub fn schema_from_yaml(yaml_input: &str) -> Result = yaml.unnamed.iter().cloned().collect(); + + for (supertype, members) in &yaml.supertypes { + let node_types = members + .iter() + .map(|m| { + let (kind, named) = resolve_type_ref_pair(m, &named_types, &unnamed_types); + crate::schema::NodeType { kind, named } + }) + .collect(); + schema.set_supertype_members(supertype, node_types); + } + + // Register allowed field child types for type checking. + for (parent_kind, fields_opt) in &yaml.named { + let Some(fields) = fields_opt else { + continue; + }; + + for (raw_field_name, type_refs) in fields { + let spec = parse_field_name(raw_field_name); + let field_id = match &spec.name { + Some(name) => schema.register_field(name), + None => CHILD_FIELD, + }; + + let mut node_types = type_refs + .clone() + .into_vec() + .into_iter() + .map(|type_ref| { + let (kind, named) = resolve_type_ref_pair(&type_ref, &named_types, &unnamed_types); + crate::schema::NodeType { kind, named } + }) + .collect::>(); + node_types.sort_by(|a, b| a.kind.cmp(&b.kind).then(a.named.cmp(&b.named))); + node_types.dedup_by(|a, b| a.kind == b.kind && a.named == b.named); + schema.set_field_types(parent_kind, field_id, node_types); + } + } +} + +pub fn schema_from_yaml(yaml_input: &str) -> Result { + let yaml: YamlNodeTypes = + serde_yaml::from_str(yaml_input).map_err(|e| format!("Failed to parse YAML: {e}"))?; + + let mut schema = crate::schema::Schema::new(); + apply_yaml_to_schema(&yaml, &mut schema); + Ok(schema) } @@ -278,29 +339,7 @@ pub fn schema_from_yaml_with_language( serde_yaml::from_str(yaml_input).map_err(|e| format!("Failed to parse YAML: {e}"))?; let mut schema = crate::schema::Schema::from_language(language); - - // Register supertypes - for name in yaml.supertypes.keys() { - schema.register_kind(name); - } - - // Register named node kinds and their fields - for (name, fields_opt) in &yaml.named { - schema.register_kind(name); - if let Some(fields) = fields_opt { - for raw_field_name in fields.keys() { - let spec = parse_field_name(raw_field_name); - if let Some(field_name) = &spec.name { - schema.register_field(field_name); - } - } - } - } - - // Register unnamed tokens - for name in &yaml.unnamed { - schema.register_unnamed_kind(name); - } + apply_yaml_to_schema(&yaml, &mut schema); Ok(schema) } diff --git a/shared/yeast/src/schema.rs b/shared/yeast/src/schema.rs index 12554d9c869..c832a57b23a 100644 --- a/shared/yeast/src/schema.rs +++ b/shared/yeast/src/schema.rs @@ -1,7 +1,13 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use crate::{FieldId, KindId, CHILD_FIELD}; +#[derive(Clone, Debug)] +pub struct NodeType { + pub kind: String, + pub named: bool, +} + /// A schema defining node kinds and field names for the output AST. /// Built from a node-types.yml file, independent of any tree-sitter grammar. /// @@ -25,6 +31,8 @@ pub struct Schema { unnamed_kind_ids: BTreeMap, kind_names: BTreeMap, next_kind_id: KindId, + field_types: BTreeMap<(String, FieldId), Vec>, + supertypes: BTreeMap>, } impl Default for Schema { @@ -43,6 +51,8 @@ impl Schema { unnamed_kind_ids: BTreeMap::new(), kind_names: BTreeMap::new(), next_kind_id: 1, // 0 is reserved + field_types: BTreeMap::new(), + supertypes: BTreeMap::new(), } } @@ -166,4 +176,68 @@ impl Schema { pub fn node_kind_for_id(&self, id: KindId) -> Option<&'static str> { self.kind_names.get(&id).copied() } + + pub fn set_field_types( + &mut self, + parent_kind: &str, + field_id: FieldId, + node_types: Vec, + ) { + self.field_types + .insert((parent_kind.to_string(), field_id), node_types); + } + + pub fn field_types( + &self, + parent_kind: &str, + field_id: FieldId, + ) -> Option<&Vec> { + self.field_types + .get(&(parent_kind.to_string(), field_id)) + } + + pub fn set_supertype_members(&mut self, supertype: &str, node_types: Vec) { + self.supertypes.insert(supertype.to_string(), node_types); + } + + fn allows_node( + &self, + node_type: &NodeType, + node_kind: &str, + node_named: bool, + active: &mut BTreeSet, + ) -> bool { + if node_type.kind == node_kind && node_type.named == node_named { + return true; + } + + if !node_type.named { + return false; + } + + let Some(members) = self.supertypes.get(&node_type.kind) else { + return false; + }; + + if !active.insert(node_type.kind.clone()) { + return false; + } + + let matched = members + .iter() + .any(|member| self.allows_node(member, node_kind, node_named, active)); + active.remove(&node_type.kind); + matched + } + + pub fn node_matches_types( + &self, + node_kind: &str, + node_named: bool, + node_types: &[NodeType], + ) -> bool { + node_types.iter().any(|node_type| { + self.allows_node(node_type, node_kind, node_named, &mut BTreeSet::new()) + }) + } } diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index e058e6b1eb0..05fd1998165 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -1,6 +1,6 @@ #![cfg(test)] -use yeast::dump::dump_ast; +use yeast::dump::{dump_ast, dump_ast_with_type_errors}; use yeast::*; const OUTPUT_SCHEMA_YAML: &str = include_str!("node-types.yml"); @@ -42,6 +42,35 @@ fn run_and_get_error(input: &str, rules: Vec) -> String { .expect_err("expected runner to return an error") } +/// Helper: parse Ruby source with no rules and dump with schema type errors. +fn parse_and_dump_typed(input: &str, schema_yaml: &str) -> String { + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run(input).unwrap(); + let schema = yeast::node_types_yaml::schema_from_yaml(schema_yaml).unwrap(); + dump_ast_with_type_errors(&ast, ast.get_root(), input, &schema) +} + +/// Helper: parse Ruby source with no rules and dump with schema type errors, +/// building schema with language IDs so field checks align with parser fields. +fn parse_and_dump_typed_with_language(input: &str, schema_yaml: &str) -> String { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let runner = Runner::new(lang.clone(), &[]); + let ast = runner.run(input).unwrap(); + let schema = yeast::node_types_yaml::schema_from_yaml_with_language(schema_yaml, &lang) + .unwrap(); + dump_ast_with_type_errors(&ast, ast.get_root(), input, &schema) +} + +/// Helper: parse Ruby source with custom rules and dump with schema type errors. +fn run_and_dump_typed(input: &str, rules: Vec, schema_yaml: &str) -> String { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = yeast::node_types_yaml::schema_from_yaml(schema_yaml).unwrap(); + let phases = vec![Phase::new("test", rules)]; + let runner = Runner::with_schema(lang, &schema, &phases); + let ast = runner.run(input).unwrap(); + dump_ast_with_type_errors(&ast, ast.get_root(), input, &schema) +} + /// Assert that a dump equals the expected string, treating the expected /// string as an indented multiline literal: leading/trailing blank lines /// are stripped, and the common leading indentation is removed from every @@ -125,6 +154,85 @@ fn test_parse_for_loop() { ); } +#[test] +fn test_dump_highlights_type_errors_inline() { + let schema_yaml = r#" +named: + program: + $children*: assignment + assignment: + left: identifier + right: identifier + identifier: +"#; + + let dump = parse_and_dump_typed("x = 1", schema_yaml); + assert!(dump.contains("integer \"1\" <-- ERROR:")); +} + +#[test] +fn test_dump_reports_preserved_unknown_kind_after_transformation() { + let schema_yaml = r#" +named: + program: + $children*: assignment + assignment: + left: identifier + right: identifier + identifier: +"#; + + // This rewrite runs and preserves the RHS node kind via capture. + // With schema above, preserving `integer` should be reported inline. + let rules = vec![yeast::rule!( + (assignment left: (_) @left right: (_) @right) + => + (assignment + left: {left} + right: {right} + ) + )]; + + let dump = run_and_dump_typed("x = 1", rules, schema_yaml); + assert!(dump.contains("integer \"1\" <-- ERROR:")); + assert!(dump.contains("node kind 'integer' not in schema")); +} + +#[test] +fn test_dump_reports_undeclared_field_on_node() { + let schema_yaml = r#" +named: + program: + $children*: assignment + assignment: + left: identifier + identifier: +"#; + + let dump = parse_and_dump_typed_with_language("x = y", schema_yaml); + assert!(dump.contains("right: identifier \"y\" <-- ERROR:")); + assert!(dump.contains("the node 'assignment' has no field 'right'")); +} + +#[test] +fn test_dump_reports_disallowed_kind_in_field_type() { + let schema_yaml = r#" +named: + program: + $children*: assignment + assignment: + left: identifier + right: identifier + identifier: + integer: +"#; + + let dump = parse_and_dump_typed_with_language("x = 1", schema_yaml); + assert!(dump.contains("right: integer \"1\" <-- ERROR:")); + assert!(dump.contains("should contain")); + assert!(dump.contains("but got integer")); +} + // ---- Query tests ---- #[test] From c3a9218dcffd337d5580d98d6d8bd2ee714cc109 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 8 May 2026 12:02:56 +0200 Subject: [PATCH 050/226] Yeast: Add one-shot phase kind --- shared/yeast/doc/yeast.md | 13 ++- shared/yeast/src/captures.rs | 15 +++ shared/yeast/src/lib.rs | 138 ++++++++++++++++++++++---- shared/yeast/tests/test.rs | 186 +++++++++++++++++++++++++++++++++-- 4 files changed, 323 insertions(+), 29 deletions(-) diff --git a/shared/yeast/doc/yeast.md b/shared/yeast/doc/yeast.md index 893cdea24dd..823bf1c1942 100644 --- a/shared/yeast/doc/yeast.md +++ b/shared/yeast/doc/yeast.md @@ -349,8 +349,8 @@ to enable rewriting: ```rust let desugar = yeast::DesugaringConfig::new() - .add_phase("cleanup", cleanup_rules()) - .add_phase("desugar", desugar_rules()) + .add_phase("cleanup", yeast::PhaseKind::Repeating, cleanup_rules()) + .add_phase("translate", yeast::PhaseKind::OneShot, translate_rules()) .with_output_node_types_yaml(include_str!("output-node-types.yml")); let lang = simple::LanguageSpec { @@ -365,6 +365,15 @@ let lang = simple::LanguageSpec { A single-phase config is just `.add_phase(...)` called once. Phase names appear in error messages so you can tell which phase failed. +There are two kinds of phases: +- **Repeating**: + Each node is re-processed until none of the rules in the phase matches. + When a node no longer matches any rules, its children are recursively processed. In practice this is used to desugar or simplify an AST, while staying mostly within the same schema. +- **One-shot**: + Each node is processed by the first matching rule, and the engine panics if no rule matches. + Rules are then recursively applied to every captured node. + In practice this is used when translating from one AST schema to another, where an exhaustive match is required. + The same YAML node-types is used for both the runtime yeast `Schema` (so rules can refer to output-only kinds and fields) and TRAP validation (it is converted to JSON internally). diff --git a/shared/yeast/src/captures.rs b/shared/yeast/src/captures.rs index a92c5096e94..ef184cd9f69 100644 --- a/shared/yeast/src/captures.rs +++ b/shared/yeast/src/captures.rs @@ -61,6 +61,21 @@ impl Captures { } } } + + /// Apply a fallible function to every captured id (across all keys), + /// replacing each id with the result. Stops and returns the error on + /// the first failure. + pub fn try_map_all_captures( + &mut self, + mut f: impl FnMut(Id) -> Result, + ) -> Result<(), E> { + for ids in self.captures.values_mut() { + for id in ids { + *id = f(*id)?; + } + } + Ok(()) + } pub fn map_captures_to(&mut self, from: &str, to: &'static str, f: &mut impl FnMut(Id) -> Id) { if let Some(from_ids) = self.captures.get(from) { let new_values = from_ids.iter().copied().map(f).collect(); diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index c06029a8626..c00732784dc 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -526,18 +526,39 @@ impl Rule { node: Id, fresh: &tree_builder::FreshScope, ) -> Result>, String> { + match self.try_match(ast, node)? { + Some(captures) => Ok(Some(self.run_transform(ast, captures, node, fresh))), + None => Ok(None), + } + } + + /// Attempt to match this rule's query against `node`, returning the + /// resulting captures on success. Does not invoke the transform. + fn try_match(&self, ast: &Ast, node: Id) -> Result, String> { let mut captures = Captures::new(); if self.query.do_match(ast, node, &mut captures)? { - fresh.next_scope(); - let source_range = ast.get_node(node).and_then(|n| match n.content { - NodeContent::Range(r) => Some(r), - _ => n.source_range, - }); - Ok(Some((self.transform)(ast, captures, fresh, source_range))) + Ok(Some(captures)) } else { Ok(None) } } + + /// Run this rule's transform with the given captures, using `node`'s + /// source range as the source range of the produced nodes. + fn run_transform( + &self, + ast: &mut Ast, + captures: Captures, + node: Id, + fresh: &tree_builder::FreshScope, + ) -> Vec { + fresh.next_scope(); + let source_range = ast.get_node(node).and_then(|n| match n.content { + NodeContent::Range(r) => Some(r), + _ => n.source_range, + }); + (self.transform)(ast, captures, fresh, source_range) + } } const MAX_REWRITE_DEPTH: usize = 100; @@ -572,17 +593,17 @@ impl<'a> RuleIndex<'a> { } } -fn apply_rules( +fn apply_repeating_rules( rules: &[Rule], ast: &mut Ast, id: Id, fresh: &tree_builder::FreshScope, ) -> Result, String> { let index = RuleIndex::new(rules); - apply_rules_inner(&index, ast, id, fresh, 0, None) + apply_repeating_rules_inner(&index, ast, id, fresh, 0, None) } -fn apply_rules_inner( +fn apply_repeating_rules_inner( index: &RuleIndex, ast: &mut Ast, id: Id, @@ -611,7 +632,7 @@ fn apply_rules_inner( let next_skip = if rule.repeated { None } else { Some(rule_ptr) }; let mut results = Vec::new(); for node in result_node { - results.extend(apply_rules_inner( + results.extend(apply_repeating_rules_inner( index, ast, node, @@ -636,7 +657,7 @@ fn apply_rules_inner( for children in fields.values_mut() { let mut new_children: Option> = None; for (i, &child_id) in children.iter().enumerate() { - let result = apply_rules_inner(index, ast, child_id, fresh, rewrite_depth, None)?; + let result = apply_repeating_rules_inner(index, ast, child_id, fresh, rewrite_depth, None)?; let unchanged = result.len() == 1 && result[0] == child_id; match (&mut new_children, unchanged) { (None, true) => {} // unchanged so far, no allocation needed @@ -661,6 +682,75 @@ fn apply_rules_inner( Ok(vec![id]) } +/// Apply rules using `OneShot` semantics: the first matching rule fires on +/// each visited node, recursion proceeds only through captured nodes (not +/// through the input node's children directly), and an error is returned if +/// no rule matches a visited node. +fn apply_one_shot_rules( + rules: &[Rule], + ast: &mut Ast, + id: Id, + fresh: &tree_builder::FreshScope, +) -> Result, String> { + let index = RuleIndex::new(rules); + apply_one_shot_rules_inner(&index, ast, id, fresh, 0) +} + +fn apply_one_shot_rules_inner( + index: &RuleIndex, + ast: &mut Ast, + id: Id, + fresh: &tree_builder::FreshScope, + rewrite_depth: usize, +) -> Result, String> { + if rewrite_depth > MAX_REWRITE_DEPTH { + return Err(format!( + "Desugaring exceeded maximum rewrite depth ({MAX_REWRITE_DEPTH}). \ + This likely indicates a non-terminating rule cycle." + )); + } + + let node_kind = ast.get_node(id).map(|n| n.kind()).unwrap_or(""); + for rule in index.rules_for_kind(node_kind) { + if let Some(mut captures) = rule.try_match(ast, id)? { + // Recursively translate every captured node before invoking the + // transform. The transform's output uses output-schema kinds, so + // we must translate captured input-schema nodes to their + // output-schema equivalents first. + captures.try_map_all_captures(|captured_id| { + let result = + apply_one_shot_rules_inner(index, ast, captured_id, fresh, rewrite_depth + 1)?; + if result.len() != 1 { + return Err(format!( + "OneShot: recursion on captured node produced {} results, expected exactly 1", + result.len() + )); + } + Ok(result[0]) + })?; + return Ok(rule.run_transform(ast, captures, id, fresh)); + } + } + + Err(format!( + "OneShot: no rule matched node of kind '{node_kind}'" + )) +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum PhaseKind { + /// A node is re-processed until none of the rules in the phase matches, + /// albeit a single rule cannot be applied twice in a row unless that rule is also marked as repeating. + /// When a node no longer matches any rules, its children are recursively processed (top down). + Repeating, + + /// A node is processed by the first matching rule, and the engine panics if no rule matches. + /// Rules are then recursively applied to every captured node. + /// In practice this is used when translating from one AST schema to another, where every node must be rewritten, + /// and it would be a type error to match the rule patterns (based on the input schema) against the output nodes (which conform to the output schema). + OneShot, +} + /// One phase of a desugaring pass: a named bundle of rules that runs to /// completion (a full traversal applying its rules) before the next phase /// starts. Rules within a phase compete for matches as usual; rules in @@ -670,13 +760,15 @@ pub struct Phase { /// Name used in error messages. pub name: String, pub rules: Vec, + pub kind: PhaseKind, } impl Phase { - pub fn new(name: impl Into, rules: Vec) -> Self { + pub fn new(name: impl Into, kind: PhaseKind, rules: Vec) -> Self { Self { name: name.into(), rules, + kind, } } } @@ -694,8 +786,8 @@ impl Phase { /// /// ```ignore /// let config = yeast::DesugaringConfig::new() -/// .add_phase("cleanup", cleanup_rules) -/// .add_phase("desugar", desugar_rules) +/// .add_phase("cleanup", PhaseKind::Repeating, cleanup_rules) +/// .add_phase("desugar", PhaseKind::Repeating, desugar_rules) /// .with_output_node_types_yaml(yaml); /// ``` #[derive(Default)] @@ -715,9 +807,14 @@ impl DesugaringConfig { Self::default() } - /// Append a new phase with the given name and rules. - pub fn add_phase(mut self, name: impl Into, rules: Vec) -> Self { - self.phases.push(Phase::new(name, rules)); + /// Append a new phase with the given name, kind, and rules. + pub fn add_phase( + mut self, + name: impl Into, + kind: PhaseKind, + rules: Vec, + ) -> Self { + self.phases.push(Phase::new(name, kind, rules)); self } @@ -806,8 +903,11 @@ impl<'a> Runner<'a> { let fresh = tree_builder::FreshScope::new(); let mut root = ast.get_root(); for phase in self.phases { - let res = apply_rules(&phase.rules, ast, root, &fresh) - .map_err(|e| format!("Phase `{}`: {e}", phase.name))?; + let res = match phase.kind { + PhaseKind::Repeating => apply_repeating_rules(&phase.rules, ast, root, &fresh), + PhaseKind::OneShot => apply_one_shot_rules(&phase.rules, ast, root, &fresh), + } + .map_err(|e| format!("Phase `{}`: {e}", phase.name))?; if res.len() != 1 { return Err(format!( "Phase `{}`: expected exactly one result node, got {}", diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index 05fd1998165..5e5c97c9ccb 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -15,7 +15,7 @@ fn parse_and_dump(input: &str) -> String { /// Helper: parse Ruby source with a custom output schema and a single /// phase of rules, return dump. fn run_and_dump(input: &str, rules: Vec) -> String { - run_phased_and_dump(input, vec![Phase::new("test", rules)]) + run_phased_and_dump(input, vec![Phase::new("test", PhaseKind::Repeating, rules)]) } /// Helper: parse Ruby source with a custom output schema and multiple @@ -35,7 +35,7 @@ fn run_and_get_error(input: &str, rules: Vec) -> String { let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); let schema = yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); - let phases = vec![Phase::new("test", rules)]; + let phases = vec![Phase::new("test", PhaseKind::Repeating, rules)]; let runner = Runner::with_schema(lang, &schema, &phases); runner .run(input) @@ -65,7 +65,7 @@ fn parse_and_dump_typed_with_language(input: &str, schema_yaml: &str) -> String fn run_and_dump_typed(input: &str, rules: Vec, schema_yaml: &str) -> String { let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); let schema = yeast::node_types_yaml::schema_from_yaml(schema_yaml).unwrap(); - let phases = vec![Phase::new("test", rules)]; + let phases = vec![Phase::new("test", PhaseKind::Repeating, rules)]; let runner = Runner::with_schema(lang, &schema, &phases); let ast = runner.run(input).unwrap(); dump_ast_with_type_errors(&ast, ast.get_root(), input, &schema) @@ -279,8 +279,12 @@ fn test_reachable_nodes_excludes_orphaned_rewrite_nodes() { let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); let schema = yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang) .unwrap(); - let rules = vec![yeast::rule!((integer) => (identifier "replaced"))]; - let runner = Runner::with_schema(lang, &schema, &rules); + let phases = vec![Phase::new( + "test", + PhaseKind::Repeating, + vec![yeast::rule!((integer) => (identifier "replaced"))], + )]; + let runner = Runner::with_schema(lang, &schema, &phases); let input = "x = 1"; let ast = runner.run(input).unwrap(); @@ -783,8 +787,8 @@ fn test_phased_desugaring() { let dump = run_phased_and_dump( "x = 1", vec![ - Phase::new("cleanup", cleanup), - Phase::new("desugar", desugar), + Phase::new("cleanup", PhaseKind::Repeating, cleanup), + Phase::new("desugar", PhaseKind::Repeating, desugar), ], ); assert_dump_eq( @@ -805,7 +809,11 @@ fn test_phase_error_includes_phase_name() { let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); let schema = yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); - let phases = vec![Phase::new("buggy", vec![swap_assignment_rule().repeated()])]; + let phases = vec![Phase::new( + "buggy", + PhaseKind::Repeating, + vec![swap_assignment_rule().repeated()], + )]; let runner = Runner::with_schema(lang, &schema, &phases); let err = runner .run("x = 1") @@ -820,6 +828,168 @@ fn test_phase_error_includes_phase_name() { ); } +/// Helper: an exhaustive set of OneShot rules covering every node reachable +/// (via captures) when translating `"x = 1"`. +fn one_shot_xeq1_rules() -> Vec { + vec![ + yeast::rule!( + (program (_)* @stmts) + => + (program stmt: {..stmts}) + ), + yeast::rule!( + (assignment left: (_) @left right: (_) @right) + => + (first_node left: {left} right: {right}) + ), + yeast::rule!((identifier) => (identifier "ID")), + yeast::rule!((integer) => (integer "INT")), + ] +} + +#[test] +fn test_one_shot_phase() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = + yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); + let phases = vec![Phase::new( + "translate", + PhaseKind::OneShot, + one_shot_xeq1_rules(), + )]; + let runner = Runner::with_schema(lang, &schema, &phases); + + let input = "x = 1"; + let ast = runner.run(input).unwrap(); + let dump = dump_ast(&ast, ast.get_root(), input); + assert_dump_eq( + &dump, + r#" + program + stmt: + first_node + left: identifier "ID" + right: integer "INT" + "#, + ); +} + +#[test] +fn test_one_shot_phase_errors_when_no_rule_matches() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = + yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); + // Drop the `integer` rule so the recursion has no rule for `integer`. + let mut rules = one_shot_xeq1_rules(); + rules.pop(); + let phases = vec![Phase::new("translate", PhaseKind::OneShot, rules)]; + let runner = Runner::with_schema(lang, &schema, &phases); + + let err = runner + .run("x = 1") + .expect_err("expected OneShot to error on unmatched node"); + assert!( + err.contains("Phase `translate`"), + "error should name the phase, got: {err}" + ); + assert!( + err.contains("no rule matched") && err.contains("integer"), + "error should describe the unmatched node kind, got: {err}" + ); +} + +/// OneShot recursion must apply rules to *captured* nodes, even if the rule +/// returns a captured child verbatim. A buggy implementation that only +/// recurses into the children of the rule's output (rather than into the +/// captures) would leave the returned capture untransformed. +#[test] +fn test_one_shot_recurses_into_returned_capture() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = + yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); + let rules = vec![ + yeast::rule!( + (program (_)* @stmts) + => + (program stmt: {..stmts}) + ), + // Returns the captured `left` verbatim, discarding `right`. + yeast::rule!( + (assignment left: (_) @left right: (_) @right) + => + {left} + ), + yeast::rule!((identifier) => (identifier "ID")), + yeast::rule!((integer) => (integer "INT")), + ]; + let phases = vec![Phase::new("translate", PhaseKind::OneShot, rules)]; + let runner = Runner::with_schema(lang, &schema, &phases); + + let input = "x = 1"; + let ast = runner.run(input).unwrap(); + let dump = dump_ast(&ast, ast.get_root(), input); + // `left` is an `identifier`; OneShot must apply the identifier rule to + // it before the assignment transform returns it verbatim. + assert_dump_eq( + &dump, + r#" + program + stmt: identifier "ID" + "#, + ); +} + +/// OneShot recursion must NOT descend into the children of the rule's output. +/// A rule may legitimately wrap a captured node in fresh output-schema nodes +/// that have no matching rule of their own (since rule patterns target the +/// input schema). Recursing into the output would erroneously try to find +/// rules for those wrapper kinds and fail. +#[test] +fn test_one_shot_does_not_recurse_into_wrapper_output() { + let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); + let schema = + yeast::node_types_yaml::schema_from_yaml_with_language(OUTPUT_SCHEMA_YAML, &lang).unwrap(); + let rules = vec![ + yeast::rule!( + (program (_)* @stmts) + => + (program stmt: {..stmts}) + ), + // Wraps `left` in nested `first_node`/`second_node` output kinds. + // Neither wrapper kind has a matching rule, so a buggy implementation + // that recurses into the wrapper's children would error. + yeast::rule!( + (assignment left: (_) @left right: (_) @right) + => + (first_node + left: (second_node left: {left} right: {right}) + right: {left} + ) + ), + yeast::rule!((identifier) => (identifier "ID")), + yeast::rule!((integer) => (integer "INT")), + ]; + let phases = vec![Phase::new("translate", PhaseKind::OneShot, rules)]; + let runner = Runner::with_schema(lang, &schema, &phases); + + let input = "x = 1"; + let ast = runner.run(input).unwrap(); + let dump = dump_ast(&ast, ast.get_root(), input); + assert_dump_eq( + &dump, + r#" + program + stmt: + first_node + left: + second_node + left: identifier "ID" + right: integer "INT" + right: identifier "ID" + "#, + ); +} + // ---- Cursor tests ---- #[test] From bb9e996cb6f2d37def2113059ccd8a2f25fd4467 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 7 May 2026 22:50:30 +0200 Subject: [PATCH 051/226] Shared: Do not emit ReservedWord class when there are no unnamed tokens --- shared/tree-sitter-extractor/src/generator/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/shared/tree-sitter-extractor/src/generator/mod.rs b/shared/tree-sitter-extractor/src/generator/mod.rs index d2521c51b3e..8167dc2574e 100644 --- a/shared/tree-sitter-extractor/src/generator/mod.rs +++ b/shared/tree-sitter-extractor/src/generator/mod.rs @@ -115,8 +115,19 @@ pub fn generate( &node_parent_table_name, )), ql::TopLevel::Class(ql_gen::create_token_class(&token_name, &tokeninfo_name)), - ql::TopLevel::Class(ql_gen::create_reserved_word_class(&reserved_word_name)), ]; + // Only emit the ReservedWord class when there are actually unnamed token + // types in the schema (i.e., @{prefix}_reserved_word exists in the dbscheme). + // When converting from a YEAST YAML schema that has no unnamed tokens, this + // type is absent and referencing it would cause a QL compilation error. + let has_reserved_words = nodes + .values() + .any(|n| n.dbscheme_name == reserved_word_name); + if has_reserved_words { + body.push(ql::TopLevel::Class(ql_gen::create_reserved_word_class( + &reserved_word_name, + ))); + } // Overlay discard predicates body.push(ql::TopLevel::Predicate( From 5d0cb9e8052d35d0098753f32a6e420795e0651f Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 May 2026 23:59:38 +0200 Subject: [PATCH 052/226] YEAST: fix one-shot rules for unnamed nodes and self-captures One-shot desugaring rules now skip unnamed nodes (punctuation, keywords, etc.) since rules are intended to target named nodes only. Also prevent infinite recursion when a capture refers to the root node of the matched tree (e.g. an @_ capture on the pattern root). Additionally fix the swift.rs add_phase call to match the updated 3-arg signature introduced by the one-shot phase kind commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shared/yeast/src/lib.rs | 17 +++++++++++++++++ unified/extractor/src/languages/swift/swift.rs | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index c00732784dc..39af38b82f8 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -703,6 +703,7 @@ fn apply_one_shot_rules_inner( fresh: &tree_builder::FreshScope, rewrite_depth: usize, ) -> Result, String> { + if rewrite_depth > MAX_REWRITE_DEPTH { return Err(format!( "Desugaring exceeded maximum rewrite depth ({MAX_REWRITE_DEPTH}). \ @@ -711,6 +712,15 @@ fn apply_one_shot_rules_inner( } let node_kind = ast.get_node(id).map(|n| n.kind()).unwrap_or(""); + + // Don't rewrite unnamed nodes (punctuation, keywords, etc.); leave them + // as-is. Rules target named nodes only. + if let Some(node) = ast.get_node(id) { + if !node.is_named() { + return Ok(vec![id]); + } + } + for rule in index.rules_for_kind(node_kind) { if let Some(mut captures) = rule.try_match(ast, id)? { // Recursively translate every captured node before invoking the @@ -718,6 +728,13 @@ fn apply_one_shot_rules_inner( // we must translate captured input-schema nodes to their // output-schema equivalents first. captures.try_map_all_captures(|captured_id| { + // Avoid infinite recursion when a capture refers to the root + // node of the matched tree (e.g. an `@_` capture on the + // pattern root): re-analyzing it would match the same rule + // again indefinitely. + if captured_id == id { + return Ok(captured_id); + } let result = apply_one_shot_rules_inner(index, ast, captured_id, fresh, rewrite_depth + 1)?; if result.len() != 1 { diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index c3843a5979c..cabbf75c54d 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -1,5 +1,5 @@ use codeql_extractor::extractor::simple; -use yeast::{rule, DesugaringConfig}; +use yeast::{rule, DesugaringConfig, PhaseKind}; fn desugaring_rules() -> Vec { vec![ @@ -12,7 +12,7 @@ fn desugaring_rules() -> Vec { } pub fn language_spec() -> simple::LanguageSpec { - let desugar = DesugaringConfig::new().add_phase("desugar", desugaring_rules()); + let desugar = DesugaringConfig::new().add_phase("desugar", PhaseKind::Repeating, desugaring_rules()); simple::LanguageSpec { prefix: "swift", ts_language: tree_sitter_swift::LANGUAGE.into(), From 8a2a48d2dd46576e1273245de361d8aac74b961c Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 May 2026 23:59:59 +0200 Subject: [PATCH 053/226] Unified extractor: add AST schema, swift translation rules, and corpus framework Add ast_types.yml defining the unified output AST schema with supertypes (expr, stmt, condition, pattern) and named nodes (top_level, binary_expr, name_expr, etc.). Rewrite swift translation rules to map from tree-sitter Swift grammar to the unified AST, using one-shot phase rules. Update the generator to use the output AST schema for dbscheme/QL generation, and normalize the extraction table prefix to 'unified'. Improve the corpus test framework to include raw tree-sitter parse output, type-error checking against the output schema, and better failure reporting. Regenerate Ast.qll, unified.dbscheme, and update BasicTest accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- unified/extractor/ast_types.yml | 102 ++++++++++++ unified/extractor/src/extractor.rs | 10 +- unified/extractor/src/generator.rs | 14 +- unified/extractor/src/languages/mod.rs | 5 +- .../extractor/src/languages/swift/swift.rs | 51 +++++- unified/extractor/tests/corpus_tests.rs | 155 +++++++++++++++--- unified/ql/lib/codeql/unified/Ast.qll | 141 ++++++++-------- unified/ql/lib/unified.dbscheme | 56 +++++-- .../library-tests/BasicTest/test.expected | 118 ++----------- .../ql/test/library-tests/BasicTest/test.ql | 10 +- 10 files changed, 442 insertions(+), 220 deletions(-) create mode 100644 unified/extractor/ast_types.yml diff --git a/unified/extractor/ast_types.yml b/unified/extractor/ast_types.yml new file mode 100644 index 00000000000..714a1eada60 --- /dev/null +++ b/unified/extractor/ast_types.yml @@ -0,0 +1,102 @@ +supertypes: + expr: + - binary_expr + - unary_expr + - name_expr + - lambda_expr + - unsupported_node + stmt: + - empty_stmt + - if_stmt + - variable_declaration_stmt + - guard_if_stmt + - unsupported_node + condition: + - expr_condition + - let_pattern_condition + - unsupported_node + pattern: + - var_pattern + - apply_pattern + - ignore_pattern + - unsupported_node +named: + # Top-level is the root node, currently containing a list of expressions + top_level: + body*: expr + + # Application of a binary operator, such as `a + b` + binary_expr: + left: expr + operator: operator + right: expr + + # Application of a unary operator, such as `!x` + unary_expr: + operand: expr + operator: operator + + # An identifier used in the context of an expression + name_expr: + identifier: identifier + + lambda_expr: + parameter*: parameter + body: [expr, stmt] + + # A parameter + parameter: + pattern: pattern + + empty_stmt: + + if_stmt: + condition: condition + then?: stmt + else?: stmt + + variable_declaration_stmt: + variable_declarator+: variable_declarator + + # A variable declaration, or assignment to a pattern. + # The initializer is optional (but typically only possible in combination with a simple variable pattern). + variable_declarator: + pattern: pattern + value?: expr + + # Evaluate 'condition', and if false, execute 'else' which must break from the enclosing block scope (return, break, etc). + # Any variables bound by 'condition' will be in scope for the remainder of the enclosing block scope + # (which differs from how if_stmt works). + guard_if_stmt: + condition: condition + else: stmt + + # Evaluates the given condition and interprets it as a boolean (by language conventions) + expr_condition: + expr: expr + + # Evaluate 'expr' and match its result against 'pattern', and return true if it matches. + # Variables bound by the pattern will be in scope within the 'true' branch controlled by this condition. + let_pattern_condition: + pattern: pattern + value: expr + + # A pattern matching anything, binding its value to the given variable + var_pattern: + identifier: identifier + + # A pattern matching anything, binding no variables, usually using the syntax "_" + ignore_pattern: + + # A pattern such as `Some(x)` where `Some` is the constructor and `x` is an argument + apply_pattern: + constructor: expr + argument*: expr + + # An simple unqualified identifier token + identifier: + + # A node that we don't yet translate + unsupported_node: + + operator: diff --git a/unified/extractor/src/extractor.rs b/unified/extractor/src/extractor.rs index ae3c1e78715..7601fa8addb 100644 --- a/unified/extractor/src/extractor.rs +++ b/unified/extractor/src/extractor.rs @@ -23,9 +23,17 @@ pub struct Options { pub fn run(options: Options) -> std::io::Result<()> { codeql_extractor::extractor::set_tracing_level("unified"); + // The generated dbscheme/QL library uses the unified_* relation namespace. + // Keep per-language specs for parser/rules/file globs, but normalize the + // extraction table prefix so emitted TRAP relations match the dbscheme. + let mut languages = languages::all_language_specs(); + for lang in &mut languages { + lang.prefix = "unified"; + } + let extractor = simple::Extractor { prefix: "unified".to_string(), - languages: languages::all_language_specs(), + languages, trap_dir: options.output_dir, trap_compression: trap::Compression::from_env("CODEQL_EXTRACTOR_UNIFIED_OPTION_TRAP_COMPRESSION"), source_archive_dir: options.source_archive_dir, diff --git a/unified/extractor/src/generator.rs b/unified/extractor/src/generator.rs index ce1f37144a4..cbf971a8ff2 100644 --- a/unified/extractor/src/generator.rs +++ b/unified/extractor/src/generator.rs @@ -3,6 +3,8 @@ use std::path::PathBuf; use codeql_extractor::generator::{generate, language::Language}; +use crate::languages; + #[derive(Args)] pub struct Options { /// Path of the generated dbscheme file @@ -17,10 +19,16 @@ pub struct Options { pub fn run(options: Options) -> std::io::Result<()> { codeql_extractor::extractor::set_tracing_level("unified"); + // The QL-visible schema is the unified output AST, not the per-language + // input grammars. Pass it via `desugar.output_node_types_yaml` so the + // generator converts the YAML to JSON node-types. + let desugar = yeast::DesugaringConfig::new() + .with_output_node_types_yaml(languages::OUTPUT_AST_SCHEMA); + let languages = vec![Language { - name: "Swift".to_owned(), - node_types: tree_sitter_swift::NODE_TYPES, - desugar: None, + name: "Unified".to_owned(), + node_types: "", // unused: generator picks up output_node_types_yaml above + desugar: Some(desugar), }]; generate(languages, options.dbscheme, options.library, "run unified/scripts/create-extractor-pack.sh") diff --git a/unified/extractor/src/languages/mod.rs b/unified/extractor/src/languages/mod.rs index 4d5c945cb9b..20ad599edfb 100644 --- a/unified/extractor/src/languages/mod.rs +++ b/unified/extractor/src/languages/mod.rs @@ -3,6 +3,9 @@ use codeql_extractor::extractor::simple; #[path = "swift/swift.rs"] mod swift; +/// Shared YEAST output AST schema for all languages. +pub(crate) const OUTPUT_AST_SCHEMA: &str = include_str!("../../ast_types.yml"); + pub fn all_language_specs() -> Vec { - vec![swift::language_spec()] + vec![swift::language_spec(OUTPUT_AST_SCHEMA)] } diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index cabbf75c54d..ebf571b7057 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -1,18 +1,59 @@ use codeql_extractor::extractor::simple; use yeast::{rule, DesugaringConfig, PhaseKind}; -fn desugaring_rules() -> Vec { +fn translation_rules() -> Vec { vec![ rule!( - (additive_expression) + (source_file (_)* @children) => - (simple_identifier "blah") + (top_level + body: {..children} + ) + ), + rule!( + (additive_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (multiplicative_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (simple_identifier) + => + name_expr + ), + rule!( + (_) + => + (unsupported_node) + ), + rule!( + _ @node + => + {node} ), ] } -pub fn language_spec() -> simple::LanguageSpec { - let desugar = DesugaringConfig::new().add_phase("desugar", PhaseKind::Repeating, desugaring_rules()); +pub fn language_spec(desugared_ast_schema: &'static str) -> simple::LanguageSpec { + let desugar = DesugaringConfig::new() + .add_phase("translate", PhaseKind::OneShot, translation_rules()) + .with_output_node_types_yaml(desugared_ast_schema); simple::LanguageSpec { prefix: "swift", ts_language: tree_sitter_swift::LANGUAGE.into(), diff --git a/unified/extractor/tests/corpus_tests.rs b/unified/extractor/tests/corpus_tests.rs index 2667647a589..ac93dd586ec 100644 --- a/unified/extractor/tests/corpus_tests.rs +++ b/unified/extractor/tests/corpus_tests.rs @@ -2,7 +2,7 @@ use std::fs; use std::path::Path; use codeql_extractor::extractor::simple; -use yeast::{dump::dump_ast, Runner}; +use yeast::{dump::dump_ast, dump::dump_ast_with_type_errors, Runner}; #[path = "../src/languages/mod.rs"] mod languages; @@ -11,6 +11,7 @@ mod languages; struct CorpusCase { name: String, input: String, + raw: String, expected: String, } @@ -63,6 +64,30 @@ fn parse_corpus(content: &str) -> Vec { let input = lines[input_start..i].join("\n").trim_end().to_string(); i += 1; + // Raw tree-sitter parse section. New-format files have a second + // `---` separator between the raw tree and the mapped AST. Legacy + // files (with only one separator) have no raw section — in that + // case `raw` stays empty and update mode will populate it. + let raw_start = i; + let mut next_sep = i; + while next_sep < lines.len() && lines[next_sep].trim() != "---" { + if is_header_rule(lines[next_sep]) + && next_sep + 2 < lines.len() + && !lines[next_sep + 1].trim().is_empty() + && is_header_rule(lines[next_sep + 2]) + { + break; + } + next_sep += 1; + } + let raw = if next_sep < lines.len() && lines[next_sep].trim() == "---" { + let raw_text = lines[raw_start..next_sep].join("\n").trim().to_string(); + i = next_sep + 1; + raw_text + } else { + String::new() + }; + let expected_start = i; while i < lines.len() { if is_header_rule(lines[i]) @@ -79,6 +104,7 @@ fn parse_corpus(content: &str) -> Vec { cases.push(CorpusCase { name, input, + raw, expected, }); } @@ -91,32 +117,52 @@ fn render_corpus(cases: &[CorpusCase]) -> String { for (idx, case) in cases.iter().enumerate() { if idx > 0 { + // Blank line between cases. out.push('\n'); } out.push_str("===\n"); out.push_str(case.name.trim()); - out.push_str("\n===\n"); - out.push('\n'); + out.push_str("\n===\n\n"); out.push_str(case.input.trim()); - out.push_str("\n\n---\n"); - out.push('\n'); + out.push_str("\n\n---\n\n"); + out.push_str(case.raw.trim()); + out.push_str("\n\n---\n\n"); out.push_str(case.expected.trim()); - out.push_str("\n\n"); + // Single trailing newline per case; the inter-case blank line is + // added by the prefix above, and the file ends with exactly one `\n`. + out.push('\n'); } out } -fn run_desugaring(lang: &simple::LanguageSpec, input: &str) -> String { +fn run_desugaring( + lang: &simple::LanguageSpec, + input: &str, +) -> Result { let runner = match lang.desugar.as_ref() { Some(config) => Runner::from_config(lang.ts_language.clone(), config) - .expect("Failed to create yeast runner from desugaring config"), + .map_err(|e| format!("Failed to create yeast runner: {e}"))?, None => Runner::new(lang.ts_language.clone(), &[]), }; + + runner + .run(input) + .map_err(|e| format!("Failed to parse input: {e}")) +} + +/// Produce the raw tree-sitter parse tree dump for `input`, with no +/// desugaring rules applied. Uses a `Runner` with an empty phase list and +/// the input grammar's own schema. +fn dump_raw_parse( + lang: &simple::LanguageSpec, + input: &str, +) -> Result { + let runner = Runner::new(lang.ts_language.clone(), &[]); let ast = runner .run(input) - .unwrap_or_else(|e| panic!("Failed to parse corpus input: {e}")); - dump_ast(&ast, ast.get_root(), input) + .map_err(|e| format!("Failed to parse input: {e}"))?; + Ok(dump_ast(&ast, ast.get_root(), input)) } #[test] @@ -126,6 +172,12 @@ fn test_corpus() { let corpus_dir = Path::new("tests/corpus"); for lang in all_languages { + let output_schema = yeast::node_types_yaml::schema_from_yaml_with_language( + languages::OUTPUT_AST_SCHEMA, + &lang.ts_language, + ) + .expect("Failed to parse OUTPUT_AST_SCHEMA YAML"); + let lang_corpus_dir = corpus_dir.join(&lang.prefix); if !lang_corpus_dir.exists() { continue; @@ -147,6 +199,7 @@ fn test_corpus() { let content = fs::read_to_string(&corpus_path) .unwrap_or_else(|e| panic!("Failed to read {}: {e}", corpus_path.display())); let mut cases = parse_corpus(&content); + let mut failures = Vec::new(); assert!( !cases.is_empty(), "No corpus cases found in {}", @@ -154,28 +207,76 @@ fn test_corpus() { ); for case in &mut cases { - let actual = run_desugaring(&lang, &case.input); - if update_mode { - case.expected = actual.trim().to_string(); - } else { - assert_eq!( - case.expected.trim(), - actual.trim(), - "Corpus case failed in {}: {}", - corpus_path.display(), - case.name - ); + match dump_raw_parse(&lang, &case.input) { + Err(e) => { + failures.push(format!( + "Raw parse failed for {} in {}: {}", + case.name, + corpus_path.display(), + e + )); + } + Ok(actual_raw) => { + if update_mode { + case.raw = actual_raw.trim().to_string(); + } else if case.raw.trim() != actual_raw.trim() { + failures.push(format!( + "Raw parse mismatch in {}: \"{}\"\nEXPECTED:\n\n{}\n\nACTUAL:\n\n{}", + corpus_path.display(), + case.name, + case.raw.trim(), + actual_raw.trim() + )); + } + } + } + + match run_desugaring(&lang, &case.input) { + Err(e) => { + failures.push(format!( + "Desugaring failed for {} in {}: {}", + case.name, + corpus_path.display(), + e + )); + } + Ok(actual) => { + let actual_dump = dump_ast_with_type_errors( + &actual, + actual.get_root(), + &case.input, + &output_schema, + ); + if update_mode { + case.expected = actual_dump.trim().to_string(); + } else if case.expected.trim() != actual_dump.trim() { + failures.push(format!( + "Test failed in {}: \"{}\"\nEXPECTED:\n\n{}\n\nACTUAL:\n\n{}", + corpus_path.display(), + case.name, + case.expected.trim(), + actual_dump.trim() + )); + } + } } } + assert!( + failures.is_empty(), + "{}", + failures.join("\n\n") + "\n\n" + ); + if update_mode { let updated = render_corpus(&cases); - fs::write(&corpus_path, updated).unwrap_or_else(|e| { - panic!( - "Failed to update corpus file {}: {e}", - corpus_path.display() - ) - }); + let write_result = fs::write(&corpus_path, updated); + assert!( + write_result.is_ok(), + "Failed to update corpus file {}: {}", + corpus_path.display(), + write_result.err().map_or_else(String::new, |e| e.to_string()) + ); } } } diff --git a/unified/ql/lib/codeql/unified/Ast.qll b/unified/ql/lib/codeql/unified/Ast.qll index 5b9491fdb9f..17adff56236 100644 --- a/unified/ql/lib/codeql/unified/Ast.qll +++ b/unified/ql/lib/codeql/unified/Ast.qll @@ -1,5 +1,5 @@ /** - * CodeQL library for Swift + * CodeQL library for Unified * Automatically generated from the tree-sitter grammar; do not edit */ @@ -24,20 +24,20 @@ private predicate discardLocation(@location_default loc) { } overlay[local] -module Swift { +module Unified { /** The base class for all AST nodes */ - class AstNode extends @swift_ast_node { + class AstNode extends @unified_ast_node { /** Gets a string representation of this element. */ string toString() { result = this.getAPrimaryQlClass() } /** Gets the location of this element. */ - final L::Location getLocation() { swift_ast_node_location(this, result) } + final L::Location getLocation() { unified_ast_node_location(this, result) } /** Gets the parent of this element. */ - final AstNode getParent() { swift_ast_node_parent(this, result, _) } + final AstNode getParent() { unified_ast_node_parent(this, result, _) } /** Gets the index of this node among the children of its parent. */ - final int getParentIndex() { swift_ast_node_parent(this, _, result) } + final int getParentIndex() { unified_ast_node_parent(this, _, result) } /** Gets a field or child node of this node. */ AstNode getAFieldOrChild() { none() } @@ -50,9 +50,9 @@ module Swift { } /** A token. */ - class Token extends @swift_token, AstNode { + class Token extends @unified_token, AstNode { /** Gets the value of this token. */ - final string getValue() { swift_tokeninfo(this, _, result) } + final string getValue() { unified_tokeninfo(this, _, result) } /** Gets a string representation of this element. */ final override string toString() { result = this.getValue() } @@ -61,32 +61,27 @@ module Swift { override string getAPrimaryQlClass() { result = "Token" } } - /** A reserved word. */ - class ReservedWord extends @swift_reserved_word, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ReservedWord" } - } - /** Gets the file containing the given `node`. */ - private @file getNodeFile(@swift_ast_node node) { - exists(@location_default loc | swift_ast_node_location(node, loc) | + private @file getNodeFile(@unified_ast_node node) { + exists(@location_default loc | unified_ast_node_location(node, loc) | locations_default(loc, result, _, _, _, _) ) } /** Holds if `node` is in the `file` and is part of the overlay base database. */ - private predicate discardableAstNode(@file file, @swift_ast_node node) { + private predicate discardableAstNode(@file file, @unified_ast_node node) { not isOverlay() and file = getNodeFile(node) } /** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */ overlay[discard_entity] - private predicate discardAstNode(@swift_ast_node node) { + private predicate discardAstNode(@unified_ast_node node) { exists(@file file, string path | files(file, path) | discardableAstNode(file, node) and overlayChangedFiles(path) ) } +<<<<<<< HEAD /** A class representing `additive_expression` nodes. */ class AdditiveExpression extends @swift_additive_expression, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -197,12 +192,34 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_assignment_def(this, _, result, _) or swift_assignment_def(this, _, _, result) +======= + /** A class representing `binary_expr` nodes. */ + class BinaryExpr extends @unified_binary_expr, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "BinaryExpr" } + + /** Gets the node corresponding to the field `left`. */ + final Expr getLeft() { unified_binary_expr_def(this, result, _, _) } + + /** Gets the node corresponding to the field `operator`. */ + final BinaryOperator getOperator() { unified_binary_expr_def(this, _, result, _) } + + /** Gets the node corresponding to the field `right`. */ + final Expr getRight() { unified_binary_expr_def(this, _, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_binary_expr_def(this, result, _, _) or + unified_binary_expr_def(this, _, result, _) or + unified_binary_expr_def(this, _, _, result) +>>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) } } - /** A class representing `associatedtype_declaration` nodes. */ - class AssociatedtypeDeclaration extends @swift_associatedtype_declaration, AstNode { + /** A class representing `binary_operator` tokens. */ + class BinaryOperator extends @unified_token_binary_operator, Token { /** Gets the name of the primary QL class for this element. */ +<<<<<<< HEAD final override string getAPrimaryQlClass() { result = "AssociatedtypeDeclaration" } /** Gets the node corresponding to the field `default_value`. */ @@ -224,23 +241,23 @@ module Swift { swift_associatedtype_declaration_def(this, result) or swift_associatedtype_declaration_child(this, _, result) } +======= + final override string getAPrimaryQlClass() { result = "BinaryOperator" } +>>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) } - /** A class representing `attribute` nodes. */ - class Attribute extends @swift_attribute, AstNode { + class Expr extends @unified_expr, AstNode { } + + /** A class representing `name_expr` tokens. */ + class NameExpr extends @unified_token_name_expr, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Attribute" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_attribute_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_attribute_child(this, _, result) } + final override string getAPrimaryQlClass() { result = "NameExpr" } } - /** A class representing `availability_condition` nodes. */ - class AvailabilityCondition extends @swift_availability_condition, AstNode { + /** A class representing `top_level` nodes. */ + class TopLevel extends @unified_top_level, AstNode { /** Gets the name of the primary QL class for this element. */ +<<<<<<< HEAD final override string getAPrimaryQlClass() { result = "AvailabilityCondition" } /** Gets the `i`th child of this node. */ @@ -2766,22 +2783,23 @@ module Swift { /** Gets the `i`th child of this node. */ final AstNode getChild(int i) { swift_where_clause_child(this, i, result) } +======= + final override string getAPrimaryQlClass() { result = "TopLevel" } + + /** Gets the node corresponding to the field `body`. */ + final Expr getBody(int i) { unified_top_level_body(this, i, result) } +>>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_where_clause_child(this, _, result) } + final override AstNode getAFieldOrChild() { unified_top_level_body(this, _, result) } } - /** A class representing `where_keyword` tokens. */ - class WhereKeyword extends @swift_token_where_keyword, Token { + /** A class representing `unary_expr` nodes. */ + class UnaryExpr extends @unified_unary_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WhereKeyword" } - } - - /** A class representing `while_statement` nodes. */ - class WhileStatement extends @swift_while_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WhileStatement" } + final override string getAPrimaryQlClass() { result = "UnaryExpr" } +<<<<<<< HEAD /** Gets the node corresponding to the field `condition`. */ final IfCondition getCondition(int i) { swift_while_statement_condition(this, i, result) } @@ -2791,36 +2809,29 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_while_statement_condition(this, _, result) or swift_while_statement_child(this, result) +======= + /** Gets the node corresponding to the field `operand`. */ + final Expr getOperand() { unified_unary_expr_def(this, result, _) } + + /** Gets the node corresponding to the field `operator`. */ + final UnaryOperator getOperator() { unified_unary_expr_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_unary_expr_def(this, result, _) or unified_unary_expr_def(this, _, result) +>>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) } } - /** A class representing `wildcard_pattern` tokens. */ - class WildcardPattern extends @swift_token_wildcard_pattern, Token { + /** A class representing `unary_operator` tokens. */ + class UnaryOperator extends @unified_token_unary_operator, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WildcardPattern" } + final override string getAPrimaryQlClass() { result = "UnaryOperator" } } - /** A class representing `willset_clause` nodes. */ - class WillsetClause extends @swift_willset_clause, AstNode { + /** A class representing `unsupported_node` tokens. */ + class UnsupportedNode extends @unified_token_unsupported_node, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WillsetClause" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_willset_clause_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_willset_clause_child(this, _, result) } - } - - /** A class representing `willset_didset_block` nodes. */ - class WillsetDidsetBlock extends @swift_willset_didset_block, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WillsetDidsetBlock" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_willset_didset_block_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_willset_didset_block_child(this, _, result) } + final override string getAPrimaryQlClass() { result = "UnsupportedNode" } } } diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme index b50bc56eaa2..91271d1b363 100644 --- a/unified/ql/lib/unified.dbscheme +++ b/unified/ql/lib/unified.dbscheme @@ -1,4 +1,4 @@ -// CodeQL database schema for Swift +// CodeQL database schema for Unified // Automatically generated from the tree-sitter grammar; do not edit // To regenerate, run unified/scripts/create-extractor-pack.sh @@ -131,6 +131,7 @@ overlayChangedFiles( string path: string ref ); +<<<<<<< HEAD /*- Swift dbscheme -*/ case @swift_additive_expression.op of 0 = @swift_additive_expression_plus @@ -2055,18 +2056,42 @@ swift_willset_didset_block_child( int swift_willset_didset_block: @swift_willset_didset_block ref, int index: int ref, unique int child: @swift_willset_didset_block_child_type ref +======= +/*- Unified dbscheme -*/ +unified_binary_expr_def( + unique int id: @unified_binary_expr, + int left: @unified_expr ref, + int operator: @unified_token_binary_operator ref, + int right: @unified_expr ref ); -swift_willset_didset_block_def( - unique int id: @swift_willset_didset_block +@unified_expr = @unified_binary_expr | @unified_token_name_expr | @unified_token_unsupported_node + +#keyset[unified_top_level, index] +unified_top_level_body( + int unified_top_level: @unified_top_level ref, + int index: int ref, + unique int body: @unified_expr ref ); -swift_tokeninfo( - unique int id: @swift_token, +unified_top_level_def( + unique int id: @unified_top_level +>>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) +); + +unified_unary_expr_def( + unique int id: @unified_unary_expr, + int operand: @unified_expr ref, + int operator: @unified_token_unary_operator ref +); + +unified_tokeninfo( + unique int id: @unified_token, int kind: int ref, string value: string ref ); +<<<<<<< HEAD case @swift_token.kind of 0 = @swift_reserved_word | 1 = @swift_token_as_operator @@ -2118,16 +2143,27 @@ case @swift_token.kind of @swift_ast_node = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_associatedtype_declaration | @swift_attribute | @swift_availability_condition | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_call_suffix | @swift_capture_list | @swift_capture_list_item | @swift_catch_block | @swift_check_expression | @swift_class_body | @swift_class_declaration | @swift_comparison_expression | @swift_computed_getter | @swift_computed_modify | @swift_computed_property | @swift_computed_setter | @swift_conjunction_expression | @swift_constructor_expression | @swift_constructor_suffix | @swift_control_transfer_statement | @swift_deinit_declaration | @swift_deprecated_operator_declaration_body | @swift_dictionary_literal | @swift_dictionary_type | @swift_didset_clause | @swift_directive | @swift_directly_assignable_expression | @swift_disjunction_expression | @swift_do_statement | @swift_enum_class_body | @swift_enum_entry | @swift_enum_type_parameters | @swift_equality_constraint | @swift_equality_expression | @swift_existential_type | @swift_external_macro_definition | @swift_for_statement | @swift_function_body | @swift_function_declaration | @swift_function_type | @swift_getter_specifier | @swift_guard_statement | @swift_identifier | @swift_if_condition | @swift_if_let_binding | @swift_if_statement | @swift_implicitly_unwrapped_type | @swift_import_declaration | @swift_infix_expression | @swift_inheritance_constraint | @swift_inheritance_specifier | @swift_init_declaration | @swift_interpolated_expression | @swift_key_path_expression | @swift_key_path_string_expression | @swift_lambda_function_type | @swift_lambda_function_type_parameters | @swift_lambda_literal | @swift_lambda_parameter | @swift_line_string_literal | @swift_macro_declaration | @swift_macro_definition | @swift_macro_invocation | @swift_metatype | @swift_modifiers | @swift_modify_specifier | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_navigation_suffix | @swift_nested_type_identifier | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_operator_declaration | @swift_optional_chain_marker | @swift_optional_type | @swift_parameter | @swift_parameter_modifiers | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_precedence_group_attribute | @swift_precedence_group_attributes | @swift_precedence_group_declaration | @swift_prefix_expression | @swift_property_declaration | @swift_protocol_body | @swift_protocol_composition_type | @swift_protocol_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_protocol_property_requirements | @swift_range_expression | @swift_raw_str_interpolation | @swift_raw_string_literal | @swift_referenceable_operator | @swift_repeat_while_statement | @swift_selector_expression | @swift_setter_specifier | @swift_source_file | @swift_statements | @swift_subscript_declaration | @swift_suppressed_constraint | @swift_switch_entry | @swift_switch_pattern | @swift_switch_statement | @swift_ternary_expression | @swift_throws_clause | @swift_token | @swift_try_expression | @swift_tuple_expression | @swift_tuple_type | @swift_tuple_type_item | @swift_type__ | @swift_type_annotation | @swift_type_arguments | @swift_type_constraint | @swift_type_constraints | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter | @swift_type_parameter_modifiers | @swift_type_parameter_pack | @swift_type_parameters | @swift_typealias_declaration | @swift_user_type | @swift_value_argument | @swift_value_argument_label | @swift_value_arguments | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause | @swift_while_statement | @swift_willset_clause | @swift_willset_didset_block +======= +case @unified_token.kind of + 1 = @unified_token_binary_operator +| 2 = @unified_token_name_expr +| 3 = @unified_token_unary_operator +| 4 = @unified_token_unsupported_node +; -swift_ast_node_location( - unique int node: @swift_ast_node ref, + +@unified_ast_node = @unified_binary_expr | @unified_token | @unified_top_level | @unified_unary_expr +>>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) + +unified_ast_node_location( + unique int node: @unified_ast_node ref, int loc: @location_default ref ); #keyset[parent, parent_index] -swift_ast_node_parent( - unique int node: @swift_ast_node ref, - int parent: @swift_ast_node ref, +unified_ast_node_parent( + unique int node: @unified_ast_node ref, + int parent: @unified_ast_node ref, int parent_index: int ref ); diff --git a/unified/ql/test/library-tests/BasicTest/test.expected b/unified/ql/test/library-tests/BasicTest/test.expected index 62b8146bf04..c36864e10d5 100644 --- a/unified/ql/test/library-tests/BasicTest/test.expected +++ b/unified/ql/test/library-tests/BasicTest/test.expected @@ -1,101 +1,17 @@ -identifier -| test.swift:1:8:1:17 | Foundation | Foundation | -| test.swift:5:9:5:13 | items | items | -| test.swift:7:19:7:21 | add | add | -| test.swift:7:23:7:23 | _ | _ | -| test.swift:7:25:7:28 | item | item | -| test.swift:8:9:8:13 | items | items | -| test.swift:8:15:8:20 | append | append | -| test.swift:8:22:8:25 | item | item | -| test.swift:11:10:11:17 | contains | contains | -| test.swift:11:19:11:19 | _ | _ | -| test.swift:11:21:11:24 | item | item | -| test.swift:12:16:12:20 | items | items | -| test.swift:12:22:12:29 | contains | contains | -| test.swift:12:31:12:34 | item | item | -| test.swift:19:9:19:13 | count | count | -| test.swift:20:10:20:13 | item | item | -| test.swift:20:15:20:16 | at | at | -| test.swift:20:18:20:22 | index | index | -| test.swift:24:6:24:10 | merge | merge | -| test.swift:24:27:24:27 | _ | _ | -| test.swift:24:29:24:33 | first | first | -| test.swift:24:39:24:39 | _ | _ | -| test.swift:24:41:24:46 | second | second | -| test.swift:24:73:24:73 | T | T | -| test.swift:24:75:24:81 | Element | Element | -| test.swift:25:9:25:14 | result | result | -| test.swift:25:18:25:22 | Array | Array | -| test.swift:25:24:25:28 | first | first | -| test.swift:26:9:26:12 | item | item | -| test.swift:26:17:26:22 | second | second | -| test.swift:27:13:27:18 | result | result | -| test.swift:27:20:27:27 | contains | contains | -| test.swift:27:29:27:32 | item | item | -| test.swift:28:13:28:18 | result | result | -| test.swift:28:20:28:25 | append | append | -| test.swift:28:27:28:30 | item | item | -| test.swift:31:12:31:17 | result | result | -| test.swift:37:17:37:20 | data | data | -| test.swift:39:9:39:13 | count | count | -| test.swift:40:16:40:19 | data | data | -| test.swift:40:21:40:25 | count | count | -| test.swift:43:9:43:15 | isEmpty | isEmpty | -| test.swift:44:9:44:12 | data | data | -| test.swift:44:14:44:20 | isEmpty | isEmpty | -| test.swift:47:10:47:13 | item | item | -| test.swift:47:15:47:16 | at | at | -| test.swift:47:18:47:22 | index | index | -| test.swift:48:15:48:19 | index | index | -| test.swift:48:29:48:33 | index | index | -| test.swift:48:37:48:40 | data | data | -| test.swift:48:42:48:46 | count | count | -| test.swift:49:16:49:19 | data | data | -| test.swift:49:21:49:25 | index | index | -| test.swift:52:10:52:12 | add | add | -| test.swift:52:14:52:14 | _ | _ | -| test.swift:52:16:52:19 | item | item | -| test.swift:53:9:53:12 | data | data | -| test.swift:53:14:53:19 | append | append | -| test.swift:53:21:53:24 | item | item | -| test.swift:59:10:59:16 | success | success | -| test.swift:60:10:60:16 | failure | failure | -| test.swift:62:10:62:12 | map | map | -| test.swift:62:17:62:17 | _ | _ | -| test.swift:62:19:62:27 | transform | transform | -| test.swift:64:15:64:21 | success | success | -| test.swift:64:27:64:31 | value | value | -| test.swift:65:21:65:27 | success | success | -| test.swift:65:29:65:37 | transform | transform | -| test.swift:65:39:65:43 | value | value | -| test.swift:66:15:66:21 | failure | failure | -| test.swift:66:27:66:31 | error | error | -| test.swift:67:21:67:27 | failure | failure | -| test.swift:67:29:67:33 | error | error | -| test.swift:73:23:73:29 | Element | Element | -| test.swift:74:10:74:17 | isSorted | isSorted | -| test.swift:75:13:75:13 | i | i | -| test.swift:75:23:75:31 | blah | blah | -| test.swift:76:21:76:21 | i | i | -| test.swift:76:31:76:35 | blah | blah | -| test.swift:85:6:85:12 | combine | combine | -| test.swift:85:17:85:17 | _ | _ | -| test.swift:85:19:85:24 | values | values | -| test.swift:85:32:85:40 | transform | transform | -| test.swift:86:12:86:17 | values | values | -| test.swift:86:19:86:25 | isEmpty | isEmpty | -| test.swift:87:12:87:17 | values | values | -| test.swift:87:19:87:27 | dropFirst | dropFirst | -| test.swift:87:31:87:36 | reduce | reduce | -| test.swift:87:38:87:43 | values | values | -| test.swift:87:49:87:57 | transform | transform | -func -| test.swift:7:5:9:5 | FunctionDeclaration | -| test.swift:11:5:13:5 | FunctionDeclaration | -| test.swift:24:1:32:1 | FunctionDeclaration | -| test.swift:47:5:50:5 | FunctionDeclaration | -| test.swift:52:5:54:5 | FunctionDeclaration | -| test.swift:62:5:69:5 | FunctionDeclaration | -| test.swift:74:5:81:5 | FunctionDeclaration | -| test.swift:85:1:88:1 | FunctionDeclaration | -add +nameExpr +unsupported +| test.swift:1:1:1:17 | import Foundation | import Foundation | +| test.swift:3:1:3:38 | // Generic struct with type constraint | // Generic struct with type constraint | +| test.swift:4:1:14:1 | struct Container {\n var items: [T] = []\n\n mutating func add(_ item: T) {\n items.append(item)\n }\n\n func contains(_ item: T) -> Bool {\n return items.contains(item)\n }\n} | struct Container {\n var items: [T] = []\n\n mutating func add(_ item: T) {\n items.append(item)\n }\n\n func contains(_ item: T) -> Bool {\n return items.contains(item)\n }\n} | +| test.swift:16:1:16:32 | // Protocol with associated type | // Protocol with associated type | +| test.swift:17:1:21:1 | protocol DataSource {\n associatedtype Element\n var count: Int { get }\n func item(at index: Int) -> Element?\n} | protocol DataSource {\n associatedtype Element\n var count: Int { get }\n func item(at index: Int) -> Element?\n} | +| test.swift:23:1:23:37 | // Generic function with where clause | // Generic function with where clause | +| test.swift:24:1:32:1 | func merge(_ first: T, _ second: T) -> [T.Element] where T.Element: Equatable {\n var result = Array(first)\n for item in second {\n if !result.contains(item) {\n result.append(item)\n }\n }\n return result\n} | func merge(_ first: T, _ second: T) -> [T.Element] where T.Element: Equatable {\n var result = Array(first)\n for item in second {\n if !result.contains(item) {\n result.append(item)\n }\n }\n return result\n} | +| test.swift:34:1:34:49 | // Class with inheritance and computed properties | // Class with inheritance and computed properties | +| test.swift:35:1:55:1 | class DataManager: DataSource {\n typealias Element = T\n private var data: [T] = []\n\n var count: Int {\n return data.count\n }\n\n var isEmpty: Bool {\n data.isEmpty\n }\n\n func item(at index: Int) -> T? {\n guard index >= 0 && index < data.count else { return nil }\n return data[index]\n }\n\n func add(_ item: T) {\n data.append(item)\n }\n} | class DataManager: DataSource {\n typealias Element = T\n private var data: [T] = []\n\n var count: Int {\n return data.count\n }\n\n var isEmpty: Bool {\n data.isEmpty\n }\n\n func item(at index: Int) -> T? {\n guard index >= 0 && index < data.count else { return nil }\n return data[index]\n }\n\n func add(_ item: T) {\n data.append(item)\n }\n} | +| test.swift:57:1:57:30 | // Enum with associated values | // Enum with associated values | +| test.swift:58:1:70:1 | enum Result {\n case success(Success)\n case failure(Failure)\n\n func map(_ transform: (Success) -> U) -> Result {\n switch self {\n case .success(let value):\n return .success(transform(value))\n case .failure(let error):\n return .failure(error)\n }\n }\n} | enum Result {\n case success(Success)\n case failure(Failure)\n\n func map(_ transform: (Success) -> U) -> Result {\n switch self {\n case .success(let value):\n return .success(transform(value))\n case .failure(let error):\n return .failure(error)\n }\n }\n} | +| test.swift:72:1:72:37 | // Extension with generic constraints | // Extension with generic constraints | +| test.swift:73:1:82:1 | extension Array where Element: Comparable {\n func isSorted() -> Bool {\n for i in 0..<(count - 1) {\n if self[i] > self[i + 1] {\n return false\n }\n }\n return true\n }\n} | extension Array where Element: Comparable {\n func isSorted() -> Bool {\n for i in 0..<(count - 1) {\n if self[i] > self[i + 1] {\n return false\n }\n }\n return true\n }\n} | +| test.swift:84:1:84:24 | // Higher-order function | // Higher-order function | +| test.swift:85:1:88:1 | func combine(_ values: [T], transform: (T, T) -> T) -> T? {\n guard !values.isEmpty else { return nil }\n return values.dropFirst().reduce(values[0], transform)\n} | func combine(_ values: [T], transform: (T, T) -> T) -> T? {\n guard !values.isEmpty else { return nil }\n return values.dropFirst().reduce(values[0], transform)\n} | diff --git a/unified/ql/test/library-tests/BasicTest/test.ql b/unified/ql/test/library-tests/BasicTest/test.ql index 3a5ee2f1c15..6fdd392cfd2 100644 --- a/unified/ql/test/library-tests/BasicTest/test.ql +++ b/unified/ql/test/library-tests/BasicTest/test.ql @@ -1,9 +1,5 @@ -import codeql.unified.Ast +import codeql.unified.Ast::Unified -query predicate identifier(Swift::SimpleIdentifier node, string name) { name = node.getValue() } +query predicate nameExpr(NameExpr node, string value) { value = node.getValue() } -query predicate func(Swift::FunctionDeclaration node) { any() } - -query predicate add(Swift::AdditiveExpression node, Swift::AstNode lhs, Swift::AstNode rhs) { - lhs = node.getLhs(0) and rhs = node.getRhs(0) -} +query predicate unsupported(UnsupportedNode node, string value) { value = node.getValue() } From 72b683d63c610b1540e9440926c8a1e480760460 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 May 2026 00:01:18 +0200 Subject: [PATCH 054/226] Unified: Add Swift corpus tests Add corpus test cases for Swift covering closures, collections, control flow, functions, literals, loops, operators, optionals/errors, types, and variables. Update existing desugar.txt with raw parse sections. Note: operator nodes currently render their node ID instead of the actual operator text (e.g. operator "3" instead of operator "+"). This will be fixed in the next commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../extractor/tests/corpus/swift/closures.txt | 188 +++++++ .../tests/corpus/swift/collections.txt | 234 +++++++++ .../tests/corpus/swift/control-flow.txt | 333 ++++++++++++ .../extractor/tests/corpus/swift/desugar.txt | 26 +- .../tests/corpus/swift/functions.txt | 297 +++++++++++ .../extractor/tests/corpus/swift/literals.txt | 121 +++++ .../extractor/tests/corpus/swift/loops.txt | 208 ++++++++ .../tests/corpus/swift/operators.txt | 264 ++++++++++ .../corpus/swift/optionals-and-errors.txt | 236 +++++++++ .../extractor/tests/corpus/swift/types.txt | 490 ++++++++++++++++++ .../tests/corpus/swift/variables.txt | 187 +++++++ 11 files changed, 2582 insertions(+), 2 deletions(-) create mode 100644 unified/extractor/tests/corpus/swift/closures.txt create mode 100644 unified/extractor/tests/corpus/swift/collections.txt create mode 100644 unified/extractor/tests/corpus/swift/control-flow.txt create mode 100644 unified/extractor/tests/corpus/swift/functions.txt create mode 100644 unified/extractor/tests/corpus/swift/literals.txt create mode 100644 unified/extractor/tests/corpus/swift/loops.txt create mode 100644 unified/extractor/tests/corpus/swift/operators.txt create mode 100644 unified/extractor/tests/corpus/swift/optionals-and-errors.txt create mode 100644 unified/extractor/tests/corpus/swift/types.txt create mode 100644 unified/extractor/tests/corpus/swift/variables.txt diff --git a/unified/extractor/tests/corpus/swift/closures.txt b/unified/extractor/tests/corpus/swift/closures.txt new file mode 100644 index 00000000000..08af80c3f65 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/closures.txt @@ -0,0 +1,188 @@ +=== +Closure with explicit parameters +=== + +let f = { (x: Int) -> Int in x * 2 } + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + type: + lambda_function_type + name: + user_type + type_identifier "Int" + lambda_function_type_parameters + lambda_parameter + name: + simple_identifier "x" + user_type + type_identifier "Int" + statements + multiplicative_expression + lhs: simple_identifier "x" + op: * + rhs: integer_literal "2" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let f = { (x: Int) -> Int in x * 2 }" + +=== +Closure with shorthand parameters +=== + +let f = { $0 + $1 } + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + statements + additive_expression + lhs: simple_identifier "$0" + op: + + rhs: simple_identifier "$1" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let f = { $0 + $1 }" + +=== +Trailing closure +=== + +xs.map { $0 * 2 } + +--- + +source_file + call_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "map" + target: simple_identifier "xs" + call_suffix + lambda_literal + statements + multiplicative_expression + lhs: simple_identifier "$0" + op: * + rhs: integer_literal "2" + +--- + +top_level + body: unsupported_node "xs.map { $0 * 2 }" + +=== +Closure with capture list +=== + +let f = { [weak self] in self?.doThing() } + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + captures: + capture_list + capture_list_item + name: simple_identifier "self" + ownership_modifier + statements + call_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "doThing" + target: + self_expression + ? + call_suffix + value_arguments + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let f = { [weak self] in self?.doThing() }" + +=== +Multi-statement closure +=== + +let f = { (x: Int) -> Int in + let y = x + 1 + return y * 2 +} + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + type: + lambda_function_type + name: + user_type + type_identifier "Int" + lambda_function_type_parameters + lambda_parameter + name: + simple_identifier "x" + user_type + type_identifier "Int" + statements + property_declaration + name: + pattern + bound_identifier: simple_identifier "y" + value: + additive_expression + lhs: simple_identifier "x" + op: + + rhs: integer_literal "1" + value_binding_pattern + mutability: let + control_transfer_statement + result: + multiplicative_expression + lhs: simple_identifier "y" + op: * + rhs: integer_literal "2" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let f = { (x: Int) -> Int in\n let y = x + 1\n return y * 2\n}" diff --git a/unified/extractor/tests/corpus/swift/collections.txt b/unified/extractor/tests/corpus/swift/collections.txt new file mode 100644 index 00000000000..76015e75baa --- /dev/null +++ b/unified/extractor/tests/corpus/swift/collections.txt @@ -0,0 +1,234 @@ +=== +Array literal +=== + +let xs = [1, 2, 3] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "xs" + value: + array_literal + element: + integer_literal "1" + integer_literal "2" + integer_literal "3" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let xs = [1, 2, 3]" + +=== +Empty array literal with type +=== + +let xs: [Int] = [] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "xs" + value: + array_literal + value_binding_pattern + mutability: let + type_annotation + name: + array_type + name: + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "let xs: [Int] = []" + +=== +Dictionary literal +=== + +let d = ["a": 1, "b": 2] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "d" + value: + dictionary_literal + key: + line_string_literal + text: line_str_text "a" + line_string_literal + text: line_str_text "b" + value: + integer_literal "1" + integer_literal "2" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let d = [\"a\": 1, \"b\": 2]" + +=== +Set literal +=== + +let s: Set = [1, 2, 3] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "s" + value: + array_literal + element: + integer_literal "1" + integer_literal "2" + integer_literal "3" + value_binding_pattern + mutability: let + type_annotation + name: + user_type + type_identifier "Set" + type_arguments + name: + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "let s: Set = [1, 2, 3]" + +=== +Tuple literal +=== + +let t = (1, "two", 3.0) + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "t" + value: + tuple_expression + value: + integer_literal "1" + line_string_literal + text: line_str_text "two" + real_literal "3.0" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let t = (1, \"two\", 3.0)" + +=== +Subscript access +=== + +let first = xs[0] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "first" + value: + call_expression + simple_identifier "xs" + call_suffix + value_arguments + value_argument + value: integer_literal "0" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let first = xs[0]" + +=== +Dictionary subscript +=== + +let v = d["key"] + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "v" + value: + call_expression + simple_identifier "d" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "key" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let v = d[\"key\"]" + +=== +Tuple member access +=== + +let n = t.0 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: + navigation_expression + suffix: + navigation_suffix + suffix: integer_literal "0" + target: simple_identifier "t" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let n = t.0" diff --git a/unified/extractor/tests/corpus/swift/control-flow.txt b/unified/extractor/tests/corpus/swift/control-flow.txt new file mode 100644 index 00000000000..ec54f9481f1 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/control-flow.txt @@ -0,0 +1,333 @@ +=== +If statement +=== + +if x > 0 { + print(x) +} + +--- + +source_file + if_statement + condition: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + +--- + +top_level + body: unsupported_node "if x > 0 {\n print(x)\n}" + +=== +If-else +=== + +if x > 0 { + print(x) +} else { + print(-x) +} + +--- + +source_file + if_statement + condition: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + else "else" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + prefix_expression + operation: - + target: simple_identifier "x" + +--- + +top_level + body: unsupported_node "if x > 0 {\n print(x)\n} else {\n print(-x)\n}" + +=== +If-else-if chain +=== + +if x > 0 { + print(1) +} else if x < 0 { + print(2) +} else { + print(3) +} + +--- + +source_file + if_statement + condition: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: integer_literal "1" + else "else" + if_statement + condition: + comparison_expression + lhs: simple_identifier "x" + op: < + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: integer_literal "2" + else "else" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: integer_literal "3" + +--- + +top_level + body: unsupported_node "if x > 0 {\n print(1)\n} else if x < 0 {\n print(2)\n} else {\n print(3)\n}" + +=== +If-let optional binding +=== + +if let value = optional { + print(value) +} + +--- + +source_file + if_statement + bound_identifier: simple_identifier "value" + condition: + value_binding_pattern + mutability: let + = + simple_identifier "optional" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "value" + +--- + +top_level + body: unsupported_node "if let value = optional {\n print(value)\n}" + +=== +Guard let +=== + +guard let value = optional else { return } + +--- + +source_file + guard_statement + bound_identifier: simple_identifier "value" + condition: + value_binding_pattern + mutability: let + = + simple_identifier "optional" + else "else" + statements + control_transfer_statement + +--- + +top_level + body: unsupported_node "guard let value = optional else { return }" + +=== +Ternary expression +=== + +let y = x > 0 ? 1 : -1 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "y" + value: + ternary_expression + condition: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + if_false: + prefix_expression + operation: - + target: integer_literal "1" + if_true: integer_literal "1" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let y = x > 0 ? 1 : -1" + +=== +Switch statement +=== + +switch x { +case 1: + print("one") +case 2, 3: + print("two or three") +default: + print("other") +} + +--- + +source_file + switch_statement + expr: simple_identifier "x" + switch_entry + switch_pattern + pattern + integer_literal "1" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "one" + switch_entry + switch_pattern + pattern + integer_literal "2" + switch_pattern + pattern + integer_literal "3" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "two or three" + switch_entry + default_keyword "default" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "other" + +--- + +top_level + body: unsupported_node "switch x {\ncase 1:\n print(\"one\")\ncase 2, 3:\n print(\"two or three\")\ndefault:\n print(\"other\")\n}" + +=== +Switch with binding pattern +=== + +switch shape { +case .circle(let r): + print(r) +case .square(let s): + print(s) +} + +--- + +source_file + switch_statement + expr: simple_identifier "shape" + switch_entry + switch_pattern + pattern + simple_identifier "circle" + pattern + bound_identifier: simple_identifier "r" + value_binding_pattern + mutability: let + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "r" + switch_entry + switch_pattern + pattern + simple_identifier "square" + pattern + bound_identifier: simple_identifier "s" + value_binding_pattern + mutability: let + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "s" + +--- + +top_level + body: unsupported_node "switch shape {\ncase .circle(let r):\n print(r)\ncase .square(let s):\n print(s)\n}" diff --git a/unified/extractor/tests/corpus/swift/desugar.txt b/unified/extractor/tests/corpus/swift/desugar.txt index 1ea0e260aad..e90fe444800 100644 --- a/unified/extractor/tests/corpus/swift/desugar.txt +++ b/unified/extractor/tests/corpus/swift/desugar.txt @@ -7,8 +7,19 @@ Additive expression is desugared --- source_file - simple_identifier "blah" + additive_expression + lhs: integer_literal "1" + op: + + rhs: integer_literal "2" +--- + +top_level + body: + binary_expr + operator: operator "3" + left: unsupported_node "1" + right: unsupported_node "2" === Another additive expression is desugared @@ -19,5 +30,16 @@ foo + bar --- source_file - simple_identifier "blah" + additive_expression + lhs: simple_identifier "foo" + op: + + rhs: simple_identifier "bar" +--- + +top_level + body: + binary_expr + operator: operator "3" + left: name_expr "foo" + right: name_expr "bar" diff --git a/unified/extractor/tests/corpus/swift/functions.txt b/unified/extractor/tests/corpus/swift/functions.txt new file mode 100644 index 00000000000..5943b75d04d --- /dev/null +++ b/unified/extractor/tests/corpus/swift/functions.txt @@ -0,0 +1,297 @@ +=== +Function with no parameters +=== + +func greet() { + print("hello") +} + +--- + +source_file + function_declaration + body: + function_body + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: + line_string_literal + text: line_str_text "hello" + name: simple_identifier "greet" + +--- + +top_level + body: unsupported_node "func greet() {\n print(\"hello\")\n}" + +=== +Function with parameters and return type +=== + +func add(_ a: Int, _ b: Int) -> Int { + return a + b +} + +--- + +source_file + function_declaration + body: + function_body + statements + control_transfer_statement + result: + additive_expression + lhs: simple_identifier "a" + op: + + rhs: simple_identifier "b" + name: + simple_identifier "add" + user_type + type_identifier "Int" + parameter + external_name: simple_identifier "_" + name: + simple_identifier "a" + user_type + type_identifier "Int" + parameter + external_name: simple_identifier "_" + name: + simple_identifier "b" + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "func add(_ a: Int, _ b: Int) -> Int {\n return a + b\n}" + +=== +Function with named parameters +=== + +func greet(person name: String) { + print(name) +} + +--- + +source_file + function_declaration + body: + function_body + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "name" + name: simple_identifier "greet" + parameter + external_name: simple_identifier "person" + name: + simple_identifier "name" + user_type + type_identifier "String" + +--- + +top_level + body: unsupported_node "func greet(person name: String) {\n print(name)\n}" + +=== +Function with default parameter value +=== + +func greet(name: String = "world") { + print(name) +} + +--- + +source_file + function_declaration + body: + function_body + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "name" + default_value: + line_string_literal + text: line_str_text "world" + name: simple_identifier "greet" + parameter + name: + simple_identifier "name" + user_type + type_identifier "String" + +--- + +top_level + body: unsupported_node "func greet(name: String = \"world\") {\n print(name)\n}" + +=== +Variadic function +=== + +func sum(_ values: Int...) -> Int { + return values.reduce(0, +) +} + +--- + +source_file + function_declaration + body: + function_body + statements + control_transfer_statement + result: + call_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "reduce" + target: simple_identifier "values" + call_suffix + value_arguments + value_argument + value: integer_literal "0" + value_argument + value: + + name: + simple_identifier "sum" + user_type + type_identifier "Int" + parameter + external_name: simple_identifier "_" + name: + simple_identifier "values" + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "func sum(_ values: Int...) -> Int {\n return values.reduce(0, +)\n}" + +=== +Function call +=== + +foo(1, 2) + +--- + +source_file + call_expression + simple_identifier "foo" + call_suffix + value_arguments + value_argument + value: integer_literal "1" + value_argument + value: integer_literal "2" + +--- + +top_level + body: unsupported_node "foo(1, 2)" + +=== +Function call with labelled arguments +=== + +greet(person: "Bob") + +--- + +source_file + call_expression + simple_identifier "greet" + call_suffix + value_arguments + value_argument + name: + value_argument_label + simple_identifier "person" + value: + line_string_literal + text: line_str_text "Bob" + +--- + +top_level + body: unsupported_node "greet(person: \"Bob\")" + +=== +Method call +=== + +list.append(1) + +--- + +source_file + call_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "append" + target: simple_identifier "list" + call_suffix + value_arguments + value_argument + value: integer_literal "1" + +--- + +top_level + body: unsupported_node "list.append(1)" + +=== +Generic function +=== + +func identity(_ x: T) -> T { + return x +} + +--- + +source_file + function_declaration + body: + function_body + statements + control_transfer_statement + result: simple_identifier "x" + name: + simple_identifier "identity" + user_type + type_identifier "T" + type_parameters + type_parameter + type_identifier "T" + parameter + external_name: simple_identifier "_" + name: + simple_identifier "x" + user_type + type_identifier "T" + +--- + +top_level + body: unsupported_node "func identity(_ x: T) -> T {\n return x\n}" diff --git a/unified/extractor/tests/corpus/swift/literals.txt b/unified/extractor/tests/corpus/swift/literals.txt new file mode 100644 index 00000000000..5e42e60e89f --- /dev/null +++ b/unified/extractor/tests/corpus/swift/literals.txt @@ -0,0 +1,121 @@ +=== +Integer literal +=== + +42 + +--- + +source_file + integer_literal "42" + +--- + +top_level + body: unsupported_node "42" + +=== +Negative integer literal +=== + +-7 + +--- + +source_file + prefix_expression + operation: - + target: integer_literal "7" + +--- + +top_level + body: unsupported_node "-7" + +=== +Floating-point literal +=== + +3.14 + +--- + +source_file + real_literal "3.14" + +--- + +top_level + body: unsupported_node "3.14" + +=== +Boolean literals +=== + +true +false + +--- + +source_file + boolean_literal + boolean_literal + +--- + +top_level + body: + unsupported_node "true" + unsupported_node "false" + +=== +Nil literal +=== + +nil + +--- + +source_file + +--- + +top_level + body: + +=== +String literal +=== + +"hello" + +--- + +source_file + line_string_literal + text: line_str_text "hello" + +--- + +top_level + body: unsupported_node "\"hello\"" + +=== +String with interpolation +=== + +"hello \(name)" + +--- + +source_file + line_string_literal + interpolation: + interpolated_expression + value: simple_identifier "name" + text: line_str_text "hello " + +--- + +top_level + body: unsupported_node "\"hello \\(name)\"" diff --git a/unified/extractor/tests/corpus/swift/loops.txt b/unified/extractor/tests/corpus/swift/loops.txt new file mode 100644 index 00000000000..68c0a86198e --- /dev/null +++ b/unified/extractor/tests/corpus/swift/loops.txt @@ -0,0 +1,208 @@ +=== +For-in over array literal +=== + +for x in [1, 2, 3] { + print(x) +} + +--- + +source_file + for_statement + collection: + array_literal + element: + integer_literal "1" + integer_literal "2" + integer_literal "3" + item: + pattern + bound_identifier: simple_identifier "x" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + +--- + +top_level + body: unsupported_node "for x in [1, 2, 3] {\n print(x)\n}" + +=== +For-in over range +=== + +for i in 0..<10 { + print(i) +} + +--- + +source_file + for_statement + collection: + range_expression + end: integer_literal "10" + op: ..< + start: integer_literal "0" + item: + pattern + bound_identifier: simple_identifier "i" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "i" + +--- + +top_level + body: unsupported_node "for i in 0..<10 {\n print(i)\n}" + +=== +For-in with where clause +=== + +for x in xs where x > 0 { + print(x) +} + +--- + +source_file + for_statement + collection: simple_identifier "xs" + item: + pattern + bound_identifier: simple_identifier "x" + where_clause + where_keyword "where" + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + +--- + +top_level + body: unsupported_node "for x in xs where x > 0 {\n print(x)\n}" + +=== +While loop +=== + +while x > 0 { + x -= 1 +} + +--- + +source_file + while_statement + condition: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + assignment + operator: -= + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "x" + +--- + +top_level + body: unsupported_node "while x > 0 {\n x -= 1\n}" + +=== +Repeat-while loop +=== + +repeat { + x -= 1 +} while x > 0 + +--- + +source_file + repeat_while_statement + condition: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + statements + assignment + operator: -= + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "x" + +--- + +top_level + body: unsupported_node "repeat {\n x -= 1\n} while x > 0" + +=== +Break and continue +=== + +for x in xs { + if x < 0 { continue } + if x > 100 { break } + print(x) +} + +--- + +source_file + for_statement + collection: simple_identifier "xs" + item: + pattern + bound_identifier: simple_identifier "x" + statements + if_statement + condition: + comparison_expression + lhs: simple_identifier "x" + op: < + rhs: integer_literal "0" + statements + control_transfer_statement + if_statement + condition: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "100" + statements + control_transfer_statement + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "x" + +--- + +top_level + body: unsupported_node "for x in xs {\n if x < 0 { continue }\n if x > 100 { break }\n print(x)\n}" diff --git a/unified/extractor/tests/corpus/swift/operators.txt b/unified/extractor/tests/corpus/swift/operators.txt new file mode 100644 index 00000000000..caa88c3cef4 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/operators.txt @@ -0,0 +1,264 @@ +=== +Addition +=== + +a + b + +--- + +source_file + additive_expression + lhs: simple_identifier "a" + op: + + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "3" + left: name_expr "a" + right: name_expr "b" + +=== +Subtraction +=== + +a - b + +--- + +source_file + additive_expression + lhs: simple_identifier "a" + op: - + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "3" + left: name_expr "a" + right: name_expr "b" + +=== +Multiplication +=== + +a * b + +--- + +source_file + multiplicative_expression + lhs: simple_identifier "a" + op: * + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "3" + left: name_expr "a" + right: name_expr "b" + +=== +Division +=== + +a / b + +--- + +source_file + multiplicative_expression + lhs: simple_identifier "a" + op: / + rhs: simple_identifier "b" + +--- + +top_level + body: + binary_expr + operator: operator "3" + left: name_expr "a" + right: name_expr "b" + +=== +Operator precedence: addition and multiplication +=== + +a + b * c + +--- + +source_file + additive_expression + lhs: simple_identifier "a" + op: + + rhs: + multiplicative_expression + lhs: simple_identifier "b" + op: * + rhs: simple_identifier "c" + +--- + +top_level + body: + binary_expr + operator: operator "3" + left: name_expr "a" + right: + binary_expr + operator: operator "6" + left: name_expr "b" + right: name_expr "c" + +=== +Parenthesised expression +=== + +(a + b) * c + +--- + +source_file + multiplicative_expression + lhs: + tuple_expression + value: + additive_expression + lhs: simple_identifier "a" + op: + + rhs: simple_identifier "b" + op: * + rhs: simple_identifier "c" + +--- + +top_level + body: + binary_expr + operator: operator "9" + left: unsupported_node "(a + b)" + right: name_expr "c" + +=== +Comparison +=== + +a < b + +--- + +source_file + comparison_expression + lhs: simple_identifier "a" + op: < + rhs: simple_identifier "b" + +--- + +top_level + body: unsupported_node "a < b" + +=== +Equality +=== + +a == b + +--- + +source_file + equality_expression + lhs: simple_identifier "a" + op: == + rhs: simple_identifier "b" + +--- + +top_level + body: unsupported_node "a == b" + +=== +Logical and +=== + +a && b + +--- + +source_file + conjunction_expression + lhs: simple_identifier "a" + op: && + rhs: simple_identifier "b" + +--- + +top_level + body: unsupported_node "a && b" + +=== +Logical or +=== + +a || b + +--- + +source_file + disjunction_expression + lhs: simple_identifier "a" + op: || + rhs: simple_identifier "b" + +--- + +top_level + body: unsupported_node "a || b" + +=== +Logical not +=== + +!a + +--- + +source_file + prefix_expression + operation: bang "!" + target: simple_identifier "a" + +--- + +top_level + body: unsupported_node "!a" + +=== +Range operator +=== + +1...10 + +--- + +source_file + range_expression + end: integer_literal "10" + op: ... + start: integer_literal "1" + +--- + +top_level + body: unsupported_node "1...10" diff --git a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt new file mode 100644 index 00000000000..3b3310c4fb9 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt @@ -0,0 +1,236 @@ +=== +Optional type annotation +=== + +let x: Int? = nil + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value: nil + value_binding_pattern + mutability: let + type_annotation + name: + optional_type + wrapped: + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "let x: Int? = nil" + +=== +Optional chaining +=== + +let n = obj?.foo?.bar + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "bar" + target: + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "foo" + target: + simple_identifier "obj" + ? + ? + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let n = obj?.foo?.bar" + +=== +Force unwrap +=== + +let n = opt! + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: + postfix_expression + operation: bang "!" + target: simple_identifier "opt" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let n = opt!" + +=== +Nil-coalescing +=== + +let n = opt ?? 0 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: + nil_coalescing_expression + if_nil: integer_literal "0" + value: simple_identifier "opt" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let n = opt ?? 0" + +=== +Throwing function +=== + +func read() throws -> String { + return "" +} + +--- + +source_file + function_declaration + body: + function_body + statements + control_transfer_statement + result: + line_string_literal + name: + simple_identifier "read" + user_type + type_identifier "String" + throws "throws" + +--- + +top_level + body: unsupported_node "func read() throws -> String {\n return \"\"\n}" + +=== +Do-catch +=== + +do { + try foo() +} catch { + print(error) +} + +--- + +source_file + do_statement + statements + try_expression + expr: + call_expression + simple_identifier "foo" + call_suffix + value_arguments + try_operator + catch_block + catch_keyword "catch" + statements + call_expression + simple_identifier "print" + call_suffix + value_arguments + value_argument + value: simple_identifier "error" + +--- + +top_level + body: unsupported_node "do {\n try foo()\n} catch {\n print(error)\n}" + +=== +Try? expression +=== + +let result = try? foo() + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "result" + value: + try_expression + expr: + call_expression + simple_identifier "foo" + call_suffix + value_arguments + try_operator + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let result = try? foo()" + +=== +Try! expression +=== + +let result = try! foo() + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "result" + value: + try_expression + expr: + call_expression + simple_identifier "foo" + call_suffix + value_arguments + try_operator + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let result = try! foo()" diff --git a/unified/extractor/tests/corpus/swift/types.txt b/unified/extractor/tests/corpus/swift/types.txt new file mode 100644 index 00000000000..c4af07383b8 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/types.txt @@ -0,0 +1,490 @@ +=== +Empty class +=== + +class Foo {} + +--- + +source_file + class_declaration + body: + class_body + declaration_kind: class + name: type_identifier "Foo" + +--- + +top_level + body: unsupported_node "class Foo {}" + +=== +Class with stored properties +=== + +class Point { + var x: Int + var y: Int +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value_binding_pattern + mutability: var + type_annotation + name: + user_type + type_identifier "Int" + property_declaration + name: + pattern + bound_identifier: simple_identifier "y" + value_binding_pattern + mutability: var + type_annotation + name: + user_type + type_identifier "Int" + declaration_kind: class + name: type_identifier "Point" + +--- + +top_level + body: unsupported_node "class Point {\n var x: Int\n var y: Int\n}" + +=== +Class with initializer +=== + +class Point { + var x: Int + init(x: Int) { + self.x = x + } +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value_binding_pattern + mutability: var + type_annotation + name: + user_type + type_identifier "Int" + init_declaration + body: + function_body + statements + assignment + operator: = + result: simple_identifier "x" + target: + directly_assignable_expression + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "x" + target: + self_expression + name: init + parameter + name: + simple_identifier "x" + user_type + type_identifier "Int" + declaration_kind: class + name: type_identifier "Point" + +--- + +top_level + body: unsupported_node "class Point {\n var x: Int\n init(x: Int) {\n self.x = x\n }\n}" + +=== +Class with method +=== + +class Counter { + var n = 0 + func bump() { + n += 1 + } +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "n" + value: integer_literal "0" + value_binding_pattern + mutability: var + function_declaration + body: + function_body + statements + assignment + operator: += + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "n" + name: simple_identifier "bump" + declaration_kind: class + name: type_identifier "Counter" + +--- + +top_level + body: unsupported_node "class Counter {\n var n = 0\n func bump() {\n n += 1\n }\n}" + +=== +Class inheritance +=== + +class Dog: Animal {} + +--- + +source_file + class_declaration + body: + class_body + declaration_kind: class + name: type_identifier "Dog" + inheritance_specifier + inherits_from: + user_type + type_identifier "Animal" + +--- + +top_level + body: unsupported_node "class Dog: Animal {}" + +=== +Struct +=== + +struct Point { + let x: Int + let y: Int +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value_binding_pattern + mutability: let + type_annotation + name: + user_type + type_identifier "Int" + property_declaration + name: + pattern + bound_identifier: simple_identifier "y" + value_binding_pattern + mutability: let + type_annotation + name: + user_type + type_identifier "Int" + declaration_kind: struct + name: type_identifier "Point" + +--- + +top_level + body: unsupported_node "struct Point {\n let x: Int\n let y: Int\n}" + +=== +Enum with cases +=== + +enum Direction { + case north + case south + case east + case west +} + +--- + +source_file + class_declaration + body: + enum_class_body + enum_entry + name: simple_identifier "north" + enum_entry + name: simple_identifier "south" + enum_entry + name: simple_identifier "east" + enum_entry + name: simple_identifier "west" + declaration_kind: enum + name: type_identifier "Direction" + +--- + +top_level + body: unsupported_node "enum Direction {\n case north\n case south\n case east\n case west\n}" + +=== +Enum with associated values +=== + +enum Shape { + case circle(radius: Double) + case square(side: Double) +} + +--- + +source_file + class_declaration + body: + enum_class_body + enum_entry + data_contents: + enum_type_parameters + name: + user_type + type_identifier "Double" + simple_identifier "radius" + name: simple_identifier "circle" + enum_entry + data_contents: + enum_type_parameters + name: + user_type + type_identifier "Double" + simple_identifier "side" + name: simple_identifier "square" + declaration_kind: enum + name: type_identifier "Shape" + +--- + +top_level + body: unsupported_node "enum Shape {\n case circle(radius: Double)\n case square(side: Double)\n}" + +=== +Protocol declaration +=== + +protocol Drawable { + func draw() +} + +--- + +source_file + protocol_declaration + body: + protocol_body + protocol_function_declaration + name: simple_identifier "draw" + declaration_kind: protocol + name: type_identifier "Drawable" + +--- + +top_level + body: unsupported_node "protocol Drawable {\n func draw()\n}" + +=== +Extension +=== + +extension Int { + func squared() -> Int { return self * self } +} + +--- + +source_file + class_declaration + body: + class_body + function_declaration + body: + function_body + statements + control_transfer_statement + result: + multiplicative_expression + lhs: + self_expression + op: * + rhs: + self_expression + name: + simple_identifier "squared" + user_type + type_identifier "Int" + declaration_kind: extension + name: + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "extension Int {\n func squared() -> Int { return self * self }\n}" + +=== +Computed property +=== + +class Rect { + var w: Double + var h: Double + var area: Double { + return w * h + } +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "w" + value_binding_pattern + mutability: var + type_annotation + name: + user_type + type_identifier "Double" + property_declaration + name: + pattern + bound_identifier: simple_identifier "h" + value_binding_pattern + mutability: var + type_annotation + name: + user_type + type_identifier "Double" + property_declaration + computed_value: + computed_property + statements + control_transfer_statement + result: + multiplicative_expression + lhs: simple_identifier "w" + op: * + rhs: simple_identifier "h" + name: + pattern + bound_identifier: simple_identifier "area" + value_binding_pattern + mutability: var + type_annotation + name: + user_type + type_identifier "Double" + declaration_kind: class + name: type_identifier "Rect" + +--- + +top_level + body: unsupported_node "class Rect {\n var w: Double\n var h: Double\n var area: Double {\n return w * h\n }\n}" + +=== +Property with getter and setter +=== + +class Box { + private var _v = 0 + var v: Int { + get { return _v } + set { _v = newValue } + } +} + +--- + +source_file + class_declaration + body: + class_body + property_declaration + name: + pattern + bound_identifier: simple_identifier "_v" + value: integer_literal "0" + modifiers + visibility_modifier + value_binding_pattern + mutability: var + property_declaration + computed_value: + computed_property + computed_getter + getter_specifier + statements + control_transfer_statement + result: simple_identifier "_v" + computed_setter + setter_specifier + statements + assignment + operator: = + result: simple_identifier "newValue" + target: + directly_assignable_expression + simple_identifier "_v" + name: + pattern + bound_identifier: simple_identifier "v" + value_binding_pattern + mutability: var + type_annotation + name: + user_type + type_identifier "Int" + declaration_kind: class + name: type_identifier "Box" + +--- + +top_level + body: unsupported_node "class Box {\n private var _v = 0\n var v: Int {\n get { return _v }\n set { _v = newValue }\n }\n}" diff --git a/unified/extractor/tests/corpus/swift/variables.txt b/unified/extractor/tests/corpus/swift/variables.txt new file mode 100644 index 00000000000..429aac05867 --- /dev/null +++ b/unified/extractor/tests/corpus/swift/variables.txt @@ -0,0 +1,187 @@ +=== +Let binding +=== + +let x = 1 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value: integer_literal "1" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let x = 1" + +=== +Var binding +=== + +var x = 1 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value: integer_literal "1" + value_binding_pattern + mutability: var + +--- + +top_level + body: unsupported_node "var x = 1" + +=== +Let with type annotation +=== + +let x: Int = 1 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value: integer_literal "1" + value_binding_pattern + mutability: let + type_annotation + name: + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "let x: Int = 1" + +=== +Var without initialiser +=== + +var x: Int + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + value_binding_pattern + mutability: var + type_annotation + name: + user_type + type_identifier "Int" + +--- + +top_level + body: unsupported_node "var x: Int" + +=== +Tuple destructuring binding +=== + +let (a, b) = pair + +--- + +source_file + property_declaration + name: + pattern + pattern + simple_identifier "a" + pattern + simple_identifier "b" + value: simple_identifier "pair" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let (a, b) = pair" + +=== +Multiple bindings on one line +=== + +let x = 1, y = 2 + +--- + +source_file + property_declaration + name: + pattern + bound_identifier: simple_identifier "x" + pattern + bound_identifier: simple_identifier "y" + value: + integer_literal "1" + integer_literal "2" + value_binding_pattern + mutability: let + +--- + +top_level + body: unsupported_node "let x = 1, y = 2" + +=== +Assignment +=== + +x = 1 + +--- + +source_file + assignment + operator: = + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "x" + +--- + +top_level + body: unsupported_node "x = 1" + +=== +Compound assignment +=== + +x += 1 + +--- + +source_file + assignment + operator: += + result: integer_literal "1" + target: + directly_assignable_expression + simple_identifier "x" + +--- + +top_level + body: unsupported_node "x += 1" From 5772ee4d9b5f313e74e83412261911834f077151 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 May 2026 00:03:32 +0200 Subject: [PATCH 055/226] YEAST: add NodeRef type, YeastDisplay trait, and source text storage Introduce NodeRef as a typed wrapper around node arena IDs. Captures in desugaring rules are now bound as NodeRef instead of raw usize, which prevents accidental misuse and enables source-text-aware rendering. Add the YeastDisplay trait as an alternative to Display: its yeast_to_string method receives the Ast, allowing NodeRef to resolve to the captured node's source text instead of printing a numeric ID. Store the original source bytes in the Ast so that NodeContent::Range values (from synthesized literal nodes) can be resolved back to text. Update yeast-macros to emit NodeRef-typed capture bindings and use Into::::into where raw IDs are needed. The #{expr} template syntax now uses YeastDisplay instead of Display. The effect is visible in the corpus tests: operator nodes now correctly render as e.g. operator "+" instead of operator "3". Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../src/extractor/mod.rs | 2 +- shared/yeast-macros/src/parse.rs | 59 +++++++-- shared/yeast/src/lib.rs | 118 +++++++++++++++++- shared/yeast/src/visitor.rs | 1 + shared/yeast/tests/test.rs | 51 ++++++++ .../extractor/tests/corpus/swift/desugar.txt | 4 +- .../tests/corpus/swift/operators.txt | 14 +-- 7 files changed, 221 insertions(+), 28 deletions(-) diff --git a/shared/tree-sitter-extractor/src/extractor/mod.rs b/shared/tree-sitter-extractor/src/extractor/mod.rs index 00816a00fd0..115f6f405d4 100644 --- a/shared/tree-sitter-extractor/src/extractor/mod.rs +++ b/shared/tree-sitter-extractor/src/extractor/mod.rs @@ -326,7 +326,7 @@ pub fn extract( if let Some(yeast_runner) = yeast_runner { let ast = yeast_runner - .run_from_tree(&tree) + .run_from_tree(&tree, source) .unwrap_or_else(|e| panic!("Desugaring failed for {path_str}: {e}")); traverse_yeast(&ast, &mut visitor); } else { diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index 70bd46d5b6f..4a8a53a47f2 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -299,7 +299,7 @@ fn parse_direct_node(tokens: &mut Tokens, ctx: &Ident) -> Result { Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Brace => { let group = expect_group(tokens, Delimiter::Brace)?; let expr = group.stream(); - Ok(quote! { #expr }) + Ok(quote! { ::std::convert::Into::::into(#expr) }) } Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis => { let group = expect_group(tokens, Delimiter::Parenthesis)?; @@ -329,12 +329,17 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result Result = #expr; }); + stmts.push(quote! { + let #temp: Vec = (#expr).into_iter() + .map(::std::convert::Into::::into) + .collect(); + }); field_args.push(quote! { (#field_str, #temp) }); continue; } @@ -382,7 +391,7 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result Result::into) + ); + }); } else { let expr = group.stream(); - items.push(quote! { __nodes.push(#expr); }); + items.push(quote! { + __nodes.push(::std::convert::Into::::into(#expr)); + }); } continue; } @@ -580,13 +595,24 @@ pub fn parse_rule_top(input: TokenStream) -> Result { let name_str = &cap.name; match cap.multiplicity { CaptureMultiplicity::Repeated => { - quote! { let #name: Vec = __captures.get_all(#name_str); } + quote! { + let #name: Vec = __captures.get_all(#name_str) + .into_iter() + .map(yeast::NodeRef) + .collect(); + } } CaptureMultiplicity::Optional => { - quote! { let #name: Option = __captures.get_opt(#name_str); } + quote! { + let #name: Option = + __captures.get_opt(#name_str).map(yeast::NodeRef); + } } CaptureMultiplicity::Single => { - quote! { let #name: usize = __captures.get_var(#name_str).unwrap(); } + quote! { + let #name: yeast::NodeRef = + yeast::NodeRef(__captures.get_var(#name_str).unwrap()); + } } } }) @@ -613,19 +639,26 @@ pub fn parse_rule_top(input: TokenStream) -> Result { CaptureMultiplicity::Repeated => quote! { let __field_id = #ctx_ident.ast.field_id_for_name(#name_str) .unwrap_or_else(|| panic!("field '{}' not found", #name_str)); - __fields.insert(__field_id, #name); + __fields.insert( + __field_id, + #name.into_iter() + .map(::std::convert::Into::::into) + .collect(), + ); }, CaptureMultiplicity::Optional => quote! { let __field_id = #ctx_ident.ast.field_id_for_name(#name_str) .unwrap_or_else(|| panic!("field '{}' not found", #name_str)); if let Some(__id) = #name { - __fields.entry(__field_id).or_insert_with(Vec::new).push(__id); + __fields.entry(__field_id).or_insert_with(Vec::new) + .push(::std::convert::Into::::into(__id)); } }, CaptureMultiplicity::Single => quote! { let __field_id = #ctx_ident.ast.field_id_for_name(#name_str) .unwrap_or_else(|| panic!("field '{}' not found", #name_str)); - __fields.entry(__field_id).or_insert_with(Vec::new).push(#name); + __fields.entry(__field_id).or_insert_with(Vec::new) + .push(::std::convert::Into::::into(#name)); }, } }) diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index 39af38b82f8..541b1bb3811 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -23,12 +23,73 @@ pub use cursor::Cursor; use query::QueryNode; /// Node ids are indexes into the arena -type Id = usize; +pub type Id = usize; /// Field and Kind ids are provided by tree-sitter type FieldId = u16; type KindId = u16; +/// A typed reference to a node in an [`Ast`] arena. Wraps an [`Id`] but +/// deliberately does not implement [`std::fmt::Display`]: rendering a node +/// requires the [`Ast`] it lives in (to resolve [`NodeContent::Range`] back +/// to source text). Use [`YeastDisplay::yeast_to_string`] to format it. +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +pub struct NodeRef(pub Id); + +impl NodeRef { + pub fn id(self) -> Id { + self.0 + } +} + +impl From for Id { + fn from(value: NodeRef) -> Self { + value.0 + } +} + +/// Like [`std::fmt::Display`], but the formatting routine is given access to +/// the [`Ast`] so that node references can resolve to their source text. +/// +/// All standard primitive and string types implement [`YeastDisplay`] via +/// the [`impl_yeast_display_via_display`] macro below. Coherence prevents a +/// blanket `impl`, so additional types must be added explicitly. +pub trait YeastDisplay { + fn yeast_to_string(&self, ast: &Ast) -> String; +} + +impl YeastDisplay for NodeRef { + fn yeast_to_string(&self, ast: &Ast) -> String { + ast.source_text(self.0) + } +} + +macro_rules! impl_yeast_display_via_display { + ($($t:ty),* $(,)?) => { + $( + impl YeastDisplay for $t { + fn yeast_to_string(&self, _ast: &Ast) -> String { + ::std::string::ToString::to_string(self) + } + } + )* + }; +} + +impl_yeast_display_via_display! { + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize, + f32, f64, + bool, char, + str, String, +} + +impl YeastDisplay for &T { + fn yeast_to_string(&self, ast: &Ast) -> String { + (**self).yeast_to_string(ast) + } +} + pub const CHILD_FIELD: u16 = u16::MAX; #[derive(Debug)] @@ -160,6 +221,9 @@ pub struct Ast { root: Id, nodes: Vec, schema: schema::Schema, + /// Original source bytes the tree was parsed from. Used to resolve + /// `NodeContent::Range` to text for synthesized literal nodes. + source: Vec, } impl std::fmt::Debug for Ast { @@ -182,11 +246,41 @@ impl Ast { schema: schema::Schema, tree: &tree_sitter::Tree, language: &tree_sitter::Language, + ) -> Self { + Self::from_tree_with_schema_and_source(schema, tree, language, Vec::new()) + } + + pub fn from_tree_with_schema_and_source( + schema: schema::Schema, + tree: &tree_sitter::Tree, + language: &tree_sitter::Language, + source: Vec, ) -> Self { let mut visitor = visitor::Visitor::new(language.clone()); visitor.visit(tree); - visitor.build_with_schema(schema) + let mut ast = visitor.build_with_schema(schema); + ast.source = source; + ast + } + + /// Returns the source text for `id`, resolving `NodeContent::Range` + /// against the stored source bytes when available. + pub fn source_text(&self, id: Id) -> String { + let Some(node) = self.get_node(id) else { return String::new(); }; + match &node.content { + NodeContent::Range(range) => { + let start = range.start_byte; + let end = range.end_byte; + if end <= self.source.len() && start <= end { + String::from_utf8_lossy(&self.source[start..end]).into_owned() + } else { + String::new() + } + } + NodeContent::String(s) => s.to_string(), + NodeContent::DynamicString(s) => s.clone(), + } } pub fn walk(&self) -> AstCursor { @@ -894,8 +988,17 @@ impl<'a> Runner<'a> { }) } - pub fn run_from_tree(&self, tree: &tree_sitter::Tree) -> Result { - let mut ast = Ast::from_tree_with_schema(self.schema.clone(), tree, &self.language); + pub fn run_from_tree( + &self, + tree: &tree_sitter::Tree, + source: &[u8], + ) -> Result { + let mut ast = Ast::from_tree_with_schema_and_source( + self.schema.clone(), + tree, + &self.language, + source.to_vec(), + ); self.run_phases(&mut ast)?; Ok(ast) } @@ -908,7 +1011,12 @@ impl<'a> Runner<'a> { let tree = parser .parse(input, None) .ok_or_else(|| "Failed to parse input".to_string())?; - let mut ast = Ast::from_tree_with_schema(self.schema.clone(), &tree, &self.language); + let mut ast = Ast::from_tree_with_schema_and_source( + self.schema.clone(), + &tree, + &self.language, + input.as_bytes().to_vec(), + ); self.run_phases(&mut ast)?; Ok(ast) } diff --git a/shared/yeast/src/visitor.rs b/shared/yeast/src/visitor.rs index 1b9c5eab362..4bd2606c958 100644 --- a/shared/yeast/src/visitor.rs +++ b/shared/yeast/src/visitor.rs @@ -52,6 +52,7 @@ impl Visitor { root: 0, schema, nodes: self.nodes.into_iter().map(|n| n.inner).collect(), + source: Vec::new(), } } diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index 5e5c97c9ccb..7f4db154183 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -1060,3 +1060,54 @@ fn test_desugar_for_with_multiple_assignment() { "#, ); } + +/// Regression test: `#{capture}` in a template must render the *source text* +/// of the captured node, not its arena `Id`. Previously, captures were bound +/// as `usize`, so `#{cap}` printed the integer id (e.g. `"3"`) via `Display`. +/// Captures are now bound as `NodeRef`, which has no `Display` impl and +/// resolves to the captured node's source text via `YeastDisplay`. +#[test] +fn test_hash_brace_renders_capture_source_text() { + let rule = rule!( + (call + method: (identifier) @name + receiver: (identifier) @recv + ) + => + (call + method: (identifier #{name}) + receiver: (identifier #{recv}) + arguments: (argument_list) + ) + ); + let dump = run_and_dump("foo.bar()", vec![rule]); + assert_dump_eq( + &dump, + r#" + program + call + arguments: argument_list "foo.bar()" + method: identifier "bar" + receiver: identifier "foo" + "#, + ); +} + +/// Regression test: non-`NodeRef` values in `#{expr}` still render via their +/// `Display` impl (covered by `YeastDisplay`'s blanket impls for primitives). +#[test] +fn test_hash_brace_renders_integer_expression() { + let rule = rule!( + (identifier) @_ + => + (identifier #{1 + 2}) + ); + let dump = run_and_dump("foo", vec![rule]); + assert_dump_eq( + &dump, + r#" + program + identifier "3" + "#, + ); +} diff --git a/unified/extractor/tests/corpus/swift/desugar.txt b/unified/extractor/tests/corpus/swift/desugar.txt index e90fe444800..bcdca0e0719 100644 --- a/unified/extractor/tests/corpus/swift/desugar.txt +++ b/unified/extractor/tests/corpus/swift/desugar.txt @@ -17,7 +17,7 @@ source_file top_level body: binary_expr - operator: operator "3" + operator: operator "+" left: unsupported_node "1" right: unsupported_node "2" @@ -40,6 +40,6 @@ source_file top_level body: binary_expr - operator: operator "3" + operator: operator "+" left: name_expr "foo" right: name_expr "bar" diff --git a/unified/extractor/tests/corpus/swift/operators.txt b/unified/extractor/tests/corpus/swift/operators.txt index caa88c3cef4..15cc19df455 100644 --- a/unified/extractor/tests/corpus/swift/operators.txt +++ b/unified/extractor/tests/corpus/swift/operators.txt @@ -17,7 +17,7 @@ source_file top_level body: binary_expr - operator: operator "3" + operator: operator "+" left: name_expr "a" right: name_expr "b" @@ -40,7 +40,7 @@ source_file top_level body: binary_expr - operator: operator "3" + operator: operator "-" left: name_expr "a" right: name_expr "b" @@ -63,7 +63,7 @@ source_file top_level body: binary_expr - operator: operator "3" + operator: operator "*" left: name_expr "a" right: name_expr "b" @@ -86,7 +86,7 @@ source_file top_level body: binary_expr - operator: operator "3" + operator: operator "/" left: name_expr "a" right: name_expr "b" @@ -113,11 +113,11 @@ source_file top_level body: binary_expr - operator: operator "3" + operator: operator "+" left: name_expr "a" right: binary_expr - operator: operator "6" + operator: operator "*" left: name_expr "b" right: name_expr "c" @@ -146,7 +146,7 @@ source_file top_level body: binary_expr - operator: operator "9" + operator: operator "*" left: unsupported_node "(a + b)" right: name_expr "c" From 92838011dda962714311a9d2c19e2f2f7693f900 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 11 May 2026 13:56:20 +0200 Subject: [PATCH 056/226] Unified: Add some more AST nodes and rules --- unified/extractor/ast_types.yml | 26 +++- .../extractor/src/languages/swift/swift.rs | 132 +++++++++++++++++- .../extractor/tests/corpus/swift/closures.txt | 39 +++++- .../tests/corpus/swift/collections.txt | 72 ++++++++-- .../tests/corpus/swift/control-flow.txt | 27 +++- .../extractor/tests/corpus/swift/desugar.txt | 12 +- .../extractor/tests/corpus/swift/literals.txt | 11 +- .../tests/corpus/swift/operators.txt | 101 +++++++++++--- .../corpus/swift/optionals-and-errors.txt | 53 ++++++- .../tests/corpus/swift/variables.txt | 59 +++++++- 10 files changed, 470 insertions(+), 62 deletions(-) diff --git a/unified/extractor/ast_types.yml b/unified/extractor/ast_types.yml index 714a1eada60..945cbda7d00 100644 --- a/unified/extractor/ast_types.yml +++ b/unified/extractor/ast_types.yml @@ -1,8 +1,10 @@ supertypes: expr: + - name_expr + - int_literal + - string_literal - binary_expr - unary_expr - - name_expr - lambda_expr - unsupported_node stmt: @@ -23,7 +25,17 @@ supertypes: named: # Top-level is the root node, currently containing a list of expressions top_level: - body*: expr + body*: [expr, stmt] + + # An identifier used in the context of an expression + name_expr: + identifier: identifier + + # An integer literal + int_literal: + + # A string literal + string_literal: # Application of a binary operator, such as `a + b` binary_expr: @@ -36,10 +48,6 @@ named: operand: expr operator: operator - # An identifier used in the context of an expression - name_expr: - identifier: identifier - lambda_expr: parameter*: parameter body: [expr, stmt] @@ -50,6 +58,12 @@ named: empty_stmt: + block_stmt: + body*: stmt + + expr_stmt: + expr: expr + if_stmt: condition: condition then?: stmt diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index ebf571b7057..085222ec818 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -10,6 +10,10 @@ fn translation_rules() -> Vec { body: {..children} ) ), + // ---- Binary expressions ---- + // Swift's parser produces a different node kind for each operator + // family, but the field shape (`lhs` / `op` / `rhs`) is uniform, so + // each maps onto `binary_expr`. rule!( (additive_expression lhs: (_) @left @@ -33,10 +37,134 @@ fn translation_rules() -> Vec { right: {right}) ), rule!( - (simple_identifier) + (comparison_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) => - name_expr + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) ), + rule!( + (equality_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (conjunction_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (disjunction_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (nil_coalescing_expression + lhs: (_) @left + op: _ @operator + rhs: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + rule!( + (range_expression + start: (_) @left + op: _ @operator + end: (_) @right) + => + (binary_expr + left: {left} + operator: (operator #{operator}) + right: {right}) + ), + // ---- Unary expressions ---- + rule!( + (prefix_expression + operation: _ @operator + target: (_) @operand) + => + (unary_expr + operand: {operand} + operator: (operator #{operator})) + ), + // ---- Identifiers / name expressions ---- + rule!( + (simple_identifier) @name + => + (name_expr + identifier: (identifier #{name})) + ), + // ---- Literals ---- + rule!( + (integer_literal) @lit + => + (int_literal #{lit}) + ), + // String literals: render the *raw* source text, including the + // surrounding quotes. Interpolations (e.g. `"hi \(x)"`) are not + // yet broken out into structured pieces \u2014 they show up as part + // of the literal's source text. + rule!( + (line_string_literal) @lit + => + (string_literal #{lit}) + ), + // ---- Patterns ---- + // The Swift parser uses a `pattern` node with a `bound_identifier` + // field for simple bindings such as `let x = ...`. + rule!( + (pattern bound_identifier: (simple_identifier) @id) + => + (var_pattern + identifier: (identifier #{id})) + ), + // ---- Variable declarations ---- + // `let x = e` / `var x = e` (with initializer). + rule!( + (property_declaration + name: (_) @pat + value: (_) @value) + => + (variable_declaration_stmt + variable_declarator: (variable_declarator + pattern: {pat} + value: {value})) + ), + // `var x: T` (no initializer). + rule!( + (property_declaration + name: (_) @pat) + => + (variable_declaration_stmt + variable_declarator: (variable_declarator + pattern: {pat})) + ), + // ---- Fallbacks ---- rule!( (_) => diff --git a/unified/extractor/tests/corpus/swift/closures.txt b/unified/extractor/tests/corpus/swift/closures.txt index 08af80c3f65..12d4e99d81f 100644 --- a/unified/extractor/tests/corpus/swift/closures.txt +++ b/unified/extractor/tests/corpus/swift/closures.txt @@ -2,11 +2,13 @@ Closure with explicit parameters === +// TODO: map lambda_literal -> lambda_expr let f = { (x: Int) -> Int in x * 2 } --- source_file + comment "// TODO: map lambda_literal -> lambda_expr" property_declaration name: pattern @@ -35,7 +37,15 @@ source_file --- top_level - body: unsupported_node "let f = { (x: Int) -> Int in x * 2 }" + body: + unsupported_node "// TODO: map lambda_literal -> lambda_expr" + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "{ (x: Int) -> Int in x * 2 }" + pattern: + var_pattern + identifier: identifier "f" === Closure with shorthand parameters @@ -63,7 +73,14 @@ source_file --- top_level - body: unsupported_node "let f = { $0 + $1 }" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "{ $0 + $1 }" + pattern: + var_pattern + identifier: identifier "f" === Trailing closure @@ -130,7 +147,14 @@ source_file --- top_level - body: unsupported_node "let f = { [weak self] in self?.doThing() }" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "{ [weak self] in self?.doThing() }" + pattern: + var_pattern + identifier: identifier "f" === Multi-statement closure @@ -185,4 +209,11 @@ source_file --- top_level - body: unsupported_node "let f = { (x: Int) -> Int in\n let y = x + 1\n return y * 2\n}" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "{ (x: Int) -> Int in\n let y = x + 1\n return y * 2\n}" + pattern: + var_pattern + identifier: identifier "f" diff --git a/unified/extractor/tests/corpus/swift/collections.txt b/unified/extractor/tests/corpus/swift/collections.txt index 76015e75baa..d5639054488 100644 --- a/unified/extractor/tests/corpus/swift/collections.txt +++ b/unified/extractor/tests/corpus/swift/collections.txt @@ -23,7 +23,14 @@ source_file --- top_level - body: unsupported_node "let xs = [1, 2, 3]" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "[1, 2, 3]" + pattern: + var_pattern + identifier: identifier "xs" === Empty array literal with type @@ -52,7 +59,14 @@ source_file --- top_level - body: unsupported_node "let xs: [Int] = []" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "[]" + pattern: + var_pattern + identifier: identifier "xs" === Dictionary literal @@ -83,7 +97,14 @@ source_file --- top_level - body: unsupported_node "let d = [\"a\": 1, \"b\": 2]" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "[\"a\": 1, \"b\": 2]" + pattern: + var_pattern + identifier: identifier "d" === Set literal @@ -118,7 +139,14 @@ source_file --- top_level - body: unsupported_node "let s: Set = [1, 2, 3]" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "[1, 2, 3]" + pattern: + var_pattern + identifier: identifier "s" === Tuple literal @@ -146,7 +174,14 @@ source_file --- top_level - body: unsupported_node "let t = (1, \"two\", 3.0)" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "(1, \"two\", 3.0)" + pattern: + var_pattern + identifier: identifier "t" === Subscript access @@ -174,7 +209,14 @@ source_file --- top_level - body: unsupported_node "let first = xs[0]" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "xs[0]" + pattern: + var_pattern + identifier: identifier "first" === Dictionary subscript @@ -204,7 +246,14 @@ source_file --- top_level - body: unsupported_node "let v = d[\"key\"]" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "d[\"key\"]" + pattern: + var_pattern + identifier: identifier "v" === Tuple member access @@ -231,4 +280,11 @@ source_file --- top_level - body: unsupported_node "let n = t.0" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "t.0" + pattern: + var_pattern + identifier: identifier "n" diff --git a/unified/extractor/tests/corpus/swift/control-flow.txt b/unified/extractor/tests/corpus/swift/control-flow.txt index ec54f9481f1..d48febb44a5 100644 --- a/unified/extractor/tests/corpus/swift/control-flow.txt +++ b/unified/extractor/tests/corpus/swift/control-flow.txt @@ -2,6 +2,7 @@ If statement === +// TODO: map if_statement -> if_stmt (needs a block-body stmt in ast_types.yml) if x > 0 { print(x) } @@ -9,6 +10,7 @@ if x > 0 { --- source_file + comment "// TODO: map if_statement -> if_stmt (needs a block-body stmt in ast_types.yml)" if_statement condition: comparison_expression @@ -26,7 +28,9 @@ source_file --- top_level - body: unsupported_node "if x > 0 {\n print(x)\n}" + body: + unsupported_node "// TODO: map if_statement -> if_stmt (needs a block-body stmt in ast_types.yml)" + unsupported_node "if x > 0 {\n print(x)\n}" === If-else @@ -131,6 +135,7 @@ top_level If-let optional binding === +// TODO: map if-let -> if_stmt with let_pattern_condition if let value = optional { print(value) } @@ -138,6 +143,7 @@ if let value = optional { --- source_file + comment "// TODO: map if-let -> if_stmt with let_pattern_condition" if_statement bound_identifier: simple_identifier "value" condition: @@ -156,17 +162,21 @@ source_file --- top_level - body: unsupported_node "if let value = optional {\n print(value)\n}" + body: + unsupported_node "// TODO: map if-let -> if_stmt with let_pattern_condition" + unsupported_node "if let value = optional {\n print(value)\n}" === Guard let === +// TODO: map guard_statement -> guard_if_stmt (with let_pattern_condition) guard let value = optional else { return } --- source_file + comment "// TODO: map guard_statement -> guard_if_stmt (with let_pattern_condition)" guard_statement bound_identifier: simple_identifier "value" condition: @@ -181,7 +191,9 @@ source_file --- top_level - body: unsupported_node "guard let value = optional else { return }" + body: + unsupported_node "// TODO: map guard_statement -> guard_if_stmt (with let_pattern_condition)" + unsupported_node "guard let value = optional else { return }" === Ternary expression @@ -214,7 +226,14 @@ source_file --- top_level - body: unsupported_node "let y = x > 0 ? 1 : -1" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "x > 0 ? 1 : -1" + pattern: + var_pattern + identifier: identifier "y" === Switch statement diff --git a/unified/extractor/tests/corpus/swift/desugar.txt b/unified/extractor/tests/corpus/swift/desugar.txt index bcdca0e0719..4e0defef022 100644 --- a/unified/extractor/tests/corpus/swift/desugar.txt +++ b/unified/extractor/tests/corpus/swift/desugar.txt @@ -18,8 +18,8 @@ top_level body: binary_expr operator: operator "+" - left: unsupported_node "1" - right: unsupported_node "2" + left: int_literal "1" + right: int_literal "2" === Another additive expression is desugared @@ -41,5 +41,9 @@ top_level body: binary_expr operator: operator "+" - left: name_expr "foo" - right: name_expr "bar" + left: + name_expr + identifier: identifier "foo" + right: + name_expr + identifier: identifier "bar" diff --git a/unified/extractor/tests/corpus/swift/literals.txt b/unified/extractor/tests/corpus/swift/literals.txt index 5e42e60e89f..5f44733e136 100644 --- a/unified/extractor/tests/corpus/swift/literals.txt +++ b/unified/extractor/tests/corpus/swift/literals.txt @@ -12,7 +12,7 @@ source_file --- top_level - body: unsupported_node "42" + body: int_literal "42" === Negative integer literal @@ -30,7 +30,10 @@ source_file --- top_level - body: unsupported_node "-7" + body: + unary_expr + operator: operator "-" + operand: int_literal "7" === Floating-point literal @@ -98,7 +101,7 @@ source_file --- top_level - body: unsupported_node "\"hello\"" + body: string_literal "\"hello\"" === String with interpolation @@ -118,4 +121,4 @@ source_file --- top_level - body: unsupported_node "\"hello \\(name)\"" + body: string_literal "\"hello \\(name)\"" diff --git a/unified/extractor/tests/corpus/swift/operators.txt b/unified/extractor/tests/corpus/swift/operators.txt index 15cc19df455..173f6e92976 100644 --- a/unified/extractor/tests/corpus/swift/operators.txt +++ b/unified/extractor/tests/corpus/swift/operators.txt @@ -18,8 +18,12 @@ top_level body: binary_expr operator: operator "+" - left: name_expr "a" - right: name_expr "b" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" === Subtraction @@ -41,8 +45,12 @@ top_level body: binary_expr operator: operator "-" - left: name_expr "a" - right: name_expr "b" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" === Multiplication @@ -64,8 +72,12 @@ top_level body: binary_expr operator: operator "*" - left: name_expr "a" - right: name_expr "b" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" === Division @@ -87,8 +99,12 @@ top_level body: binary_expr operator: operator "/" - left: name_expr "a" - right: name_expr "b" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" === Operator precedence: addition and multiplication @@ -114,12 +130,18 @@ top_level body: binary_expr operator: operator "+" - left: name_expr "a" + left: + name_expr + identifier: identifier "a" right: binary_expr operator: operator "*" - left: name_expr "b" - right: name_expr "c" + left: + name_expr + identifier: identifier "b" + right: + name_expr + identifier: identifier "c" === Parenthesised expression @@ -148,7 +170,9 @@ top_level binary_expr operator: operator "*" left: unsupported_node "(a + b)" - right: name_expr "c" + right: + name_expr + identifier: identifier "c" === Comparison @@ -167,7 +191,15 @@ source_file --- top_level - body: unsupported_node "a < b" + body: + binary_expr + operator: operator "<" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" === Equality @@ -186,7 +218,15 @@ source_file --- top_level - body: unsupported_node "a == b" + body: + binary_expr + operator: operator "==" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" === Logical and @@ -205,7 +245,15 @@ source_file --- top_level - body: unsupported_node "a && b" + body: + binary_expr + operator: operator "&&" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" === Logical or @@ -224,7 +272,15 @@ source_file --- top_level - body: unsupported_node "a || b" + body: + binary_expr + operator: operator "||" + left: + name_expr + identifier: identifier "a" + right: + name_expr + identifier: identifier "b" === Logical not @@ -242,7 +298,12 @@ source_file --- top_level - body: unsupported_node "!a" + body: + unary_expr + operator: operator "!" + operand: + name_expr + identifier: identifier "a" === Range operator @@ -261,4 +322,8 @@ source_file --- top_level - body: unsupported_node "1...10" + body: + binary_expr + operator: operator "..." + left: int_literal "1" + right: int_literal "10" diff --git a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt index 3b3310c4fb9..43c0e7d7f0d 100644 --- a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt +++ b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt @@ -24,7 +24,13 @@ source_file --- top_level - body: unsupported_node "let x: Int? = nil" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + pattern: + var_pattern + identifier: identifier "x" === Optional chaining @@ -59,7 +65,14 @@ source_file --- top_level - body: unsupported_node "let n = obj?.foo?.bar" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "obj?.foo?.bar" + pattern: + var_pattern + identifier: identifier "n" === Force unwrap @@ -84,7 +97,14 @@ source_file --- top_level - body: unsupported_node "let n = opt!" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "opt!" + pattern: + var_pattern + identifier: identifier "n" === Nil-coalescing @@ -109,7 +129,14 @@ source_file --- top_level - body: unsupported_node "let n = opt ?? 0" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "opt ?? 0" + pattern: + var_pattern + identifier: identifier "n" === Throwing function @@ -204,7 +231,14 @@ source_file --- top_level - body: unsupported_node "let result = try? foo()" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "try? foo()" + pattern: + var_pattern + identifier: identifier "result" === Try! expression @@ -233,4 +267,11 @@ source_file --- top_level - body: unsupported_node "let result = try! foo()" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: unsupported_node "try! foo()" + pattern: + var_pattern + identifier: identifier "result" diff --git a/unified/extractor/tests/corpus/swift/variables.txt b/unified/extractor/tests/corpus/swift/variables.txt index 429aac05867..b4f274f6cee 100644 --- a/unified/extractor/tests/corpus/swift/variables.txt +++ b/unified/extractor/tests/corpus/swift/variables.txt @@ -18,7 +18,14 @@ source_file --- top_level - body: unsupported_node "let x = 1" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: int_literal "1" + pattern: + var_pattern + identifier: identifier "x" === Var binding @@ -40,7 +47,14 @@ source_file --- top_level - body: unsupported_node "var x = 1" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: int_literal "1" + pattern: + var_pattern + identifier: identifier "x" === Let with type annotation @@ -66,7 +80,14 @@ source_file --- top_level - body: unsupported_node "let x: Int = 1" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: int_literal "1" + pattern: + var_pattern + identifier: identifier "x" === Var without initialiser @@ -91,17 +112,25 @@ source_file --- top_level - body: unsupported_node "var x: Int" + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + pattern: + var_pattern + identifier: identifier "x" === Tuple destructuring binding === +// TODO: map tuple destructuring pattern -> apply_pattern let (a, b) = pair --- source_file + comment "// TODO: map tuple destructuring pattern -> apply_pattern" property_declaration name: pattern @@ -116,17 +145,27 @@ source_file --- top_level - body: unsupported_node "let (a, b) = pair" + body: + unsupported_node "// TODO: map tuple destructuring pattern -> apply_pattern" + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + name_expr + identifier: identifier "pair" + pattern: unsupported_node "(a, b)" === Multiple bindings on one line === +// TODO: emit multiple variable_declarators in one variable_declaration_stmt let x = 1, y = 2 --- source_file + comment "// TODO: emit multiple variable_declarators in one variable_declaration_stmt" property_declaration name: pattern @@ -142,7 +181,15 @@ source_file --- top_level - body: unsupported_node "let x = 1, y = 2" + body: + unsupported_node "// TODO: emit multiple variable_declarators in one variable_declaration_stmt" + variable_declaration_stmt + variable_declarator: + variable_declarator + value: int_literal "1" + pattern: + var_pattern + identifier: identifier "x" === Assignment From 2307839050174554ab82e811ba000e659d54dfa7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 11 May 2026 14:11:16 +0200 Subject: [PATCH 057/226] Yeast: Change how patterns with repetition are parsed --- shared/yeast-macros/src/parse.rs | 39 +++++++++++++++++-- .../tests/corpus/swift/operators.txt | 2 +- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index 4a8a53a47f2..c9510620353 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -122,10 +122,41 @@ fn parse_query_fields(tokens: &mut Tokens) -> Result> { expect_punct(tokens, ':', "expected `:` after field name")?; - let child = parse_query_node(tokens)?; - fields.push(quote! { - (#field_str, vec![yeast::query::QueryListElem::SingleNode(#child)]) - }); + // Parse the field's pattern. To support repetition like + // `field: (kind)* @cap`, parse the atom first, then check for + // a quantifier, and lastly handle a trailing `@capture`. + let atom = parse_query_atom(tokens)?; + if peek_is_repetition(tokens) { + let rep = expect_repetition(tokens)?; + let elem = quote! { + yeast::query::QueryListElem::Repeated { + children: vec![yeast::query::QueryListElem::SingleNode(#atom)], + rep: #rep, + } + }; + let elem = maybe_wrap_list_capture(tokens, elem)?; + fields.push(quote! { + (#field_str, vec![#elem]) + }); + } else { + let child = if peek_is_at(tokens) { + tokens.next(); + let capture_name = + expect_ident(tokens, "expected capture name after @")?; + let name_str = capture_name.to_string(); + quote! { + yeast::query::QueryNode::Capture { + capture: #name_str, + node: Box::new(#atom), + } + } + } else { + atom + }; + fields.push(quote! { + (#field_str, vec![yeast::query::QueryListElem::SingleNode(#child)]) + }); + } } else { // Bare patterns — accumulate into the implicit `child` field. // We don't break here, so we can interleave with named fields. diff --git a/unified/extractor/tests/corpus/swift/operators.txt b/unified/extractor/tests/corpus/swift/operators.txt index 173f6e92976..78cbe757743 100644 --- a/unified/extractor/tests/corpus/swift/operators.txt +++ b/unified/extractor/tests/corpus/swift/operators.txt @@ -300,7 +300,7 @@ source_file top_level body: unary_expr - operator: operator "!" + operator: operator "!a" operand: name_expr identifier: identifier "a" From 6b58482dfb508723389a87d11bbadfbb882be86f Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 11 May 2026 13:55:14 +0200 Subject: [PATCH 058/226] Yeast: Fix text associated with synthesized nodes --- shared/yeast/src/lib.rs | 29 ++++++++++++------- .../tests/corpus/swift/operators.txt | 2 +- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index 541b1bb3811..8826c3d6c1e 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -268,18 +268,27 @@ impl Ast { /// against the stored source bytes when available. pub fn source_text(&self, id: Id) -> String { let Some(node) = self.get_node(id) else { return String::new(); }; - match &node.content { - NodeContent::Range(range) => { - let start = range.start_byte; - let end = range.end_byte; - if end <= self.source.len() && start <= end { - String::from_utf8_lossy(&self.source[start..end]).into_owned() - } else { - String::new() - } + let read_range = |range: &tree_sitter::Range| { + let start = range.start_byte; + let end = range.end_byte; + if end <= self.source.len() && start <= end { + String::from_utf8_lossy(&self.source[start..end]).into_owned() + } else { + String::new() } + }; + match &node.content { + NodeContent::Range(range) => read_range(range), NodeContent::String(s) => s.to_string(), - NodeContent::DynamicString(s) => s.clone(), + NodeContent::DynamicString(s) if !s.is_empty() => s.clone(), + // Synthesized nodes (from rule transforms) carry an empty + // `DynamicString`; resolve them against the inherited source + // range so `#{capture}` after a translation still yields the + // original source text. + NodeContent::DynamicString(_) => match node.source_range { + Some(range) => read_range(&range), + None => String::new(), + }, } } diff --git a/unified/extractor/tests/corpus/swift/operators.txt b/unified/extractor/tests/corpus/swift/operators.txt index 78cbe757743..173f6e92976 100644 --- a/unified/extractor/tests/corpus/swift/operators.txt +++ b/unified/extractor/tests/corpus/swift/operators.txt @@ -300,7 +300,7 @@ source_file top_level body: unary_expr - operator: operator "!a" + operator: operator "!" operand: name_expr identifier: identifier "a" From a966dff76e1e755028549731de25a8e7fc220fc9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 11 May 2026 14:14:00 +0200 Subject: [PATCH 059/226] Unified: Add more patterns and some fixes to the AST --- unified/extractor/ast_types.yml | 4 +- .../extractor/src/languages/swift/swift.rs | 138 ++++++++++++++++-- .../extractor/tests/corpus/swift/closures.txt | 46 +++++- .../tests/corpus/swift/control-flow.txt | 99 +++++++++++-- .../tests/corpus/swift/variables.txt | 22 ++- 5 files changed, 266 insertions(+), 43 deletions(-) diff --git a/unified/extractor/ast_types.yml b/unified/extractor/ast_types.yml index 945cbda7d00..511e8c14fc5 100644 --- a/unified/extractor/ast_types.yml +++ b/unified/extractor/ast_types.yml @@ -9,6 +9,8 @@ supertypes: - unsupported_node stmt: - empty_stmt + - block_stmt + - expr_stmt - if_stmt - variable_declaration_stmt - guard_if_stmt @@ -105,7 +107,7 @@ named: # A pattern such as `Some(x)` where `Some` is the constructor and `x` is an argument apply_pattern: constructor: expr - argument*: expr + argument*: pattern # An simple unqualified identifier token identifier: diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index 085222ec818..2f72f4f79be 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -133,8 +133,99 @@ fn translation_rules() -> Vec { (line_string_literal) @lit => (string_literal #{lit}) + ), // ---- Lambdas / closures ---- + // Map a `lambda_literal` whose body is a single statement to + // `lambda_expr`. Multi-statement bodies fall through to + // `unsupported_node` because `lambda_expr.body` is single-valued + // in the current `ast_types.yml`. Parameters from explicit-typed + // closures (`{ (x: Int) -> Int in ... }`) are not yet captured. + rule!( + (lambda_literal + (statements (_) @body)) + => + (lambda_expr + body: {body}) ), - // ---- Patterns ---- + // ---- Block / statement wrapping ---- + // A `(statements ...)` node corresponds to a brace-delimited block. + // Each child is mapped through translation; bare expression results + // get wrapped in `expr_stmt`. + rule!( + (statements (_)* @stmts) + => + (block_stmt body: {..stmts}) + ), + // ---- Guard statement ---- + // `guard let x = e else { ... }` — currently only handles the + // let-binding form, since plain `guard cond else { ... }` is not + // exercised by any existing corpus test. + rule!( + (guard_statement + bound_identifier: (simple_identifier) @id + condition: (_)* @cond_children + (else) + (statements) @else_branch) + => + (guard_if_stmt + condition: (let_pattern_condition + pattern: (var_pattern identifier: (identifier #{id})) + value: {*cond_children.last().unwrap()}) + else: {else_branch}) + ), + // ---- If statement ---- + // if-let binding (with optional else branch). The Swift parser puts + // the bound name in `bound_identifier` and the source expression as + // the last child of the multi-child `condition` field. + rule!( + (if_statement + bound_identifier: (simple_identifier) @id + condition: (_)* @cond_children + (statements) @then + (else) + (_) @else_branch) + => + (if_stmt + condition: (let_pattern_condition + pattern: (var_pattern identifier: (identifier #{id})) + value: {*cond_children.last().unwrap()}) + then: {then} + else: {else_branch}) + ), + rule!( + (if_statement + bound_identifier: (simple_identifier) @id + condition: (_)* @cond_children + (statements) @then) + => + (if_stmt + condition: (let_pattern_condition + pattern: (var_pattern identifier: (identifier #{id})) + value: {*cond_children.last().unwrap()}) + then: {then}) + ), + // With explicit else branch (block or chained if). + rule!( + (if_statement + condition: (_) @cond + (statements) @then + (else) + (_) @else_branch) + => + (if_stmt + condition: (expr_condition expr: {cond}) + then: {then} + else: {else_branch}) + ), + // Without else branch. + rule!( + (if_statement + condition: (_) @cond + (statements) @then) + => + (if_stmt + condition: (expr_condition expr: {cond}) + then: {then}) + ), // ---- Patterns ---- // The Swift parser uses a `pattern` node with a `bound_identifier` // field for simple bindings such as `let x = ...`. rule!( @@ -143,26 +234,45 @@ fn translation_rules() -> Vec { (var_pattern identifier: (identifier #{id})) ), - // ---- Variable declarations ---- - // `let x = e` / `var x = e` (with initializer). + // Inside tuple patterns, the inner `pattern` node holds a bare + // `simple_identifier` (with no `bound_identifier` field). rule!( - (property_declaration - name: (_) @pat - value: (_) @value) + (pattern (simple_identifier) @id) => - (variable_declaration_stmt - variable_declarator: (variable_declarator - pattern: {pat} - value: {value})) + (var_pattern + identifier: (identifier #{id})) ), - // `var x: T` (no initializer). + // Tuple destructuring pattern, e.g. `let (a, b) = pair`. The parser + // emits a `pattern` node whose unnamed children are themselves + // `pattern` nodes. We synthesize a `tuple` constructor since the + // syntax has no name. + rule!( + (pattern (pattern)+ @parts) + => + (apply_pattern + constructor: (name_expr identifier: (identifier "tuple")) + argument: {..parts}) + ), + // ---- Variable declarations ---- + // Handles single (`let x = e`), multiple (`let x = 1, y = 2`), + // and uninitialized (`var x: T`) bindings. rule!( (property_declaration - name: (_) @pat) + name: (_)* @pats + value: (_)* @vals) => (variable_declaration_stmt - variable_declarator: (variable_declarator - pattern: {pat})) + variable_declarator: {..pats.iter().enumerate().map(|(i, &pat)| { + match vals.get(i).copied() { + Some(val) => yeast::tree!( + (variable_declarator + pattern: {pat} + value: {val})), + None => yeast::tree!( + (variable_declarator + pattern: {pat})), + } + })}) ), // ---- Fallbacks ---- rule!( diff --git a/unified/extractor/tests/corpus/swift/closures.txt b/unified/extractor/tests/corpus/swift/closures.txt index 12d4e99d81f..0abb205bbfe 100644 --- a/unified/extractor/tests/corpus/swift/closures.txt +++ b/unified/extractor/tests/corpus/swift/closures.txt @@ -2,13 +2,11 @@ Closure with explicit parameters === -// TODO: map lambda_literal -> lambda_expr let f = { (x: Int) -> Int in x * 2 } --- source_file - comment "// TODO: map lambda_literal -> lambda_expr" property_declaration name: pattern @@ -38,11 +36,18 @@ source_file top_level body: - unsupported_node "// TODO: map lambda_literal -> lambda_expr" variable_declaration_stmt variable_declarator: variable_declarator - value: unsupported_node "{ (x: Int) -> Int in x * 2 }" + value: + lambda_expr + body: + binary_expr + operator: operator "*" + left: + name_expr + identifier: identifier "x" + right: int_literal "2" pattern: var_pattern identifier: identifier "f" @@ -77,7 +82,17 @@ top_level variable_declaration_stmt variable_declarator: variable_declarator - value: unsupported_node "{ $0 + $1 }" + value: + lambda_expr + body: + binary_expr + operator: operator "+" + left: + name_expr + identifier: identifier "$0" + right: + name_expr + identifier: identifier "$1" pattern: var_pattern identifier: identifier "f" @@ -151,7 +166,9 @@ top_level variable_declaration_stmt variable_declarator: variable_declarator - value: unsupported_node "{ [weak self] in self?.doThing() }" + value: + lambda_expr + body: unsupported_node "self?.doThing()" pattern: var_pattern identifier: identifier "f" @@ -213,7 +230,22 @@ top_level variable_declaration_stmt variable_declarator: variable_declarator - value: unsupported_node "{ (x: Int) -> Int in\n let y = x + 1\n return y * 2\n}" + value: + lambda_expr + body: + variable_declaration_stmt + variable_declarator: + variable_declarator + value: + binary_expr + operator: operator "+" + left: + name_expr + identifier: identifier "x" + right: int_literal "1" + pattern: + var_pattern + identifier: identifier "y" pattern: var_pattern identifier: identifier "f" diff --git a/unified/extractor/tests/corpus/swift/control-flow.txt b/unified/extractor/tests/corpus/swift/control-flow.txt index d48febb44a5..6792c94dd7b 100644 --- a/unified/extractor/tests/corpus/swift/control-flow.txt +++ b/unified/extractor/tests/corpus/swift/control-flow.txt @@ -2,7 +2,6 @@ If statement === -// TODO: map if_statement -> if_stmt (needs a block-body stmt in ast_types.yml) if x > 0 { print(x) } @@ -10,7 +9,6 @@ if x > 0 { --- source_file - comment "// TODO: map if_statement -> if_stmt (needs a block-body stmt in ast_types.yml)" if_statement condition: comparison_expression @@ -29,8 +27,19 @@ source_file top_level body: - unsupported_node "// TODO: map if_statement -> if_stmt (needs a block-body stmt in ast_types.yml)" - unsupported_node "if x > 0 {\n print(x)\n}" + if_stmt + condition: + expr_condition + expr: + binary_expr + operator: operator ">" + left: + name_expr + identifier: identifier "x" + right: int_literal "0" + then: + block_stmt + body: unsupported_node "print(x)" === If-else @@ -73,7 +82,23 @@ source_file --- top_level - body: unsupported_node "if x > 0 {\n print(x)\n} else {\n print(-x)\n}" + body: + if_stmt + condition: + expr_condition + expr: + binary_expr + operator: operator ">" + left: + name_expr + identifier: identifier "x" + right: int_literal "0" + else: + block_stmt + body: unsupported_node "print(-x)" + then: + block_stmt + body: unsupported_node "print(x)" === If-else-if chain @@ -129,13 +154,42 @@ source_file --- top_level - body: unsupported_node "if x > 0 {\n print(1)\n} else if x < 0 {\n print(2)\n} else {\n print(3)\n}" + body: + if_stmt + condition: + expr_condition + expr: + binary_expr + operator: operator ">" + left: + name_expr + identifier: identifier "x" + right: int_literal "0" + else: + if_stmt + condition: + expr_condition + expr: + binary_expr + operator: operator "<" + left: + name_expr + identifier: identifier "x" + right: int_literal "0" + else: + block_stmt + body: unsupported_node "print(3)" + then: + block_stmt + body: unsupported_node "print(2)" + then: + block_stmt + body: unsupported_node "print(1)" === If-let optional binding === -// TODO: map if-let -> if_stmt with let_pattern_condition if let value = optional { print(value) } @@ -143,7 +197,6 @@ if let value = optional { --- source_file - comment "// TODO: map if-let -> if_stmt with let_pattern_condition" if_statement bound_identifier: simple_identifier "value" condition: @@ -163,20 +216,28 @@ source_file top_level body: - unsupported_node "// TODO: map if-let -> if_stmt with let_pattern_condition" - unsupported_node "if let value = optional {\n print(value)\n}" + if_stmt + condition: + let_pattern_condition + value: + name_expr + identifier: identifier "optional" + pattern: + var_pattern + identifier: identifier "value" + then: + block_stmt + body: unsupported_node "print(value)" === Guard let === -// TODO: map guard_statement -> guard_if_stmt (with let_pattern_condition) guard let value = optional else { return } --- source_file - comment "// TODO: map guard_statement -> guard_if_stmt (with let_pattern_condition)" guard_statement bound_identifier: simple_identifier "value" condition: @@ -192,8 +253,18 @@ source_file top_level body: - unsupported_node "// TODO: map guard_statement -> guard_if_stmt (with let_pattern_condition)" - unsupported_node "guard let value = optional else { return }" + guard_if_stmt + condition: + let_pattern_condition + value: + name_expr + identifier: identifier "optional" + pattern: + var_pattern + identifier: identifier "value" + else: + block_stmt + body: unsupported_node "return" === Ternary expression diff --git a/unified/extractor/tests/corpus/swift/variables.txt b/unified/extractor/tests/corpus/swift/variables.txt index b4f274f6cee..33eff211d11 100644 --- a/unified/extractor/tests/corpus/swift/variables.txt +++ b/unified/extractor/tests/corpus/swift/variables.txt @@ -124,13 +124,11 @@ top_level Tuple destructuring binding === -// TODO: map tuple destructuring pattern -> apply_pattern let (a, b) = pair --- source_file - comment "// TODO: map tuple destructuring pattern -> apply_pattern" property_declaration name: pattern @@ -146,26 +144,32 @@ source_file top_level body: - unsupported_node "// TODO: map tuple destructuring pattern -> apply_pattern" variable_declaration_stmt variable_declarator: variable_declarator value: name_expr identifier: identifier "pair" - pattern: unsupported_node "(a, b)" + pattern: + apply_pattern + argument: + var_pattern + identifier: identifier "a" + var_pattern + identifier: identifier "b" + constructor: + name_expr + identifier: identifier "tuple" === Multiple bindings on one line === -// TODO: emit multiple variable_declarators in one variable_declaration_stmt let x = 1, y = 2 --- source_file - comment "// TODO: emit multiple variable_declarators in one variable_declaration_stmt" property_declaration name: pattern @@ -182,7 +186,6 @@ source_file top_level body: - unsupported_node "// TODO: emit multiple variable_declarators in one variable_declaration_stmt" variable_declaration_stmt variable_declarator: variable_declarator @@ -190,6 +193,11 @@ top_level pattern: var_pattern identifier: identifier "x" + variable_declarator + value: int_literal "2" + pattern: + var_pattern + identifier: identifier "y" === Assignment From ccc1dd5d3e5d91d1bdb9b258d4b45aa8c8613378 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 11 May 2026 14:18:54 +0200 Subject: [PATCH 060/226] Unified: Add tuple_pattern --- unified/extractor/ast_types.yml | 5 +++++ unified/extractor/src/languages/swift/swift.rs | 7 ++----- unified/extractor/tests/corpus/swift/variables.txt | 7 ++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/unified/extractor/ast_types.yml b/unified/extractor/ast_types.yml index 511e8c14fc5..a04e1d38e95 100644 --- a/unified/extractor/ast_types.yml +++ b/unified/extractor/ast_types.yml @@ -22,6 +22,7 @@ supertypes: pattern: - var_pattern - apply_pattern + - tuple_pattern - ignore_pattern - unsupported_node named: @@ -109,6 +110,10 @@ named: constructor: expr argument*: pattern + # A tuple pattern such as `(a, b)` in `let (a, b) = pair`. + tuple_pattern: + element*: pattern + # An simple unqualified identifier token identifier: diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index 2f72f4f79be..9a7d18c8321 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -244,14 +244,11 @@ fn translation_rules() -> Vec { ), // Tuple destructuring pattern, e.g. `let (a, b) = pair`. The parser // emits a `pattern` node whose unnamed children are themselves - // `pattern` nodes. We synthesize a `tuple` constructor since the - // syntax has no name. + // `pattern` nodes. rule!( (pattern (pattern)+ @parts) => - (apply_pattern - constructor: (name_expr identifier: (identifier "tuple")) - argument: {..parts}) + (tuple_pattern element: {..parts}) ), // ---- Variable declarations ---- // Handles single (`let x = e`), multiple (`let x = 1, y = 2`), diff --git a/unified/extractor/tests/corpus/swift/variables.txt b/unified/extractor/tests/corpus/swift/variables.txt index 33eff211d11..96fbbd3b740 100644 --- a/unified/extractor/tests/corpus/swift/variables.txt +++ b/unified/extractor/tests/corpus/swift/variables.txt @@ -151,15 +151,12 @@ top_level name_expr identifier: identifier "pair" pattern: - apply_pattern - argument: + tuple_pattern + element: var_pattern identifier: identifier "a" var_pattern identifier: identifier "b" - constructor: - name_expr - identifier: identifier "tuple" === Multiple bindings on one line From 3b7a53f678af1487746289e20eeae1a7d309dddd Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 11 May 2026 14:39:03 +0200 Subject: [PATCH 061/226] yeast-macros: merge repeated field declarations and support repetition in field patterns Two changes to parse_query_fields: - Allow `field: (kind)* @cap` (repetition + optional capture) in field position, mirroring how it works for bare children. - When the same field name is declared multiple times in a query (e.g. `condition: (foo) condition: (bar)`), merge them into a single ordered list of children rather than emitting duplicate field entries (which at runtime restart the iterator for the field and cause the second declaration to re-match from the first child). --- shared/yeast-macros/src/parse.rs | 36 +++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index c9510620353..7842ef6fb8c 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -113,8 +113,24 @@ fn parse_query_node_inner(tokens: &mut Tokens) -> Result { /// appear in any order; bare patterns are accumulated and emitted as a /// single `("child", ...)` entry. fn parse_query_fields(tokens: &mut Tokens) -> Result> { - let mut fields = Vec::new(); + // Accumulate per-field elems in declaration order; multiple uses of the + // same field name extend the same list (so e.g. `cond: (foo) cond: (bar)` + // matches a `cond` field whose first child is `foo` and second is `bar`). + let mut field_order: Vec = Vec::new(); + let mut field_elems: std::collections::HashMap> = + std::collections::HashMap::new(); let mut bare_children: Vec = Vec::new(); + let mut push_field_elem = |order: &mut Vec, + map: &mut std::collections::HashMap>, + name: String, + elem: TokenStream| { + if !map.contains_key(&name) { + order.push(name.clone()); + map.insert(name, vec![elem]); + } else { + map.get_mut(&name).unwrap().push(elem); + } + }; while tokens.peek().is_some() { if peek_is_field(tokens) { let field_name = expect_ident(tokens, "expected field name")?; @@ -135,9 +151,7 @@ fn parse_query_fields(tokens: &mut Tokens) -> Result> { } }; let elem = maybe_wrap_list_capture(tokens, elem)?; - fields.push(quote! { - (#field_str, vec![#elem]) - }); + push_field_elem(&mut field_order, &mut field_elems, field_str, elem); } else { let child = if peek_is_at(tokens) { tokens.next(); @@ -153,9 +167,10 @@ fn parse_query_fields(tokens: &mut Tokens) -> Result> { } else { atom }; - fields.push(quote! { - (#field_str, vec![yeast::query::QueryListElem::SingleNode(#child)]) - }); + let elem = quote! { + yeast::query::QueryListElem::SingleNode(#child) + }; + push_field_elem(&mut field_order, &mut field_elems, field_str, elem); } } else { // Bare patterns — accumulate into the implicit `child` field. @@ -168,6 +183,13 @@ fn parse_query_fields(tokens: &mut Tokens) -> Result> { bare_children.extend(elems); } } + let mut fields: Vec = Vec::new(); + for name in field_order { + let elems = field_elems.remove(&name).unwrap(); + fields.push(quote! { + (#name, vec![#(#elems),*]) + }); + } if !bare_children.is_empty() { fields.push(quote! { ("child", vec![#(#bare_children),*]) From cbe4c81ca665617342fd209bdecdea41e7008bb5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 11 May 2026 14:39:29 +0200 Subject: [PATCH 062/226] Unified: add tuple_pattern and sequence_condition; refine if-let/guard mapping ast_types.yml additions: - tuple_pattern { element*: pattern } in the pattern supertype. - sequence_condition { stmt*: stmt, condition: condition } in the condition supertype. swift.rs: - Map Swift tuple destructuring (e.g. `let (a, b) = pair`) to the new tuple_pattern instead of synthesizing an apply_pattern. - if-let / guard-let: explicitly match the value_binding_pattern (the `let` keyword) and bind the source expression as the next condition child, so `let` no longer leaks into the output. --- unified/extractor/ast_types.yml | 8 ++++++ .../extractor/src/languages/swift/swift.rs | 25 +++++++++++-------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/unified/extractor/ast_types.yml b/unified/extractor/ast_types.yml index a04e1d38e95..7ed6f9cf854 100644 --- a/unified/extractor/ast_types.yml +++ b/unified/extractor/ast_types.yml @@ -18,6 +18,7 @@ supertypes: condition: - expr_condition - let_pattern_condition + - sequence_condition - unsupported_node pattern: - var_pattern @@ -92,6 +93,13 @@ named: expr_condition: expr: expr + # A series of statements that are executed before evaluating the trailing condition. + # Useful for languages where a conditional clause may be preceded by side-effecting + # syntactic elements (e.g. binding clauses) that don't themselves form a condition. + sequence_condition: + stmt*: stmt + condition: condition + # Evaluate 'expr' and match its result against 'pattern', and return true if it matches. # Variables bound by the pattern will be in scope within the 'true' branch controlled by this condition. let_pattern_condition: diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index 9a7d18c8321..47bfe437ef2 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -157,29 +157,33 @@ fn translation_rules() -> Vec { ), // ---- Guard statement ---- // `guard let x = e else { ... }` — currently only handles the - // let-binding form, since plain `guard cond else { ... }` is not - // exercised by any existing corpus test. + // let-binding form. The Swift parser models the `let` keyword as a + // `value_binding_pattern` child of `condition`, followed by an + // unnamed `=` and the source expression. rule!( (guard_statement bound_identifier: (simple_identifier) @id - condition: (_)* @cond_children + condition: (value_binding_pattern) + condition: (_) @value (else) (statements) @else_branch) => (guard_if_stmt condition: (let_pattern_condition pattern: (var_pattern identifier: (identifier #{id})) - value: {*cond_children.last().unwrap()}) + value: {value}) else: {else_branch}) ), // ---- If statement ---- // if-let binding (with optional else branch). The Swift parser puts - // the bound name in `bound_identifier` and the source expression as - // the last child of the multi-child `condition` field. + // the bound name in `bound_identifier`, the `let` keyword as a + // `value_binding_pattern` child of `condition`, and the source + // expression as a separate child of `condition`. rule!( (if_statement bound_identifier: (simple_identifier) @id - condition: (_)* @cond_children + condition: (value_binding_pattern) + condition: (_) @value (statements) @then (else) (_) @else_branch) @@ -187,20 +191,21 @@ fn translation_rules() -> Vec { (if_stmt condition: (let_pattern_condition pattern: (var_pattern identifier: (identifier #{id})) - value: {*cond_children.last().unwrap()}) + value: {value}) then: {then} else: {else_branch}) ), rule!( (if_statement bound_identifier: (simple_identifier) @id - condition: (_)* @cond_children + condition: (value_binding_pattern) + condition: (_) @value (statements) @then) => (if_stmt condition: (let_pattern_condition pattern: (var_pattern identifier: (identifier #{id})) - value: {*cond_children.last().unwrap()}) + value: {value}) then: {then}) ), // With explicit else branch (block or chained if). From 55194dd757bda4a849eb72ba207332db96e1d5b7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 11 May 2026 15:15:38 +0200 Subject: [PATCH 063/226] Unified: Support for calls and member access --- unified/extractor/ast_types.yml | 13 ++++ .../extractor/src/languages/swift/swift.rs | 64 +++++++++++++++- .../extractor/tests/corpus/swift/closures.txt | 26 ++++++- .../tests/corpus/swift/collections.txt | 29 +++++++- .../tests/corpus/swift/control-flow.txt | 74 +++++++++++++++++-- .../tests/corpus/swift/functions.txt | 26 ++++++- .../corpus/swift/optionals-and-errors.txt | 10 ++- 7 files changed, 224 insertions(+), 18 deletions(-) diff --git a/unified/extractor/ast_types.yml b/unified/extractor/ast_types.yml index 7ed6f9cf854..22a5e8b19fb 100644 --- a/unified/extractor/ast_types.yml +++ b/unified/extractor/ast_types.yml @@ -5,6 +5,8 @@ supertypes: - string_literal - binary_expr - unary_expr + - call_expr + - member_access_expr - lambda_expr - unsupported_node stmt: @@ -52,6 +54,17 @@ named: operand: expr operator: operator + # A function or method call, such as `f(x)` or `obj.m(x)`. Method calls + # are represented as a call whose `function` is a `member_access_expr`. + call_expr: + function: expr + argument*: expr + + # Member access, such as `obj.member`. + member_access_expr: + target: expr + member: identifier + lambda_expr: parameter*: parameter body: [expr, stmt] diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index 47bfe437ef2..23b516815cb 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -1,5 +1,30 @@ use codeql_extractor::extractor::simple; -use yeast::{rule, DesugaringConfig, PhaseKind}; +use yeast::{build::BuildCtx, rule, DesugaringConfig, PhaseKind}; + +/// Names of output AST kinds that belong to the `expr` supertype. Kept in +/// sync with `ast_types.yml`. `unsupported_node` is intentionally omitted +/// because it is also a member of the `stmt` supertype. +const EXPR_KINDS: &[&str] = &[ + "name_expr", + "int_literal", + "string_literal", + "binary_expr", + "unary_expr", + "call_expr", + "member_access_expr", + "lambda_expr", +]; + +/// If `id` is an `expr`, wrap it in `expr_stmt` so it can sit in a `stmt` +/// position; otherwise return it unchanged. +fn wrap_expr_in_stmt(ctx: &mut BuildCtx, id: usize) -> usize { + let kind = ctx.ast.get_node(id).map(|n| n.kind()).unwrap_or(""); + if EXPR_KINDS.contains(&kind) { + yeast::tree!(ctx, (expr_stmt expr: {id})) + } else { + id + } +} fn translation_rules() -> Vec { vec![ @@ -149,11 +174,44 @@ fn translation_rules() -> Vec { // ---- Block / statement wrapping ---- // A `(statements ...)` node corresponds to a brace-delimited block. // Each child is mapped through translation; bare expression results - // get wrapped in `expr_stmt`. + // get wrapped in `expr_stmt` so they fit the `body*: stmt` field. rule!( (statements (_)* @stmts) => - (block_stmt body: {..stmts}) + (block_stmt body: {..stmts.iter().copied().map(|n| + wrap_expr_in_stmt(&mut __yeast_ctx, n.into()) + ).collect::>()}) + ), + // ---- Calls and member access ---- + // Member access, e.g. `obj.member`. The Swift parser wraps the + // member name as `(navigation_suffix suffix: (simple_identifier))`. + rule!( + (navigation_expression + target: (_) @target + suffix: (navigation_suffix + suffix: (simple_identifier) @member)) + => + (member_access_expr + target: {target} + member: (identifier #{member})) + ), + // Function / method call. The callee is the first child of + // `call_expression`; the second is a `call_suffix` whose + // `value_arguments` (if present) hold the parenthesized args. A + // trailing closure (`call_suffix` with a `lambda_literal` child) + // is appended as a final argument. + rule!( + (call_expression + (_) @callee + (call_suffix + (value_arguments + (value_argument value: (_) @args)*)? + (lambda_literal)? @trailing)) + => + (call_expr + function: {callee} + argument: {..args.iter().copied().map(Into::into) + .chain(trailing.map(Into::into)).collect::>()}) ), // ---- Guard statement ---- // `guard let x = e else { ... }` — currently only handles the diff --git a/unified/extractor/tests/corpus/swift/closures.txt b/unified/extractor/tests/corpus/swift/closures.txt index 0abb205bbfe..c10aa78c1fa 100644 --- a/unified/extractor/tests/corpus/swift/closures.txt +++ b/unified/extractor/tests/corpus/swift/closures.txt @@ -123,7 +123,23 @@ source_file --- top_level - body: unsupported_node "xs.map { $0 * 2 }" + body: + call_expr + argument: + lambda_expr + body: + binary_expr + operator: operator "*" + left: + name_expr + identifier: identifier "$0" + right: int_literal "2" + function: + member_access_expr + target: + name_expr + identifier: identifier "xs" + member: identifier "map" === Closure with capture list @@ -168,7 +184,13 @@ top_level variable_declarator value: lambda_expr - body: unsupported_node "self?.doThing()" + body: + call_expr + argument: + function: + member_access_expr + target: unsupported_node "self" + member: identifier "doThing" pattern: var_pattern identifier: identifier "f" diff --git a/unified/extractor/tests/corpus/swift/collections.txt b/unified/extractor/tests/corpus/swift/collections.txt index d5639054488..d5950a18109 100644 --- a/unified/extractor/tests/corpus/swift/collections.txt +++ b/unified/extractor/tests/corpus/swift/collections.txt @@ -187,11 +187,17 @@ top_level Subscript access === +// TODO: tree-sitter-swift parses `xs[0]` as a call_expression (same shape +// as `xs(0)`), so the mapping currently produces a call_expr. Update the +// parser / add a separate subscript_expr node and remap when fixed. let first = xs[0] --- source_file + comment "// TODO: tree-sitter-swift parses `xs[0]` as a call_expression (same shape" + comment "// as `xs(0)`), so the mapping currently produces a call_expr. Update the" + comment "// parser / add a separate subscript_expr node and remap when fixed." property_declaration name: pattern @@ -210,10 +216,18 @@ source_file top_level body: + unsupported_node "// TODO: tree-sitter-swift parses `xs[0]` as a call_expression (same shape" + unsupported_node "// as `xs(0)`), so the mapping currently produces a call_expr. Update the" + unsupported_node "// parser / add a separate subscript_expr node and remap when fixed." variable_declaration_stmt variable_declarator: variable_declarator - value: unsupported_node "xs[0]" + value: + call_expr + argument: int_literal "0" + function: + name_expr + identifier: identifier "xs" pattern: var_pattern identifier: identifier "first" @@ -222,11 +236,15 @@ top_level Dictionary subscript === +// TODO: same parser issue as the array subscript case above — +// `d["key"]` is parsed as `call_expression(d, ("key"))`. let v = d["key"] --- source_file + comment "// TODO: same parser issue as the array subscript case above —" + comment "// `d[\"key\"]` is parsed as `call_expression(d, (\"key\"))`." property_declaration name: pattern @@ -247,10 +265,17 @@ source_file top_level body: + unsupported_node "// TODO: same parser issue as the array subscript case above —" + unsupported_node "// `d[\"key\"]` is parsed as `call_expression(d, (\"key\"))`." variable_declaration_stmt variable_declarator: variable_declarator - value: unsupported_node "d[\"key\"]" + value: + call_expr + argument: string_literal "\"key\"" + function: + name_expr + identifier: identifier "d" pattern: var_pattern identifier: identifier "v" diff --git a/unified/extractor/tests/corpus/swift/control-flow.txt b/unified/extractor/tests/corpus/swift/control-flow.txt index 6792c94dd7b..de2b17e52bb 100644 --- a/unified/extractor/tests/corpus/swift/control-flow.txt +++ b/unified/extractor/tests/corpus/swift/control-flow.txt @@ -39,7 +39,16 @@ top_level right: int_literal "0" then: block_stmt - body: unsupported_node "print(x)" + body: + expr_stmt + expr: + call_expr + argument: + name_expr + identifier: identifier "x" + function: + name_expr + identifier: identifier "print" === If-else @@ -95,10 +104,31 @@ top_level right: int_literal "0" else: block_stmt - body: unsupported_node "print(-x)" + body: + expr_stmt + expr: + call_expr + argument: + unary_expr + operator: operator "-" + operand: + name_expr + identifier: identifier "x" + function: + name_expr + identifier: identifier "print" then: block_stmt - body: unsupported_node "print(x)" + body: + expr_stmt + expr: + call_expr + argument: + name_expr + identifier: identifier "x" + function: + name_expr + identifier: identifier "print" === If-else-if chain @@ -178,13 +208,34 @@ top_level right: int_literal "0" else: block_stmt - body: unsupported_node "print(3)" + body: + expr_stmt + expr: + call_expr + argument: int_literal "3" + function: + name_expr + identifier: identifier "print" then: block_stmt - body: unsupported_node "print(2)" + body: + expr_stmt + expr: + call_expr + argument: int_literal "2" + function: + name_expr + identifier: identifier "print" then: block_stmt - body: unsupported_node "print(1)" + body: + expr_stmt + expr: + call_expr + argument: int_literal "1" + function: + name_expr + identifier: identifier "print" === If-let optional binding @@ -227,7 +278,16 @@ top_level identifier: identifier "value" then: block_stmt - body: unsupported_node "print(value)" + body: + expr_stmt + expr: + call_expr + argument: + name_expr + identifier: identifier "value" + function: + name_expr + identifier: identifier "print" === Guard let diff --git a/unified/extractor/tests/corpus/swift/functions.txt b/unified/extractor/tests/corpus/swift/functions.txt index 5943b75d04d..eb12e995bac 100644 --- a/unified/extractor/tests/corpus/swift/functions.txt +++ b/unified/extractor/tests/corpus/swift/functions.txt @@ -207,7 +207,14 @@ source_file --- top_level - body: unsupported_node "foo(1, 2)" + body: + call_expr + argument: + int_literal "1" + int_literal "2" + function: + name_expr + identifier: identifier "foo" === Function call with labelled arguments @@ -233,7 +240,12 @@ source_file --- top_level - body: unsupported_node "greet(person: \"Bob\")" + body: + call_expr + argument: string_literal "\"Bob\"" + function: + name_expr + identifier: identifier "greet" === Method call @@ -258,7 +270,15 @@ source_file --- top_level - body: unsupported_node "list.append(1)" + body: + call_expr + argument: int_literal "1" + function: + member_access_expr + target: + name_expr + identifier: identifier "list" + member: identifier "append" === Generic function diff --git a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt index 43c0e7d7f0d..acaff1f6ac8 100644 --- a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt +++ b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt @@ -69,7 +69,15 @@ top_level variable_declaration_stmt variable_declarator: variable_declarator - value: unsupported_node "obj?.foo?.bar" + value: + member_access_expr + target: + member_access_expr + target: + name_expr + identifier: identifier "obj" + member: identifier "foo" + member: identifier "bar" pattern: var_pattern identifier: identifier "n" From 600a4969c95204e99684721b757442b396f1475b Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 12 May 2026 12:45:40 +0200 Subject: [PATCH 064/226] Unified: Simplify concatenation of arguments --- unified/extractor/src/languages/swift/swift.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index 23b516815cb..595f56a0b39 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -210,8 +210,9 @@ fn translation_rules() -> Vec { => (call_expr function: {callee} - argument: {..args.iter().copied().map(Into::into) - .chain(trailing.map(Into::into)).collect::>()}) + argument: {..args} + argument: {..trailing} + ) ), // ---- Guard statement ---- // `guard let x = e else { ... }` — currently only handles the From 7fa6c4e4a30d29ff1ec456f571702b8b4824780d Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 May 2026 10:27:09 +0200 Subject: [PATCH 065/226] Unified: Update test output after rebasing on grammar changes The branch was rebased on the grammar changes, but rewriting the history was too difficult, so I'm just updating the test output here. --- .../extractor/tests/corpus/swift/closures.txt | 38 +++--- .../tests/corpus/swift/collections.txt | 29 +++-- .../tests/corpus/swift/control-flow.txt | 113 ++++++------------ .../tests/corpus/swift/functions.txt | 93 ++++++++------ .../extractor/tests/corpus/swift/loops.txt | 36 +++--- .../corpus/swift/optionals-and-errors.txt | 45 ++++--- .../extractor/tests/corpus/swift/types.txt | 106 +++++++++------- .../tests/corpus/swift/variables.txt | 16 ++- 8 files changed, 253 insertions(+), 223 deletions(-) diff --git a/unified/extractor/tests/corpus/swift/closures.txt b/unified/extractor/tests/corpus/swift/closures.txt index c10aa78c1fa..57dbfe79381 100644 --- a/unified/extractor/tests/corpus/swift/closures.txt +++ b/unified/extractor/tests/corpus/swift/closures.txt @@ -15,15 +15,19 @@ source_file lambda_literal type: lambda_function_type - name: - user_type - type_identifier "Int" - lambda_function_type_parameters - lambda_parameter + return_type: + type name: - simple_identifier "x" user_type type_identifier "Int" + lambda_function_type_parameters + lambda_parameter + name: simple_identifier "x" + type: + type + name: + user_type + type_identifier "Int" statements multiplicative_expression lhs: simple_identifier "x" @@ -168,8 +172,8 @@ source_file navigation_suffix suffix: simple_identifier "doThing" target: - self_expression - ? + optional_chain_marker + self_expression call_suffix value_arguments value_binding_pattern @@ -189,7 +193,7 @@ top_level argument: function: member_access_expr - target: unsupported_node "self" + target: unsupported_node "self?" member: identifier "doThing" pattern: var_pattern @@ -215,15 +219,19 @@ source_file lambda_literal type: lambda_function_type - name: - user_type - type_identifier "Int" - lambda_function_type_parameters - lambda_parameter + return_type: + type name: - simple_identifier "x" user_type type_identifier "Int" + lambda_function_type_parameters + lambda_parameter + name: simple_identifier "x" + type: + type + name: + user_type + type_identifier "Int" statements property_declaration name: diff --git a/unified/extractor/tests/corpus/swift/collections.txt b/unified/extractor/tests/corpus/swift/collections.txt index d5950a18109..9a1186ac77d 100644 --- a/unified/extractor/tests/corpus/swift/collections.txt +++ b/unified/extractor/tests/corpus/swift/collections.txt @@ -50,11 +50,15 @@ source_file value_binding_pattern mutability: let type_annotation - name: - array_type + type: + type name: - user_type - type_identifier "Int" + array_type + element: + type + name: + user_type + type_identifier "Int" --- @@ -128,13 +132,16 @@ source_file value_binding_pattern mutability: let type_annotation - name: - user_type - type_identifier "Set" - type_arguments - name: - user_type - type_identifier "Int" + type: + type + name: + user_type + type_identifier "Set" + type_arguments + type + name: + user_type + type_identifier "Int" --- diff --git a/unified/extractor/tests/corpus/swift/control-flow.txt b/unified/extractor/tests/corpus/swift/control-flow.txt index de2b17e52bb..f8526183d4d 100644 --- a/unified/extractor/tests/corpus/swift/control-flow.txt +++ b/unified/extractor/tests/corpus/swift/control-flow.txt @@ -11,10 +11,11 @@ if x > 0 { source_file if_statement condition: - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" statements call_expression simple_identifier "print" @@ -30,13 +31,7 @@ top_level if_stmt condition: expr_condition - expr: - binary_expr - operator: operator ">" - left: - name_expr - identifier: identifier "x" - right: int_literal "0" + expr: unsupported_node "x > 0" then: block_stmt body: @@ -65,10 +60,11 @@ if x > 0 { source_file if_statement condition: - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" statements call_expression simple_identifier "print" @@ -95,13 +91,7 @@ top_level if_stmt condition: expr_condition - expr: - binary_expr - operator: operator ">" - left: - name_expr - identifier: identifier "x" - right: int_literal "0" + expr: unsupported_node "x > 0" else: block_stmt body: @@ -147,10 +137,11 @@ if x > 0 { source_file if_statement condition: - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" statements call_expression simple_identifier "print" @@ -161,10 +152,11 @@ source_file else "else" if_statement condition: - comparison_expression - lhs: simple_identifier "x" - op: < - rhs: integer_literal "0" + if_condition + comparison_expression + lhs: simple_identifier "x" + op: < + rhs: integer_literal "0" statements call_expression simple_identifier "print" @@ -188,24 +180,12 @@ top_level if_stmt condition: expr_condition - expr: - binary_expr - operator: operator ">" - left: - name_expr - identifier: identifier "x" - right: int_literal "0" + expr: unsupported_node "x > 0" else: if_stmt condition: expr_condition - expr: - binary_expr - operator: operator "<" - left: - name_expr - identifier: identifier "x" - right: int_literal "0" + expr: unsupported_node "x < 0" else: block_stmt body: @@ -249,12 +229,13 @@ if let value = optional { source_file if_statement - bound_identifier: simple_identifier "value" condition: - value_binding_pattern - mutability: let - = - simple_identifier "optional" + if_condition + if_let_binding + bound_identifier: simple_identifier "value" + value_binding_pattern + mutability: let + simple_identifier "optional" statements call_expression simple_identifier "print" @@ -269,13 +250,8 @@ top_level body: if_stmt condition: - let_pattern_condition - value: - name_expr - identifier: identifier "optional" - pattern: - var_pattern - identifier: identifier "value" + expr_condition + expr: unsupported_node "let value = optional" then: block_stmt body: @@ -299,12 +275,13 @@ guard let value = optional else { return } source_file guard_statement - bound_identifier: simple_identifier "value" condition: - value_binding_pattern - mutability: let - = - simple_identifier "optional" + if_condition + if_let_binding + bound_identifier: simple_identifier "value" + value_binding_pattern + mutability: let + simple_identifier "optional" else "else" statements control_transfer_statement @@ -312,19 +289,7 @@ source_file --- top_level - body: - guard_if_stmt - condition: - let_pattern_condition - value: - name_expr - identifier: identifier "optional" - pattern: - var_pattern - identifier: identifier "value" - else: - block_stmt - body: unsupported_node "return" + body: unsupported_node "guard let value = optional else { return }" === Ternary expression diff --git a/unified/extractor/tests/corpus/swift/functions.txt b/unified/extractor/tests/corpus/swift/functions.txt index eb12e995bac..3329a6255f3 100644 --- a/unified/extractor/tests/corpus/swift/functions.txt +++ b/unified/extractor/tests/corpus/swift/functions.txt @@ -49,22 +49,28 @@ source_file lhs: simple_identifier "a" op: + rhs: simple_identifier "b" - name: - simple_identifier "add" - user_type - type_identifier "Int" + name: simple_identifier "add" + return_type: + type + name: + user_type + type_identifier "Int" parameter external_name: simple_identifier "_" - name: - simple_identifier "a" - user_type - type_identifier "Int" + name: simple_identifier "a" + type: + type + name: + user_type + type_identifier "Int" parameter external_name: simple_identifier "_" - name: - simple_identifier "b" - user_type - type_identifier "Int" + name: simple_identifier "b" + type: + type + name: + user_type + type_identifier "Int" --- @@ -95,10 +101,12 @@ source_file name: simple_identifier "greet" parameter external_name: simple_identifier "person" - name: - simple_identifier "name" - user_type - type_identifier "String" + name: simple_identifier "name" + type: + type + name: + user_type + type_identifier "String" --- @@ -131,10 +139,12 @@ source_file text: line_str_text "world" name: simple_identifier "greet" parameter - name: - simple_identifier "name" - user_type - type_identifier "String" + name: simple_identifier "name" + type: + type + name: + user_type + type_identifier "String" --- @@ -169,17 +179,22 @@ source_file value_argument value: integer_literal "0" value_argument - value: + - name: - simple_identifier "sum" - user_type - type_identifier "Int" + value: + referenceable_operator + name: simple_identifier "sum" + return_type: + type + name: + user_type + type_identifier "Int" parameter external_name: simple_identifier "_" - name: - simple_identifier "values" - user_type - type_identifier "Int" + name: simple_identifier "values" + type: + type + name: + user_type + type_identifier "Int" --- @@ -297,19 +312,23 @@ source_file statements control_transfer_statement result: simple_identifier "x" - name: - simple_identifier "identity" - user_type - type_identifier "T" + name: simple_identifier "identity" + return_type: + type + name: + user_type + type_identifier "T" type_parameters type_parameter type_identifier "T" parameter external_name: simple_identifier "_" - name: - simple_identifier "x" - user_type - type_identifier "T" + name: simple_identifier "x" + type: + type + name: + user_type + type_identifier "T" --- diff --git a/unified/extractor/tests/corpus/swift/loops.txt b/unified/extractor/tests/corpus/swift/loops.txt index 68c0a86198e..62d0d097bb0 100644 --- a/unified/extractor/tests/corpus/swift/loops.txt +++ b/unified/extractor/tests/corpus/swift/loops.txt @@ -113,10 +113,11 @@ while x > 0 { source_file while_statement condition: - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" statements assignment operator: -= @@ -143,10 +144,11 @@ repeat { source_file repeat_while_statement condition: - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" statements assignment operator: -= @@ -181,18 +183,20 @@ source_file statements if_statement condition: - comparison_expression - lhs: simple_identifier "x" - op: < - rhs: integer_literal "0" + if_condition + comparison_expression + lhs: simple_identifier "x" + op: < + rhs: integer_literal "0" statements control_transfer_statement if_statement condition: - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "100" + if_condition + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "100" statements control_transfer_statement call_expression diff --git a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt index acaff1f6ac8..c4f9118eedc 100644 --- a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt +++ b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt @@ -15,11 +15,13 @@ source_file value_binding_pattern mutability: let type_annotation - name: - optional_type - wrapped: - user_type - type_identifier "Int" + type: + type + name: + optional_type + wrapped: + user_type + type_identifier "Int" --- @@ -51,14 +53,14 @@ source_file navigation_suffix suffix: simple_identifier "bar" target: - navigation_expression - suffix: - navigation_suffix - suffix: simple_identifier "foo" - target: - simple_identifier "obj" - ? - ? + optional_chain_marker + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "foo" + target: + optional_chain_marker + simple_identifier "obj" value_binding_pattern mutability: let @@ -71,12 +73,7 @@ top_level variable_declarator value: member_access_expr - target: - member_access_expr - target: - name_expr - identifier: identifier "obj" - member: identifier "foo" + target: unsupported_node "obj?.foo?" member: identifier "bar" pattern: var_pattern @@ -164,10 +161,12 @@ source_file control_transfer_statement result: line_string_literal - name: - simple_identifier "read" - user_type - type_identifier "String" + name: simple_identifier "read" + return_type: + type + name: + user_type + type_identifier "String" throws "throws" --- diff --git a/unified/extractor/tests/corpus/swift/types.txt b/unified/extractor/tests/corpus/swift/types.txt index c4af07383b8..873749aa6ce 100644 --- a/unified/extractor/tests/corpus/swift/types.txt +++ b/unified/extractor/tests/corpus/swift/types.txt @@ -40,9 +40,11 @@ source_file value_binding_pattern mutability: var type_annotation - name: - user_type - type_identifier "Int" + type: + type + name: + user_type + type_identifier "Int" property_declaration name: pattern @@ -50,9 +52,11 @@ source_file value_binding_pattern mutability: var type_annotation - name: - user_type - type_identifier "Int" + type: + type + name: + user_type + type_identifier "Int" declaration_kind: class name: type_identifier "Point" @@ -85,9 +89,11 @@ source_file value_binding_pattern mutability: var type_annotation - name: - user_type - type_identifier "Int" + type: + type + name: + user_type + type_identifier "Int" init_declaration body: function_body @@ -105,10 +111,12 @@ source_file self_expression name: init parameter - name: - simple_identifier "x" - user_type - type_identifier "Int" + name: simple_identifier "x" + type: + type + name: + user_type + type_identifier "Int" declaration_kind: class name: type_identifier "Point" @@ -206,9 +214,11 @@ source_file value_binding_pattern mutability: let type_annotation - name: - user_type - type_identifier "Int" + type: + type + name: + user_type + type_identifier "Int" property_declaration name: pattern @@ -216,9 +226,11 @@ source_file value_binding_pattern mutability: let type_annotation - name: - user_type - type_identifier "Int" + type: + type + name: + user_type + type_identifier "Int" declaration_kind: struct name: type_identifier "Point" @@ -278,18 +290,20 @@ source_file enum_entry data_contents: enum_type_parameters - name: - user_type - type_identifier "Double" simple_identifier "radius" + type + name: + user_type + type_identifier "Double" name: simple_identifier "circle" enum_entry data_contents: enum_type_parameters - name: - user_type - type_identifier "Double" simple_identifier "side" + type + name: + user_type + type_identifier "Double" name: simple_identifier "square" declaration_kind: enum name: type_identifier "Shape" @@ -349,10 +363,12 @@ source_file op: * rhs: self_expression - name: - simple_identifier "squared" - user_type - type_identifier "Int" + name: simple_identifier "squared" + return_type: + type + name: + user_type + type_identifier "Int" declaration_kind: extension name: user_type @@ -388,9 +404,11 @@ source_file value_binding_pattern mutability: var type_annotation - name: - user_type - type_identifier "Double" + type: + type + name: + user_type + type_identifier "Double" property_declaration name: pattern @@ -398,9 +416,11 @@ source_file value_binding_pattern mutability: var type_annotation - name: - user_type - type_identifier "Double" + type: + type + name: + user_type + type_identifier "Double" property_declaration computed_value: computed_property @@ -417,9 +437,11 @@ source_file value_binding_pattern mutability: var type_annotation - name: - user_type - type_identifier "Double" + type: + type + name: + user_type + type_identifier "Double" declaration_kind: class name: type_identifier "Rect" @@ -478,9 +500,11 @@ source_file value_binding_pattern mutability: var type_annotation - name: - user_type - type_identifier "Int" + type: + type + name: + user_type + type_identifier "Int" declaration_kind: class name: type_identifier "Box" diff --git a/unified/extractor/tests/corpus/swift/variables.txt b/unified/extractor/tests/corpus/swift/variables.txt index 96fbbd3b740..3fe7686a8c3 100644 --- a/unified/extractor/tests/corpus/swift/variables.txt +++ b/unified/extractor/tests/corpus/swift/variables.txt @@ -73,9 +73,11 @@ source_file value_binding_pattern mutability: let type_annotation - name: - user_type - type_identifier "Int" + type: + type + name: + user_type + type_identifier "Int" --- @@ -105,9 +107,11 @@ source_file value_binding_pattern mutability: var type_annotation - name: - user_type - type_identifier "Int" + type: + type + name: + user_type + type_identifier "Int" --- From b031e5b1f89ec165035d7a3cc2e31650462f67c9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 May 2026 10:48:43 +0200 Subject: [PATCH 066/226] Unified: regenerate QL and make tests not crash The output is not so interesting as the mapping removes most nodes from the current test file. I added a name_expr.swift test so at least one NameExpr makes it through. --- unified/ql/lib/codeql/unified/Ast.qll | 2957 ++--------------- unified/ql/lib/unified.dbscheme | 2161 +----------- .../library-tests/BasicTest/name_expr.swift | 1 + .../library-tests/BasicTest/test.expected | 31 +- .../ql/test/library-tests/BasicTest/test.ql | 2 +- 5 files changed, 472 insertions(+), 4680 deletions(-) create mode 100644 unified/ql/test/library-tests/BasicTest/name_expr.swift diff --git a/unified/ql/lib/codeql/unified/Ast.qll b/unified/ql/lib/codeql/unified/Ast.qll index 17adff56236..d9060c26f0f 100644 --- a/unified/ql/lib/codeql/unified/Ast.qll +++ b/unified/ql/lib/codeql/unified/Ast.qll @@ -81,118 +81,23 @@ module Unified { ) } -<<<<<<< HEAD - /** A class representing `additive_expression` nodes. */ - class AdditiveExpression extends @swift_additive_expression, AstNode { + /** A class representing `apply_pattern` nodes. */ + class ApplyPattern extends @unified_apply_pattern, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AdditiveExpression" } + final override string getAPrimaryQlClass() { result = "ApplyPattern" } - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_additive_expression_def(this, result, _, _) } + /** Gets the node corresponding to the field `argument`. */ + final Pattern getArgument(int i) { unified_apply_pattern_argument(this, i, result) } - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_additive_expression_def(this, _, value, _) | - result = "+" and value = 0 - or - result = "-" and value = 1 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_additive_expression_def(this, _, _, result) } + /** Gets the node corresponding to the field `constructor`. */ + final Expr getConstructor() { unified_apply_pattern_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_additive_expression_def(this, result, _, _) or - swift_additive_expression_def(this, _, _, result) + unified_apply_pattern_argument(this, _, result) or unified_apply_pattern_def(this, result) } } - /** A class representing `array_literal` nodes. */ - class ArrayLiteral extends @swift_array_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ArrayLiteral" } - - /** Gets the node corresponding to the field `element`. */ - final Expression getElement(int i) { swift_array_literal_element(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_array_literal_element(this, _, result) } - } - - /** A class representing `array_type` nodes. */ - class ArrayType extends @swift_array_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ArrayType" } - - /** Gets the node corresponding to the field `element`. */ - final Type getElement() { swift_array_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_array_type_def(this, result) } - } - - /** A class representing `as_expression` nodes. */ - class AsExpression extends @swift_as_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AsExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_as_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_as_expression_def(this, _, result, _) } - - /** Gets the child of this node. */ - final AsOperator getChild() { swift_as_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_as_expression_def(this, result, _, _) or - swift_as_expression_def(this, _, result, _) or - swift_as_expression_def(this, _, _, result) - } - } - - /** A class representing `as_operator` tokens. */ - class AsOperator extends @swift_token_as_operator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AsOperator" } - } - - /** A class representing `assignment` nodes. */ - class Assignment extends @swift_assignment, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Assignment" } - - /** Gets the node corresponding to the field `operator`. */ - final string getOperator() { - exists(int value | swift_assignment_def(this, value, _, _) | - result = "%=" and value = 0 - or - result = "*=" and value = 1 - or - result = "+=" and value = 2 - or - result = "-=" and value = 3 - or - result = "/=" and value = 4 - or - result = "=" and value = 5 - ) - } - - /** Gets the node corresponding to the field `result`. */ - final Expression getResult() { swift_assignment_def(this, _, result, _) } - - /** Gets the node corresponding to the field `target`. */ - final DirectlyAssignableExpression getTarget() { swift_assignment_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_assignment_def(this, _, result, _) or swift_assignment_def(this, _, _, result) -======= /** A class representing `binary_expr` nodes. */ class BinaryExpr extends @unified_binary_expr, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -202,7 +107,7 @@ module Unified { final Expr getLeft() { unified_binary_expr_def(this, result, _, _) } /** Gets the node corresponding to the field `operator`. */ - final BinaryOperator getOperator() { unified_binary_expr_def(this, _, result, _) } + final Operator getOperator() { unified_binary_expr_def(this, _, result, _) } /** Gets the node corresponding to the field `right`. */ final Expr getRight() { unified_binary_expr_def(this, _, _, result) } @@ -212,2626 +117,330 @@ module Unified { unified_binary_expr_def(this, result, _, _) or unified_binary_expr_def(this, _, result, _) or unified_binary_expr_def(this, _, _, result) ->>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) } } - /** A class representing `binary_operator` tokens. */ - class BinaryOperator extends @unified_token_binary_operator, Token { + /** A class representing `block_stmt` nodes. */ + class BlockStmt extends @unified_block_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ -<<<<<<< HEAD - final override string getAPrimaryQlClass() { result = "AssociatedtypeDeclaration" } + final override string getAPrimaryQlClass() { result = "BlockStmt" } - /** Gets the node corresponding to the field `default_value`. */ - final Type getDefaultValue() { swift_associatedtype_declaration_default_value(this, result) } + /** Gets the node corresponding to the field `body`. */ + final Stmt getBody(int i) { unified_block_stmt_body(this, i, result) } - /** Gets the node corresponding to the field `must_inherit`. */ - final Type getMustInherit() { swift_associatedtype_declaration_must_inherit(this, result) } + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { unified_block_stmt_body(this, _, result) } + } - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_associatedtype_declaration_def(this, result) } + /** A class representing `call_expr` nodes. */ + class CallExpr extends @unified_call_expr, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "CallExpr" } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_associatedtype_declaration_child(this, i, result) } + /** Gets the node corresponding to the field `argument`. */ + final Expr getArgument(int i) { unified_call_expr_argument(this, i, result) } + + /** Gets the node corresponding to the field `function`. */ + final Expr getFunction() { unified_call_expr_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_associatedtype_declaration_default_value(this, result) or - swift_associatedtype_declaration_must_inherit(this, result) or - swift_associatedtype_declaration_def(this, result) or - swift_associatedtype_declaration_child(this, _, result) + unified_call_expr_argument(this, _, result) or unified_call_expr_def(this, result) } -======= - final override string getAPrimaryQlClass() { result = "BinaryOperator" } ->>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) + } + + class Condition extends @unified_condition, AstNode { } + + /** A class representing `empty_stmt` tokens. */ + class EmptyStmt extends @unified_token_empty_stmt, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "EmptyStmt" } } class Expr extends @unified_expr, AstNode { } - /** A class representing `name_expr` tokens. */ - class NameExpr extends @unified_token_name_expr, Token { + /** A class representing `expr_condition` nodes. */ + class ExprCondition extends @unified_expr_condition, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ExprCondition" } + + /** Gets the node corresponding to the field `expr`. */ + final Expr getExpr() { unified_expr_condition_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { unified_expr_condition_def(this, result) } + } + + /** A class representing `expr_stmt` nodes. */ + class ExprStmt extends @unified_expr_stmt, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "ExprStmt" } + + /** Gets the node corresponding to the field `expr`. */ + final Expr getExpr() { unified_expr_stmt_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { unified_expr_stmt_def(this, result) } + } + + /** A class representing `guard_if_stmt` nodes. */ + class GuardIfStmt extends @unified_guard_if_stmt, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "GuardIfStmt" } + + /** Gets the node corresponding to the field `condition`. */ + final Condition getCondition() { unified_guard_if_stmt_def(this, result, _) } + + /** Gets the node corresponding to the field `else`. */ + final Stmt getElse() { unified_guard_if_stmt_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_guard_if_stmt_def(this, result, _) or unified_guard_if_stmt_def(this, _, result) + } + } + + /** A class representing `identifier` tokens. */ + class Identifier extends @unified_token_identifier, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Identifier" } + } + + /** A class representing `if_stmt` nodes. */ + class IfStmt extends @unified_if_stmt, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "IfStmt" } + + /** Gets the node corresponding to the field `condition`. */ + final Condition getCondition() { unified_if_stmt_def(this, result) } + + /** Gets the node corresponding to the field `else`. */ + final Stmt getElse() { unified_if_stmt_else(this, result) } + + /** Gets the node corresponding to the field `then`. */ + final Stmt getThen() { unified_if_stmt_then(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_if_stmt_def(this, result) or + unified_if_stmt_else(this, result) or + unified_if_stmt_then(this, result) + } + } + + /** A class representing `ignore_pattern` tokens. */ + class IgnorePattern extends @unified_token_ignore_pattern, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "IgnorePattern" } + } + + /** A class representing `int_literal` tokens. */ + class IntLiteral extends @unified_token_int_literal, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "IntLiteral" } + } + + /** A class representing `lambda_expr` nodes. */ + class LambdaExpr extends @unified_lambda_expr, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "LambdaExpr" } + + /** Gets the node corresponding to the field `body`. */ + final AstNode getBody() { unified_lambda_expr_def(this, result) } + + /** Gets the node corresponding to the field `parameter`. */ + final Parameter getParameter(int i) { unified_lambda_expr_parameter(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_lambda_expr_def(this, result) or unified_lambda_expr_parameter(this, _, result) + } + } + + /** A class representing `let_pattern_condition` nodes. */ + class LetPatternCondition extends @unified_let_pattern_condition, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "LetPatternCondition" } + + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { unified_let_pattern_condition_def(this, result, _) } + + /** Gets the node corresponding to the field `value`. */ + final Expr getValue() { unified_let_pattern_condition_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_let_pattern_condition_def(this, result, _) or + unified_let_pattern_condition_def(this, _, result) + } + } + + /** A class representing `member_access_expr` nodes. */ + class MemberAccessExpr extends @unified_member_access_expr, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "MemberAccessExpr" } + + /** Gets the node corresponding to the field `member`. */ + final Identifier getMember() { unified_member_access_expr_def(this, result, _) } + + /** Gets the node corresponding to the field `target`. */ + final Expr getTarget() { unified_member_access_expr_def(this, _, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_member_access_expr_def(this, result, _) or + unified_member_access_expr_def(this, _, result) + } + } + + /** A class representing `name_expr` nodes. */ + class NameExpr extends @unified_name_expr, AstNode { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "NameExpr" } + + /** Gets the node corresponding to the field `identifier`. */ + final Identifier getIdentifier() { unified_name_expr_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { unified_name_expr_def(this, result) } + } + + /** A class representing `operator` tokens. */ + class Operator extends @unified_token_operator, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Operator" } + } + + /** A class representing `parameter` nodes. */ + class Parameter extends @unified_parameter, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Parameter" } + + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { unified_parameter_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { unified_parameter_def(this, result) } + } + + class Pattern extends @unified_pattern, AstNode { } + + /** A class representing `sequence_condition` nodes. */ + class SequenceCondition extends @unified_sequence_condition, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "SequenceCondition" } + + /** Gets the node corresponding to the field `condition`. */ + final Condition getCondition() { unified_sequence_condition_def(this, result) } + + /** Gets the node corresponding to the field `stmt`. */ + final Stmt getStmt(int i) { unified_sequence_condition_stmt(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_sequence_condition_def(this, result) or + unified_sequence_condition_stmt(this, _, result) + } + } + + class Stmt extends @unified_stmt, AstNode { } + + /** A class representing `string_literal` tokens. */ + class StringLiteral extends @unified_token_string_literal, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "StringLiteral" } } /** A class representing `top_level` nodes. */ class TopLevel extends @unified_top_level, AstNode { /** Gets the name of the primary QL class for this element. */ -<<<<<<< HEAD - final override string getAPrimaryQlClass() { result = "AvailabilityCondition" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_availability_condition_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_availability_condition_child(this, _, result) - } - } - - /** A class representing `await_expression` nodes. */ - class AwaitExpression extends @swift_await_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AwaitExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_await_expression_expr(this, result) } - - /** Gets the child of this node. */ - final Expression getChild() { swift_await_expression_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_await_expression_expr(this, result) or swift_await_expression_child(this, result) - } - } - - /** A class representing `bang` tokens. */ - class Bang extends @swift_token_bang, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Bang" } - } - - /** A class representing `bin_literal` tokens. */ - class BinLiteral extends @swift_token_bin_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BinLiteral" } - } - - /** A class representing `bitwise_operation` nodes. */ - class BitwiseOperation extends @swift_bitwise_operation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BitwiseOperation" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_bitwise_operation_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_bitwise_operation_def(this, _, value, _) | - result = "&" and value = 0 - or - result = "<<" and value = 1 - or - result = ">>" and value = 2 - or - result = "^" and value = 3 - or - result = "|" and value = 4 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_bitwise_operation_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_bitwise_operation_def(this, result, _, _) or - swift_bitwise_operation_def(this, _, _, result) - } - } - - /** A class representing `boolean_literal` tokens. */ - class BooleanLiteral extends @swift_token_boolean_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BooleanLiteral" } - } - - /** A class representing `call_expression` nodes. */ - class CallExpression extends @swift_call_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CallExpression" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_call_expression_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_call_expression_child(this, _, result) } - } - - /** A class representing `call_suffix` nodes. */ - class CallSuffix extends @swift_call_suffix, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CallSuffix" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_call_suffix_name(this, i, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_call_suffix_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_call_suffix_name(this, _, result) or swift_call_suffix_child(this, _, result) - } - } - - /** A class representing `capture_list` nodes. */ - class CaptureList extends @swift_capture_list, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CaptureList" } - - /** Gets the `i`th child of this node. */ - final CaptureListItem getChild(int i) { swift_capture_list_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_capture_list_child(this, _, result) } - } - - /** A class representing `capture_list_item` nodes. */ - class CaptureListItem extends @swift_capture_list_item, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CaptureListItem" } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_capture_list_item_def(this, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_capture_list_item_value(this, result) } - - /** Gets the child of this node. */ - final OwnershipModifier getChild() { swift_capture_list_item_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_capture_list_item_def(this, result) or - swift_capture_list_item_value(this, result) or - swift_capture_list_item_child(this, result) - } - } - - /** A class representing `catch_block` nodes. */ - class CatchBlock extends @swift_catch_block, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CatchBlock" } - - /** Gets the node corresponding to the field `error`. */ - final Pattern getError() { swift_catch_block_error(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_catch_block_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_catch_block_error(this, result) or swift_catch_block_child(this, _, result) - } - } - - /** A class representing `catch_keyword` tokens. */ - class CatchKeyword extends @swift_token_catch_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CatchKeyword" } - } - - /** A class representing `check_expression` nodes. */ - class CheckExpression extends @swift_check_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CheckExpression" } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_check_expression_def(this, value, _, _) | - (result = "is" and value = 0) - ) - } - - /** Gets the node corresponding to the field `target`. */ - final Expression getTarget() { swift_check_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_check_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_check_expression_def(this, _, result, _) or - swift_check_expression_def(this, _, _, result) - } - } - - /** A class representing `class_body` nodes. */ - class ClassBody extends @swift_class_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ClassBody" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_class_body_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_class_body_child(this, _, result) } - } - - /** A class representing `class_declaration` nodes. */ - class ClassDeclaration extends @swift_class_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ClassDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final AstNode getBody() { swift_class_declaration_def(this, result, _, _) } - - /** Gets the node corresponding to the field `declaration_kind`. */ - final string getDeclarationKind() { - exists(int value | swift_class_declaration_def(this, _, value, _) | - result = "actor" and value = 0 - or - result = "class" and value = 1 - or - result = "enum" and value = 2 - or - result = "extension" and value = 3 - or - result = "struct" and value = 4 - ) - } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_class_declaration_def(this, _, _, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_class_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_class_declaration_def(this, result, _, _) or - swift_class_declaration_def(this, _, _, result) or - swift_class_declaration_child(this, _, result) - } - } - - /** A class representing `comment` tokens. */ - class Comment extends @swift_token_comment, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Comment" } - } - - /** A class representing `comparison_expression` nodes. */ - class ComparisonExpression extends @swift_comparison_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComparisonExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_comparison_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_comparison_expression_def(this, _, value, _) | - result = "<" and value = 0 - or - result = "<=" and value = 1 - or - result = ">" and value = 2 - or - result = ">=" and value = 3 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_comparison_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_comparison_expression_def(this, result, _, _) or - swift_comparison_expression_def(this, _, _, result) - } - } - - /** A class representing `computed_getter` nodes. */ - class ComputedGetter extends @swift_computed_getter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedGetter" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_getter_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_getter_child(this, _, result) } - } - - /** A class representing `computed_modify` nodes. */ - class ComputedModify extends @swift_computed_modify, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedModify" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_modify_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_modify_child(this, _, result) } - } - - /** A class representing `computed_property` nodes. */ - class ComputedProperty extends @swift_computed_property, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedProperty" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_property_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_property_child(this, _, result) } - } - - /** A class representing `computed_setter` nodes. */ - class ComputedSetter extends @swift_computed_setter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedSetter" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_computed_setter_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_computed_setter_child(this, _, result) } - } - - /** A class representing `conjunction_expression` nodes. */ - class ConjunctionExpression extends @swift_conjunction_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ConjunctionExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_conjunction_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_conjunction_expression_def(this, _, value, _) | - (result = "&&" and value = 0) - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_conjunction_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_conjunction_expression_def(this, result, _, _) or - swift_conjunction_expression_def(this, _, _, result) - } - } - - /** A class representing `constructor_expression` nodes. */ - class ConstructorExpression extends @swift_constructor_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ConstructorExpression" } - - /** Gets the node corresponding to the field `constructed_type`. */ - final AstNode getConstructedType() { swift_constructor_expression_def(this, result, _) } - - /** Gets the child of this node. */ - final ConstructorSuffix getChild() { swift_constructor_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_constructor_expression_def(this, result, _) or - swift_constructor_expression_def(this, _, result) - } - } - - /** A class representing `constructor_suffix` nodes. */ - class ConstructorSuffix extends @swift_constructor_suffix, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ConstructorSuffix" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_constructor_suffix_name(this, i, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_constructor_suffix_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_constructor_suffix_name(this, _, result) or - swift_constructor_suffix_child(this, _, result) - } - } - - /** A class representing `control_transfer_statement` nodes. */ - class ControlTransferStatement extends @swift_control_transfer_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ControlTransferStatement" } - - /** Gets the node corresponding to the field `result`. */ - final Expression getResult() { swift_control_transfer_statement_result(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_control_transfer_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_control_transfer_statement_result(this, result) or - swift_control_transfer_statement_child(this, _, result) - } - } - - /** A class representing `custom_operator` tokens. */ - class CustomOperator extends @swift_token_custom_operator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CustomOperator" } - } - - /** A class representing `default_keyword` tokens. */ - class DefaultKeyword extends @swift_token_default_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DefaultKeyword" } - } - - /** A class representing `deinit_declaration` nodes. */ - class DeinitDeclaration extends @swift_deinit_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DeinitDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_deinit_declaration_def(this, result) } - - /** Gets the child of this node. */ - final Modifiers getChild() { swift_deinit_declaration_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_deinit_declaration_def(this, result) or swift_deinit_declaration_child(this, result) - } - } - - /** A class representing `deprecated_operator_declaration_body` nodes. */ - class DeprecatedOperatorDeclarationBody extends @swift_deprecated_operator_declaration_body, - AstNode - { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DeprecatedOperatorDeclarationBody" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { - swift_deprecated_operator_declaration_body_child(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_deprecated_operator_declaration_body_child(this, _, result) - } - } - - /** A class representing `diagnostic` tokens. */ - class Diagnostic extends @swift_token_diagnostic, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Diagnostic" } - } - - /** A class representing `dictionary_literal` nodes. */ - class DictionaryLiteral extends @swift_dictionary_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DictionaryLiteral" } - - /** Gets the node corresponding to the field `key`. */ - final Expression getKey(int i) { swift_dictionary_literal_key(this, i, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_dictionary_literal_value(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_dictionary_literal_key(this, _, result) or - swift_dictionary_literal_value(this, _, result) - } - } - - /** A class representing `dictionary_type` nodes. */ - class DictionaryType extends @swift_dictionary_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DictionaryType" } - - /** Gets the node corresponding to the field `key`. */ - final Type getKey() { swift_dictionary_type_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Type getValue() { swift_dictionary_type_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_dictionary_type_def(this, result, _) or swift_dictionary_type_def(this, _, result) - } - } - - /** A class representing `didset_clause` nodes. */ - class DidsetClause extends @swift_didset_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DidsetClause" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_didset_clause_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_didset_clause_child(this, _, result) } - } - - /** A class representing `directive` nodes. */ - class Directive extends @swift_directive, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Directive" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_directive_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_directive_child(this, _, result) } - } - - /** A class representing `directly_assignable_expression` nodes. */ - class DirectlyAssignableExpression extends @swift_directly_assignable_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DirectlyAssignableExpression" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_directly_assignable_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_directly_assignable_expression_def(this, result) - } - } - - /** A class representing `disjunction_expression` nodes. */ - class DisjunctionExpression extends @swift_disjunction_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DisjunctionExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_disjunction_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_disjunction_expression_def(this, _, value, _) | - (result = "||" and value = 0) - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_disjunction_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_disjunction_expression_def(this, result, _, _) or - swift_disjunction_expression_def(this, _, _, result) - } - } - - /** A class representing `do_statement` nodes. */ - class DoStatement extends @swift_do_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DoStatement" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_do_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_do_statement_child(this, _, result) } - } - - /** A class representing `else` tokens. */ - class Else extends @swift_token_else, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Else" } - } - - /** A class representing `enum_class_body` nodes. */ - class EnumClassBody extends @swift_enum_class_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumClassBody" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_enum_class_body_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_enum_class_body_child(this, _, result) } - } - - /** A class representing `enum_entry` nodes. */ - class EnumEntry extends @swift_enum_entry, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumEntry" } - - /** Gets the node corresponding to the field `data_contents`. */ - final EnumTypeParameters getDataContents(int i) { - swift_enum_entry_data_contents(this, i, result) - } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_enum_entry_name(this, i, result) } - - /** Gets the node corresponding to the field `raw_value`. */ - final Expression getRawValue(int i) { swift_enum_entry_raw_value(this, i, result) } - - /** Gets the child of this node. */ - final Modifiers getChild() { swift_enum_entry_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_enum_entry_data_contents(this, _, result) or - swift_enum_entry_name(this, _, result) or - swift_enum_entry_raw_value(this, _, result) or - swift_enum_entry_child(this, result) - } - } - - /** A class representing `enum_type_parameters` nodes. */ - class EnumTypeParameters extends @swift_enum_type_parameters, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumTypeParameters" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_enum_type_parameters_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_enum_type_parameters_child(this, _, result) } - } - - /** A class representing `equality_constraint` nodes. */ - class EqualityConstraint extends @swift_equality_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EqualityConstraint" } - - /** Gets the node corresponding to the field `constrained_type`. */ - final AstNode getConstrainedType() { swift_equality_constraint_def(this, result, _) } - - /** Gets the node corresponding to the field `must_equal`. */ - final Type getMustEqual() { swift_equality_constraint_def(this, _, result) } - - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_equality_constraint_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_equality_constraint_def(this, result, _) or - swift_equality_constraint_def(this, _, result) or - swift_equality_constraint_child(this, _, result) - } - } - - /** A class representing `equality_expression` nodes. */ - class EqualityExpression extends @swift_equality_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EqualityExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_equality_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_equality_expression_def(this, _, value, _) | - result = "!=" and value = 0 - or - result = "!==" and value = 1 - or - result = "==" and value = 2 - or - result = "===" and value = 3 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_equality_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_equality_expression_def(this, result, _, _) or - swift_equality_expression_def(this, _, _, result) - } - } - - /** A class representing `existential_type` nodes. */ - class ExistentialType extends @swift_existential_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ExistentialType" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_existential_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_existential_type_def(this, result) } - } - - class Expression extends @swift_expression, AstNode { } - - /** A class representing `external_macro_definition` nodes. */ - class ExternalMacroDefinition extends @swift_external_macro_definition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ExternalMacroDefinition" } - - /** Gets the child of this node. */ - final ValueArguments getChild() { swift_external_macro_definition_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_external_macro_definition_def(this, result) } - } - - /** A class representing `for_statement` nodes. */ - class ForStatement extends @swift_for_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ForStatement" } - - /** Gets the node corresponding to the field `collection`. */ - final Expression getCollection() { swift_for_statement_def(this, result, _) } - - /** Gets the node corresponding to the field `item`. */ - final Pattern getItem() { swift_for_statement_def(this, _, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_for_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_for_statement_def(this, result, _) or - swift_for_statement_def(this, _, result) or - swift_for_statement_child(this, _, result) - } - } - - /** A class representing `fully_open_range` tokens. */ - class FullyOpenRange extends @swift_token_fully_open_range, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FullyOpenRange" } - } - - /** A class representing `function_body` nodes. */ - class FunctionBody extends @swift_function_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionBody" } - - /** Gets the child of this node. */ - final Statements getChild() { swift_function_body_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_function_body_child(this, result) } - } - - /** A class representing `function_declaration` nodes. */ - class FunctionDeclaration extends @swift_function_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_function_declaration_def(this, result, _) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_function_declaration_default_value(this, i, result) - } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_function_declaration_def(this, _, result) } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_function_declaration_return_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_function_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_function_declaration_def(this, result, _) or - swift_function_declaration_default_value(this, _, result) or - swift_function_declaration_def(this, _, result) or - swift_function_declaration_return_type(this, result) or - swift_function_declaration_child(this, _, result) - } - } - - /** A class representing `function_modifier` tokens. */ - class FunctionModifier extends @swift_token_function_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionModifier" } - } - - /** A class representing `function_type` nodes. */ - class FunctionType extends @swift_function_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionType" } - - /** Gets the node corresponding to the field `params`. */ - final UnannotatedType getParams() { swift_function_type_def(this, result, _) } - - /** Gets the node corresponding to the field `return_type`. */ - final Type getReturnType() { swift_function_type_def(this, _, result) } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_function_type_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_function_type_def(this, result, _) or - swift_function_type_def(this, _, result) or - swift_function_type_child(this, result) - } - } - - /** A class representing `getter_specifier` nodes. */ - class GetterSpecifier extends @swift_getter_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "GetterSpecifier" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_getter_specifier_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_getter_specifier_child(this, _, result) } - } - - class GlobalDeclaration extends @swift_global_declaration, AstNode { } - - /** A class representing `guard_statement` nodes. */ - class GuardStatement extends @swift_guard_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "GuardStatement" } - - /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { swift_guard_statement_condition(this, i, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_guard_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_guard_statement_condition(this, _, result) or - swift_guard_statement_child(this, _, result) - } - } - - /** A class representing `hex_literal` tokens. */ - class HexLiteral extends @swift_token_hex_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "HexLiteral" } - } - - /** A class representing `identifier` nodes. */ - class Identifier extends @swift_identifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Identifier" } - - /** Gets the `i`th child of this node. */ - final SimpleIdentifier getChild(int i) { swift_identifier_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_identifier_child(this, _, result) } - } - - /** A class representing `if_condition` nodes. */ - class IfCondition extends @swift_if_condition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IfCondition" } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_if_condition_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_if_condition_def(this, result) } - } - - /** A class representing `if_let_binding` nodes. */ - class IfLetBinding extends @swift_if_let_binding, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IfLetBinding" } - - /** Gets the node corresponding to the field `bound_identifier`. */ - final SimpleIdentifier getBoundIdentifier() { - swift_if_let_binding_bound_identifier(this, result) - } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_if_let_binding_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_if_let_binding_bound_identifier(this, result) or - swift_if_let_binding_child(this, _, result) - } - } - - /** A class representing `if_statement` nodes. */ - class IfStatement extends @swift_if_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IfStatement" } - - /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { swift_if_statement_condition(this, i, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_if_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_if_statement_condition(this, _, result) or swift_if_statement_child(this, _, result) - } - } - - /** A class representing `implicitly_unwrapped_type` nodes. */ - class ImplicitlyUnwrappedType extends @swift_implicitly_unwrapped_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ImplicitlyUnwrappedType" } - - /** Gets the child of this node. */ - final Type getChild() { swift_implicitly_unwrapped_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_implicitly_unwrapped_type_def(this, result) } - } - - /** A class representing `import_declaration` nodes. */ - class ImportDeclaration extends @swift_import_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ImportDeclaration" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_import_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_import_declaration_child(this, _, result) } - } - - /** A class representing `infix_expression` nodes. */ - class InfixExpression extends @swift_infix_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InfixExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_infix_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final CustomOperator getOp() { swift_infix_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_infix_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_infix_expression_def(this, result, _, _) or - swift_infix_expression_def(this, _, result, _) or - swift_infix_expression_def(this, _, _, result) - } - } - - /** A class representing `inheritance_constraint` nodes. */ - class InheritanceConstraint extends @swift_inheritance_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InheritanceConstraint" } - - /** Gets the node corresponding to the field `constrained_type`. */ - final AstNode getConstrainedType() { swift_inheritance_constraint_def(this, result, _) } - - /** Gets the node corresponding to the field `inherits_from`. */ - final AstNode getInheritsFrom() { swift_inheritance_constraint_def(this, _, result) } - - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_inheritance_constraint_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_inheritance_constraint_def(this, result, _) or - swift_inheritance_constraint_def(this, _, result) or - swift_inheritance_constraint_child(this, _, result) - } - } - - /** A class representing `inheritance_modifier` tokens. */ - class InheritanceModifier extends @swift_token_inheritance_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InheritanceModifier" } - } - - /** A class representing `inheritance_specifier` nodes. */ - class InheritanceSpecifier extends @swift_inheritance_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InheritanceSpecifier" } - - /** Gets the node corresponding to the field `inherits_from`. */ - final AstNode getInheritsFrom() { swift_inheritance_specifier_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_inheritance_specifier_def(this, result) } - } - - /** A class representing `init_declaration` nodes. */ - class InitDeclaration extends @swift_init_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InitDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_init_declaration_body(this, result) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_init_declaration_default_value(this, i, result) - } - - /** Gets the node corresponding to the field `name`. */ - final string getName() { - exists(int value | swift_init_declaration_def(this, value) | (result = "init" and value = 0)) - } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_init_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_init_declaration_body(this, result) or - swift_init_declaration_default_value(this, _, result) or - swift_init_declaration_child(this, _, result) - } - } - - /** A class representing `integer_literal` tokens. */ - class IntegerLiteral extends @swift_token_integer_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IntegerLiteral" } - } - - /** A class representing `interpolated_expression` nodes. */ - class InterpolatedExpression extends @swift_interpolated_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InterpolatedExpression" } - - /** Gets the node corresponding to the field `name`. */ - final ValueArgumentLabel getName() { swift_interpolated_expression_name(this, result) } - - /** Gets the node corresponding to the field `reference_specifier`. */ - final ValueArgumentLabel getReferenceSpecifier(int i) { - swift_interpolated_expression_reference_specifier(this, i, result) - } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_interpolated_expression_value(this, result) } - - /** Gets the child of this node. */ - final TypeModifiers getChild() { swift_interpolated_expression_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_interpolated_expression_name(this, result) or - swift_interpolated_expression_reference_specifier(this, _, result) or - swift_interpolated_expression_value(this, result) or - swift_interpolated_expression_child(this, result) - } - } - - /** A class representing `key_path_expression` nodes. */ - class KeyPathExpression extends @swift_key_path_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "KeyPathExpression" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_key_path_expression_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_key_path_expression_child(this, _, result) } - } - - /** A class representing `key_path_string_expression` nodes. */ - class KeyPathStringExpression extends @swift_key_path_string_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "KeyPathStringExpression" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_key_path_string_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_key_path_string_expression_def(this, result) } - } - - /** A class representing `lambda_function_type` nodes. */ - class LambdaFunctionType extends @swift_lambda_function_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaFunctionType" } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_lambda_function_type_return_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_lambda_function_type_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_function_type_return_type(this, result) or - swift_lambda_function_type_child(this, _, result) - } - } - - /** A class representing `lambda_function_type_parameters` nodes. */ - class LambdaFunctionTypeParameters extends @swift_lambda_function_type_parameters, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaFunctionTypeParameters" } - - /** Gets the `i`th child of this node. */ - final LambdaParameter getChild(int i) { - swift_lambda_function_type_parameters_child(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_function_type_parameters_child(this, _, result) - } - } - - /** A class representing `lambda_literal` nodes. */ - class LambdaLiteral extends @swift_lambda_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaLiteral" } - - /** Gets the node corresponding to the field `captures`. */ - final CaptureList getCaptures() { swift_lambda_literal_captures(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final LambdaFunctionType getType() { swift_lambda_literal_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_lambda_literal_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_literal_captures(this, result) or - swift_lambda_literal_type(this, result) or - swift_lambda_literal_child(this, _, result) - } - } - - /** A class representing `lambda_parameter` nodes. */ - class LambdaParameter extends @swift_lambda_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaParameter" } - - /** Gets the node corresponding to the field `external_name`. */ - final SimpleIdentifier getExternalName() { swift_lambda_parameter_external_name(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_lambda_parameter_name(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_lambda_parameter_type(this, result) } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_lambda_parameter_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_parameter_external_name(this, result) or - swift_lambda_parameter_name(this, result) or - swift_lambda_parameter_type(this, result) or - swift_lambda_parameter_child(this, result) - } - } - - /** A class representing `line_str_text` tokens. */ - class LineStrText extends @swift_token_line_str_text, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LineStrText" } - } - - /** A class representing `line_string_literal` nodes. */ - class LineStringLiteral extends @swift_line_string_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LineStringLiteral" } - - /** Gets the node corresponding to the field `interpolation`. */ - final InterpolatedExpression getInterpolation(int i) { - swift_line_string_literal_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `text`. */ - final AstNode getText(int i) { swift_line_string_literal_text(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_line_string_literal_interpolation(this, _, result) or - swift_line_string_literal_text(this, _, result) - } - } - - class LocalDeclaration extends @swift_local_declaration, AstNode { } - - /** A class representing `macro_declaration` nodes. */ - class MacroDeclaration extends @swift_macro_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MacroDeclaration" } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_macro_declaration_default_value(this, i, result) - } - - /** Gets the node corresponding to the field `definition`. */ - final MacroDefinition getDefinition() { swift_macro_declaration_definition(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_macro_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_macro_declaration_default_value(this, _, result) or - swift_macro_declaration_definition(this, result) or - swift_macro_declaration_child(this, _, result) - } - } - - /** A class representing `macro_definition` nodes. */ - class MacroDefinition extends @swift_macro_definition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MacroDefinition" } - - /** Gets the node corresponding to the field `body`. */ - final AstNode getBody() { swift_macro_definition_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_macro_definition_def(this, result) } - } - - /** A class representing `macro_invocation` nodes. */ - class MacroInvocation extends @swift_macro_invocation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MacroInvocation" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_macro_invocation_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_macro_invocation_child(this, _, result) } - } - - /** A class representing `member_modifier` tokens. */ - class MemberModifier extends @swift_token_member_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MemberModifier" } - } - - /** A class representing `metatype` nodes. */ - class Metatype extends @swift_metatype, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Metatype" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_metatype_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_metatype_def(this, result) } - } - - /** A class representing `modifiers` nodes. */ - class Modifiers extends @swift_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Modifiers" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_modifiers_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_modifiers_child(this, _, result) } - } - - /** A class representing `modify_specifier` nodes. */ - class ModifySpecifier extends @swift_modify_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ModifySpecifier" } - - /** Gets the child of this node. */ - final MutationModifier getChild() { swift_modify_specifier_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_modify_specifier_child(this, result) } - } - - /** A class representing `multi_line_str_text` tokens. */ - class MultiLineStrText extends @swift_token_multi_line_str_text, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultiLineStrText" } - } - - /** A class representing `multi_line_string_literal` nodes. */ - class MultiLineStringLiteral extends @swift_multi_line_string_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultiLineStringLiteral" } - - /** Gets the node corresponding to the field `interpolation`. */ - final InterpolatedExpression getInterpolation(int i) { - swift_multi_line_string_literal_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `text`. */ - final AstNode getText(int i) { swift_multi_line_string_literal_text(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_multi_line_string_literal_interpolation(this, _, result) or - swift_multi_line_string_literal_text(this, _, result) - } - } - - /** A class representing `multiline_comment` tokens. */ - class MultilineComment extends @swift_token_multiline_comment, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultilineComment" } - } - - /** A class representing `multiplicative_expression` nodes. */ - class MultiplicativeExpression extends @swift_multiplicative_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultiplicativeExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_multiplicative_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_multiplicative_expression_def(this, _, value, _) | - result = "%" and value = 0 - or - result = "*" and value = 1 - or - result = "/" and value = 2 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_multiplicative_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_multiplicative_expression_def(this, result, _, _) or - swift_multiplicative_expression_def(this, _, _, result) - } - } - - /** A class representing `mutation_modifier` tokens. */ - class MutationModifier extends @swift_token_mutation_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MutationModifier" } - } - - /** A class representing `navigation_expression` nodes. */ - class NavigationExpression extends @swift_navigation_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NavigationExpression" } - - /** Gets the node corresponding to the field `suffix`. */ - final NavigationSuffix getSuffix() { swift_navigation_expression_def(this, result) } - - /** Gets the node corresponding to the field `target`. */ - final AstNode getTarget(int i) { swift_navigation_expression_target(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_navigation_expression_def(this, result) or - swift_navigation_expression_target(this, _, result) - } - } - - /** A class representing `navigation_suffix` nodes. */ - class NavigationSuffix extends @swift_navigation_suffix, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NavigationSuffix" } - - /** Gets the node corresponding to the field `suffix`. */ - final AstNode getSuffix() { swift_navigation_suffix_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_navigation_suffix_def(this, result) } - } - - /** A class representing `nested_type_identifier` nodes. */ - class NestedTypeIdentifier extends @swift_nested_type_identifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NestedTypeIdentifier" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_nested_type_identifier_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_nested_type_identifier_child(this, _, result) - } - } - - /** A class representing `nil_coalescing_expression` nodes. */ - class NilCoalescingExpression extends @swift_nil_coalescing_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NilCoalescingExpression" } - - /** Gets the node corresponding to the field `if_nil`. */ - final Expression getIfNil() { swift_nil_coalescing_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_nil_coalescing_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_nil_coalescing_expression_def(this, result, _) or - swift_nil_coalescing_expression_def(this, _, result) - } - } - - /** A class representing `oct_literal` tokens. */ - class OctLiteral extends @swift_token_oct_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OctLiteral" } - } - - /** A class representing `opaque_type` nodes. */ - class OpaqueType extends @swift_opaque_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OpaqueType" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_opaque_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_opaque_type_def(this, result) } - } - - /** A class representing `open_end_range_expression` nodes. */ - class OpenEndRangeExpression extends @swift_open_end_range_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OpenEndRangeExpression" } - - /** Gets the node corresponding to the field `start`. */ - final Expression getStart() { swift_open_end_range_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_open_end_range_expression_def(this, result) } - } - - /** A class representing `open_start_range_expression` nodes. */ - class OpenStartRangeExpression extends @swift_open_start_range_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OpenStartRangeExpression" } - - /** Gets the node corresponding to the field `end`. */ - final Expression getEnd() { swift_open_start_range_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_open_start_range_expression_def(this, result) - } - } - - /** A class representing `operator_declaration` nodes. */ - class OperatorDeclaration extends @swift_operator_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OperatorDeclaration" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_operator_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_operator_declaration_child(this, _, result) } - } - - /** A class representing `optional_chain_marker` nodes. */ - class OptionalChainMarker extends @swift_optional_chain_marker, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OptionalChainMarker" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_optional_chain_marker_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_optional_chain_marker_def(this, result) } - } - - /** A class representing `optional_type` nodes. */ - class OptionalType extends @swift_optional_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OptionalType" } - - /** Gets the node corresponding to the field `wrapped`. */ - final AstNode getWrapped() { swift_optional_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_optional_type_def(this, result) } - } - - /** A class representing `ownership_modifier` tokens. */ - class OwnershipModifier extends @swift_token_ownership_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OwnershipModifier" } - } - - /** A class representing `parameter` nodes. */ - class Parameter extends @swift_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Parameter" } - - /** Gets the node corresponding to the field `external_name`. */ - final SimpleIdentifier getExternalName() { swift_parameter_external_name(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_parameter_def(this, result, _) } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_parameter_def(this, _, result) } - - /** Gets the child of this node. */ - final ParameterModifiers getChild() { swift_parameter_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_parameter_external_name(this, result) or - swift_parameter_def(this, result, _) or - swift_parameter_def(this, _, result) or - swift_parameter_child(this, result) - } - } - - /** A class representing `parameter_modifier` tokens. */ - class ParameterModifier extends @swift_token_parameter_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ParameterModifier" } - } - - /** A class representing `parameter_modifiers` nodes. */ - class ParameterModifiers extends @swift_parameter_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ParameterModifiers" } - - /** Gets the `i`th child of this node. */ - final ParameterModifier getChild(int i) { swift_parameter_modifiers_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_parameter_modifiers_child(this, _, result) } - } - - /** A class representing `pattern` nodes. */ - class Pattern extends @swift_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Pattern" } - - /** Gets the node corresponding to the field `bound_identifier`. */ - final SimpleIdentifier getBoundIdentifier() { swift_pattern_bound_identifier(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_pattern_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_pattern_bound_identifier(this, result) or swift_pattern_child(this, _, result) - } - } - - /** A class representing `playground_literal` nodes. */ - class PlaygroundLiteral extends @swift_playground_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PlaygroundLiteral" } - - /** Gets the `i`th child of this node. */ - final Expression getChild(int i) { swift_playground_literal_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_playground_literal_child(this, _, result) } - } - - /** A class representing `postfix_expression` nodes. */ - class PostfixExpression extends @swift_postfix_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PostfixExpression" } - - /** Gets the node corresponding to the field `operation`. */ - final AstNode getOperation() { swift_postfix_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `target`. */ - final Expression getTarget() { swift_postfix_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_postfix_expression_def(this, result, _) or swift_postfix_expression_def(this, _, result) - } - } - - /** A class representing `precedence_group_attribute` nodes. */ - class PrecedenceGroupAttribute extends @swift_precedence_group_attribute, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrecedenceGroupAttribute" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_precedence_group_attribute_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_precedence_group_attribute_child(this, _, result) - } - } - - /** A class representing `precedence_group_attributes` nodes. */ - class PrecedenceGroupAttributes extends @swift_precedence_group_attributes, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrecedenceGroupAttributes" } - - /** Gets the `i`th child of this node. */ - final PrecedenceGroupAttribute getChild(int i) { - swift_precedence_group_attributes_child(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_precedence_group_attributes_child(this, _, result) - } - } - - /** A class representing `precedence_group_declaration` nodes. */ - class PrecedenceGroupDeclaration extends @swift_precedence_group_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrecedenceGroupDeclaration" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_precedence_group_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_precedence_group_declaration_child(this, _, result) - } - } - - /** A class representing `prefix_expression` nodes. */ - class PrefixExpression extends @swift_prefix_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrefixExpression" } - - /** Gets the node corresponding to the field `operation`. */ - final AstNode getOperation() { swift_prefix_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `target`. */ - final Expression getTarget() { swift_prefix_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_prefix_expression_def(this, result, _) or swift_prefix_expression_def(this, _, result) - } - } - - /** A class representing `property_behavior_modifier` tokens. */ - class PropertyBehaviorModifier extends @swift_token_property_behavior_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyBehaviorModifier" } - } - - /** A class representing `property_declaration` nodes. */ - class PropertyDeclaration extends @swift_property_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyDeclaration" } - - /** Gets the node corresponding to the field `computed_value`. */ - final ComputedProperty getComputedValue(int i) { - swift_property_declaration_computed_value(this, i, result) - } - - /** Gets the node corresponding to the field `name`. */ - final Pattern getName(int i) { swift_property_declaration_name(this, i, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_property_declaration_value(this, i, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_property_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_property_declaration_computed_value(this, _, result) or - swift_property_declaration_name(this, _, result) or - swift_property_declaration_value(this, _, result) or - swift_property_declaration_child(this, _, result) - } - } - - /** A class representing `property_modifier` tokens. */ - class PropertyModifier extends @swift_token_property_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyModifier" } - } - - /** A class representing `protocol_body` nodes. */ - class ProtocolBody extends @swift_protocol_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolBody" } - - /** Gets the `i`th child of this node. */ - final ProtocolMemberDeclaration getChild(int i) { swift_protocol_body_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_protocol_body_child(this, _, result) } - } - - /** A class representing `protocol_composition_type` nodes. */ - class ProtocolCompositionType extends @swift_protocol_composition_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolCompositionType" } - - /** Gets the `i`th child of this node. */ - final UnannotatedType getChild(int i) { swift_protocol_composition_type_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_composition_type_child(this, _, result) - } - } - - /** A class representing `protocol_declaration` nodes. */ - class ProtocolDeclaration extends @swift_protocol_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final ProtocolBody getBody() { swift_protocol_declaration_def(this, result, _, _) } - - /** Gets the node corresponding to the field `declaration_kind`. */ - final string getDeclarationKind() { - exists(int value | swift_protocol_declaration_def(this, _, value, _) | - (result = "protocol" and value = 0) - ) - } - - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_protocol_declaration_def(this, _, _, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_declaration_def(this, result, _, _) or - swift_protocol_declaration_def(this, _, _, result) or - swift_protocol_declaration_child(this, _, result) - } - } - - /** A class representing `protocol_function_declaration` nodes. */ - class ProtocolFunctionDeclaration extends @swift_protocol_function_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolFunctionDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_protocol_function_declaration_body(this, result) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_protocol_function_declaration_default_value(this, i, result) - } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_protocol_function_declaration_def(this, result) } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_protocol_function_declaration_return_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_function_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_function_declaration_body(this, result) or - swift_protocol_function_declaration_default_value(this, _, result) or - swift_protocol_function_declaration_def(this, result) or - swift_protocol_function_declaration_return_type(this, result) or - swift_protocol_function_declaration_child(this, _, result) - } - } - - class ProtocolMemberDeclaration extends @swift_protocol_member_declaration, AstNode { } - - /** A class representing `protocol_property_declaration` nodes. */ - class ProtocolPropertyDeclaration extends @swift_protocol_property_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolPropertyDeclaration" } - - /** Gets the node corresponding to the field `name`. */ - final Pattern getName() { swift_protocol_property_declaration_def(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_property_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_property_declaration_def(this, result) or - swift_protocol_property_declaration_child(this, _, result) - } - } - - /** A class representing `protocol_property_requirements` nodes. */ - class ProtocolPropertyRequirements extends @swift_protocol_property_requirements, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolPropertyRequirements" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_protocol_property_requirements_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_property_requirements_child(this, _, result) - } - } - - /** A class representing `range_expression` nodes. */ - class RangeExpression extends @swift_range_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RangeExpression" } - - /** Gets the node corresponding to the field `end`. */ - final Expression getEnd() { swift_range_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_range_expression_def(this, _, value, _) | - result = "..." and value = 0 - or - result = "..<" and value = 1 - ) - } - - /** Gets the node corresponding to the field `start`. */ - final Expression getStart() { swift_range_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_range_expression_def(this, result, _, _) or - swift_range_expression_def(this, _, _, result) - } - } - - /** A class representing `raw_str_continuing_indicator` tokens. */ - class RawStrContinuingIndicator extends @swift_token_raw_str_continuing_indicator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrContinuingIndicator" } - } - - /** A class representing `raw_str_end_part` tokens. */ - class RawStrEndPart extends @swift_token_raw_str_end_part, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrEndPart" } - } - - /** A class representing `raw_str_interpolation` nodes. */ - class RawStrInterpolation extends @swift_raw_str_interpolation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrInterpolation" } - - /** Gets the node corresponding to the field `interpolation`. */ - final InterpolatedExpression getInterpolation(int i) { - swift_raw_str_interpolation_interpolation(this, i, result) - } - - /** Gets the child of this node. */ - final RawStrInterpolationStart getChild() { swift_raw_str_interpolation_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_raw_str_interpolation_interpolation(this, _, result) or - swift_raw_str_interpolation_def(this, result) - } - } - - /** A class representing `raw_str_interpolation_start` tokens. */ - class RawStrInterpolationStart extends @swift_token_raw_str_interpolation_start, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrInterpolationStart" } - } - - /** A class representing `raw_str_part` tokens. */ - class RawStrPart extends @swift_token_raw_str_part, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrPart" } - } - - /** A class representing `raw_string_literal` nodes. */ - class RawStringLiteral extends @swift_raw_string_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStringLiteral" } - - /** Gets the node corresponding to the field `interpolation`. */ - final RawStrInterpolation getInterpolation(int i) { - swift_raw_string_literal_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `text`. */ - final AstNode getText(int i) { swift_raw_string_literal_text(this, i, result) } - - /** Gets the `i`th child of this node. */ - final RawStrContinuingIndicator getChild(int i) { - swift_raw_string_literal_child(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_raw_string_literal_interpolation(this, _, result) or - swift_raw_string_literal_text(this, _, result) or - swift_raw_string_literal_child(this, _, result) - } - } - - /** A class representing `real_literal` tokens. */ - class RealLiteral extends @swift_token_real_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RealLiteral" } - } - - /** A class representing `referenceable_operator` nodes. */ - class ReferenceableOperator extends @swift_referenceable_operator, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ReferenceableOperator" } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_referenceable_operator_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_referenceable_operator_child(this, result) } - } - - /** A class representing `regex_literal` tokens. */ - class RegexLiteral extends @swift_token_regex_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RegexLiteral" } - } - - /** A class representing `repeat_while_statement` nodes. */ - class RepeatWhileStatement extends @swift_repeat_while_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RepeatWhileStatement" } - - /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { - swift_repeat_while_statement_condition(this, i, result) - } - - /** Gets the child of this node. */ - final Statements getChild() { swift_repeat_while_statement_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_repeat_while_statement_condition(this, _, result) or - swift_repeat_while_statement_child(this, result) - } - } - - /** A class representing `selector_expression` nodes. */ - class SelectorExpression extends @swift_selector_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SelectorExpression" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_selector_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_selector_expression_def(this, result) } - } - - /** A class representing `self_expression` tokens. */ - class SelfExpression extends @swift_token_self_expression, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SelfExpression" } - } - - /** A class representing `setter_specifier` nodes. */ - class SetterSpecifier extends @swift_setter_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SetterSpecifier" } - - /** Gets the child of this node. */ - final MutationModifier getChild() { swift_setter_specifier_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_setter_specifier_child(this, result) } - } - - /** A class representing `shebang_line` tokens. */ - class ShebangLine extends @swift_token_shebang_line, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ShebangLine" } - } - - /** A class representing `simple_identifier` tokens. */ - class SimpleIdentifier extends @swift_token_simple_identifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SimpleIdentifier" } - } - - /** A class representing `source_file` nodes. */ - class SourceFile extends @swift_source_file, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SourceFile" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_source_file_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_source_file_child(this, _, result) } - } - - /** A class representing `special_literal` tokens. */ - class SpecialLiteral extends @swift_token_special_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SpecialLiteral" } - } - - /** A class representing `statement_label` tokens. */ - class StatementLabel extends @swift_token_statement_label, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "StatementLabel" } - } - - /** A class representing `statements` nodes. */ - class Statements extends @swift_statements, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Statements" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_statements_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_statements_child(this, _, result) } - } - - /** A class representing `str_escaped_char` tokens. */ - class StrEscapedChar extends @swift_token_str_escaped_char, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "StrEscapedChar" } - } - - /** A class representing `subscript_declaration` nodes. */ - class SubscriptDeclaration extends @swift_subscript_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SubscriptDeclaration" } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_subscript_declaration_default_value(this, i, result) - } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_subscript_declaration_return_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_subscript_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_subscript_declaration_default_value(this, _, result) or - swift_subscript_declaration_return_type(this, result) or - swift_subscript_declaration_child(this, _, result) - } - } - - /** A class representing `super_expression` tokens. */ - class SuperExpression extends @swift_token_super_expression, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SuperExpression" } - } - - /** A class representing `suppressed_constraint` nodes. */ - class SuppressedConstraint extends @swift_suppressed_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SuppressedConstraint" } - - /** Gets the node corresponding to the field `suppressed`. */ - final TypeIdentifier getSuppressed() { swift_suppressed_constraint_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_suppressed_constraint_def(this, result) } - } - - /** A class representing `switch_entry` nodes. */ - class SwitchEntry extends @swift_switch_entry, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SwitchEntry" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_switch_entry_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_switch_entry_child(this, _, result) } - } - - /** A class representing `switch_pattern` nodes. */ - class SwitchPattern extends @swift_switch_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SwitchPattern" } - - /** Gets the child of this node. */ - final Pattern getChild() { swift_switch_pattern_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_switch_pattern_def(this, result) } - } - - /** A class representing `switch_statement` nodes. */ - class SwitchStatement extends @swift_switch_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SwitchStatement" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_switch_statement_def(this, result) } - - /** Gets the `i`th child of this node. */ - final SwitchEntry getChild(int i) { swift_switch_statement_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_switch_statement_def(this, result) or swift_switch_statement_child(this, _, result) - } - } - - /** A class representing `ternary_expression` nodes. */ - class TernaryExpression extends @swift_ternary_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TernaryExpression" } - - /** Gets the node corresponding to the field `condition`. */ - final Expression getCondition() { swift_ternary_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `if_false`. */ - final Expression getIfFalse() { swift_ternary_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `if_true`. */ - final Expression getIfTrue() { swift_ternary_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_ternary_expression_def(this, result, _, _) or - swift_ternary_expression_def(this, _, result, _) or - swift_ternary_expression_def(this, _, _, result) - } - } - - /** A class representing `throw_keyword` tokens. */ - class ThrowKeyword extends @swift_token_throw_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ThrowKeyword" } - } - - /** A class representing `throws` tokens. */ - class Throws extends @swift_token_throws, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Throws" } - } - - /** A class representing `throws_clause` nodes. */ - class ThrowsClause extends @swift_throws_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ThrowsClause" } - - /** Gets the node corresponding to the field `type`. */ - final UnannotatedType getType() { swift_throws_clause_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_throws_clause_def(this, result) } - } - - /** A class representing `try_expression` nodes. */ - class TryExpression extends @swift_try_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TryExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_try_expression_def(this, result, _) } - - /** Gets the child of this node. */ - final TryOperator getChild() { swift_try_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_try_expression_def(this, result, _) or swift_try_expression_def(this, _, result) - } - } - - /** A class representing `try_operator` tokens. */ - class TryOperator extends @swift_token_try_operator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TryOperator" } - } - - /** A class representing `tuple_expression` nodes. */ - class TupleExpression extends @swift_tuple_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleExpression" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_tuple_expression_name(this, i, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_tuple_expression_value(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_tuple_expression_name(this, _, result) or swift_tuple_expression_value(this, _, result) - } - } - - /** A class representing `tuple_type` nodes. */ - class TupleType extends @swift_tuple_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleType" } - - /** Gets the node corresponding to the field `element`. */ - final TupleTypeItem getElement(int i) { swift_tuple_type_element(this, i, result) } - - /** Gets the child of this node. */ - final TupleTypeItem getChild() { swift_tuple_type_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_tuple_type_element(this, _, result) or swift_tuple_type_child(this, result) - } - } - - /** A class representing `tuple_type_item` nodes. */ - class TupleTypeItem extends @swift_tuple_type_item, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleTypeItem" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_tuple_type_item_name(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_tuple_type_item_type(this, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_tuple_type_item_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_tuple_type_item_name(this, result) or - swift_tuple_type_item_type(this, result) or - swift_tuple_type_item_child(this, _, result) - } - } - - /** A class representing `type` nodes. */ - class Type extends @swift_type__, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Type" } - - /** Gets the node corresponding to the field `modifiers`. */ - final TypeModifiers getModifiers() { swift_type_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final UnannotatedType getName() { swift_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_type_modifiers(this, result) or swift_type_def(this, result) - } - } - - /** A class representing `type_annotation` nodes. */ - class TypeAnnotation extends @swift_type_annotation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeAnnotation" } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_type_annotation_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_annotation_def(this, result) } - } - - /** A class representing `type_arguments` nodes. */ - class TypeArguments extends @swift_type_arguments, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeArguments" } - - /** Gets the `i`th child of this node. */ - final Type getChild(int i) { swift_type_arguments_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_arguments_child(this, _, result) } - } - - /** A class representing `type_constraint` nodes. */ - class TypeConstraint extends @swift_type_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeConstraint" } - - /** Gets the child of this node. */ - final AstNode getChild() { swift_type_constraint_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_constraint_def(this, result) } - } - - /** A class representing `type_constraints` nodes. */ - class TypeConstraints extends @swift_type_constraints, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeConstraints" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_type_constraints_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_constraints_child(this, _, result) } - } - - /** A class representing `type_identifier` tokens. */ - class TypeIdentifier extends @swift_token_type_identifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeIdentifier" } - } - - class TypeLevelDeclaration extends @swift_type_level_declaration, AstNode { } - - /** A class representing `type_modifiers` nodes. */ - class TypeModifiers extends @swift_type_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeModifiers" } - - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_type_modifiers_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_modifiers_child(this, _, result) } - } - - /** A class representing `type_pack_expansion` nodes. */ - class TypePackExpansion extends @swift_type_pack_expansion, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypePackExpansion" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_type_pack_expansion_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_pack_expansion_def(this, result) } - } - - /** A class representing `type_parameter` nodes. */ - class TypeParameter extends @swift_type_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameter" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_type_parameter_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_parameter_child(this, _, result) } - } - - /** A class representing `type_parameter_modifiers` nodes. */ - class TypeParameterModifiers extends @swift_type_parameter_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameterModifiers" } - - /** Gets the `i`th child of this node. */ - final Attribute getChild(int i) { swift_type_parameter_modifiers_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_type_parameter_modifiers_child(this, _, result) - } - } - - /** A class representing `type_parameter_pack` nodes. */ - class TypeParameterPack extends @swift_type_parameter_pack, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameterPack" } - - /** Gets the child of this node. */ - final UnannotatedType getChild() { swift_type_parameter_pack_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_parameter_pack_def(this, result) } - } - - /** A class representing `type_parameters` nodes. */ - class TypeParameters extends @swift_type_parameters, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameters" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_type_parameters_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_parameters_child(this, _, result) } - } - - /** A class representing `typealias_declaration` nodes. */ - class TypealiasDeclaration extends @swift_typealias_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypealiasDeclaration" } - - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_typealias_declaration_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Type getValue() { swift_typealias_declaration_def(this, _, result) } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_typealias_declaration_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_typealias_declaration_def(this, result, _) or - swift_typealias_declaration_def(this, _, result) or - swift_typealias_declaration_child(this, _, result) - } - } - - class UnannotatedType extends @swift_unannotated_type, AstNode { } - - /** A class representing `user_type` nodes. */ - class UserType extends @swift_user_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "UserType" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_user_type_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_user_type_child(this, _, result) } - } - - /** A class representing `value_argument` nodes. */ - class ValueArgument extends @swift_value_argument, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueArgument" } - - /** Gets the node corresponding to the field `name`. */ - final ValueArgumentLabel getName() { swift_value_argument_name(this, result) } - - /** Gets the node corresponding to the field `reference_specifier`. */ - final ValueArgumentLabel getReferenceSpecifier(int i) { - swift_value_argument_reference_specifier(this, i, result) - } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_value_argument_value(this, result) } - - /** Gets the child of this node. */ - final TypeModifiers getChild() { swift_value_argument_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_value_argument_name(this, result) or - swift_value_argument_reference_specifier(this, _, result) or - swift_value_argument_value(this, result) or - swift_value_argument_child(this, result) - } - } - - /** A class representing `value_argument_label` nodes. */ - class ValueArgumentLabel extends @swift_value_argument_label, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueArgumentLabel" } - - /** Gets the child of this node. */ - final SimpleIdentifier getChild() { swift_value_argument_label_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_argument_label_def(this, result) } - } - - /** A class representing `value_arguments` nodes. */ - class ValueArguments extends @swift_value_arguments, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueArguments" } - - /** Gets the `i`th child of this node. */ - final ValueArgument getChild(int i) { swift_value_arguments_child(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_arguments_child(this, _, result) } - } - - /** A class representing `value_binding_pattern` nodes. */ - class ValueBindingPattern extends @swift_value_binding_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueBindingPattern" } - - /** Gets the node corresponding to the field `mutability`. */ - final string getMutability() { - exists(int value | swift_value_binding_pattern_def(this, value) | - result = "let" and value = 0 - or - result = "var" and value = 1 - ) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { none() } - } - - /** A class representing `value_pack_expansion` nodes. */ - class ValuePackExpansion extends @swift_value_pack_expansion, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValuePackExpansion" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_value_pack_expansion_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_pack_expansion_def(this, result) } - } - - /** A class representing `value_parameter_pack` nodes. */ - class ValueParameterPack extends @swift_value_parameter_pack, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueParameterPack" } - - /** Gets the child of this node. */ - final Expression getChild() { swift_value_parameter_pack_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_parameter_pack_def(this, result) } - } - - /** A class representing `visibility_modifier` tokens. */ - class VisibilityModifier extends @swift_token_visibility_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "VisibilityModifier" } - } - - /** A class representing `where_clause` nodes. */ - class WhereClause extends @swift_where_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WhereClause" } - - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { swift_where_clause_child(this, i, result) } -======= final override string getAPrimaryQlClass() { result = "TopLevel" } /** Gets the node corresponding to the field `body`. */ - final Expr getBody(int i) { unified_top_level_body(this, i, result) } ->>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) + final AstNode getBody(int i) { unified_top_level_body(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { unified_top_level_body(this, _, result) } } + /** A class representing `tuple_pattern` nodes. */ + class TuplePattern extends @unified_tuple_pattern, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TuplePattern" } + + /** Gets the node corresponding to the field `element`. */ + final Pattern getElement(int i) { unified_tuple_pattern_element(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { unified_tuple_pattern_element(this, _, result) } + } + /** A class representing `unary_expr` nodes. */ class UnaryExpr extends @unified_unary_expr, AstNode { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "UnaryExpr" } -<<<<<<< HEAD - /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { swift_while_statement_condition(this, i, result) } - - /** Gets the child of this node. */ - final Statements getChild() { swift_while_statement_child(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_while_statement_condition(this, _, result) or swift_while_statement_child(this, result) -======= /** Gets the node corresponding to the field `operand`. */ final Expr getOperand() { unified_unary_expr_def(this, result, _) } /** Gets the node corresponding to the field `operator`. */ - final UnaryOperator getOperator() { unified_unary_expr_def(this, _, result) } + final Operator getOperator() { unified_unary_expr_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { unified_unary_expr_def(this, result, _) or unified_unary_expr_def(this, _, result) ->>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) } } - /** A class representing `unary_operator` tokens. */ - class UnaryOperator extends @unified_token_unary_operator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "UnaryOperator" } - } - /** A class representing `unsupported_node` tokens. */ class UnsupportedNode extends @unified_token_unsupported_node, Token { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "UnsupportedNode" } } + + /** A class representing `var_pattern` nodes. */ + class VarPattern extends @unified_var_pattern, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "VarPattern" } + + /** Gets the node corresponding to the field `identifier`. */ + final Identifier getIdentifier() { unified_var_pattern_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { unified_var_pattern_def(this, result) } + } + + /** A class representing `variable_declaration_stmt` nodes. */ + class VariableDeclarationStmt extends @unified_variable_declaration_stmt, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "VariableDeclarationStmt" } + + /** Gets the node corresponding to the field `variable_declarator`. */ + final VariableDeclarator getVariableDeclarator(int i) { + unified_variable_declaration_stmt_variable_declarator(this, i, result) + } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_variable_declaration_stmt_variable_declarator(this, _, result) + } + } + + /** A class representing `variable_declarator` nodes. */ + class VariableDeclarator extends @unified_variable_declarator, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "VariableDeclarator" } + + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { unified_variable_declarator_def(this, result) } + + /** Gets the node corresponding to the field `value`. */ + final Expr getValue() { unified_variable_declarator_value(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + unified_variable_declarator_def(this, result) or + unified_variable_declarator_value(this, result) + } + } } diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme index 91271d1b363..28718d79423 100644 --- a/unified/ql/lib/unified.dbscheme +++ b/unified/ql/lib/unified.dbscheme @@ -131,1958 +131,190 @@ overlayChangedFiles( string path: string ref ); -<<<<<<< HEAD -/*- Swift dbscheme -*/ -case @swift_additive_expression.op of - 0 = @swift_additive_expression_plus -| 1 = @swift_additive_expression_minus -; - - -swift_additive_expression_def( - unique int id: @swift_additive_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -#keyset[swift_array_literal, index] -swift_array_literal_element( - int swift_array_literal: @swift_array_literal ref, - int index: int ref, - unique int element: @swift_expression ref -); - -swift_array_literal_def( - unique int id: @swift_array_literal -); - -swift_array_type_def( - unique int id: @swift_array_type, - int element: @swift_type__ ref -); - -swift_as_expression_def( - unique int id: @swift_as_expression, - int expr: @swift_expression ref, - int type__: @swift_type__ ref, - int child: @swift_token_as_operator ref -); - -case @swift_assignment.operator of - 0 = @swift_assignment_percentequal -| 1 = @swift_assignment_starequal -| 2 = @swift_assignment_plusequal -| 3 = @swift_assignment_minusequal -| 4 = @swift_assignment_slashequal -| 5 = @swift_assignment_equal -; - - -swift_assignment_def( - unique int id: @swift_assignment, - int operator: int ref, - int result: @swift_expression ref, - int target: @swift_directly_assignable_expression ref -); - -swift_associatedtype_declaration_default_value( - unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - unique int default_value: @swift_type__ ref -); - -swift_associatedtype_declaration_must_inherit( - unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - unique int must_inherit: @swift_type__ ref -); - -@swift_associatedtype_declaration_child_type = @swift_modifiers | @swift_type_constraints - -#keyset[swift_associatedtype_declaration, index] -swift_associatedtype_declaration_child( - int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - int index: int ref, - unique int child: @swift_associatedtype_declaration_child_type ref -); - -swift_associatedtype_declaration_def( - unique int id: @swift_associatedtype_declaration, - int name: @swift_token_type_identifier ref -); - -@swift_attribute_child_type = @swift_expression | @swift_user_type - -#keyset[swift_attribute, index] -swift_attribute_child( - int swift_attribute: @swift_attribute ref, - int index: int ref, - unique int child: @swift_attribute_child_type ref -); - -swift_attribute_def( - unique int id: @swift_attribute -); - -@swift_availability_condition_child_type = @swift_identifier | @swift_token_integer_literal - -#keyset[swift_availability_condition, index] -swift_availability_condition_child( - int swift_availability_condition: @swift_availability_condition ref, - int index: int ref, - unique int child: @swift_availability_condition_child_type ref -); - -swift_availability_condition_def( - unique int id: @swift_availability_condition -); - -swift_await_expression_expr( - unique int swift_await_expression: @swift_await_expression ref, - unique int expr: @swift_expression ref -); - -swift_await_expression_child( - unique int swift_await_expression: @swift_await_expression ref, - unique int child: @swift_expression ref -); - -swift_await_expression_def( - unique int id: @swift_await_expression -); - -case @swift_bitwise_operation.op of - 0 = @swift_bitwise_operation_ampersand -| 1 = @swift_bitwise_operation_langlelangle -| 2 = @swift_bitwise_operation_ranglerangle -| 3 = @swift_bitwise_operation_caret -| 4 = @swift_bitwise_operation_pipe -; - - -swift_bitwise_operation_def( - unique int id: @swift_bitwise_operation, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_call_expression_child_type = @swift_call_suffix | @swift_expression - -#keyset[swift_call_expression, index] -swift_call_expression_child( - int swift_call_expression: @swift_call_expression ref, - int index: int ref, - unique int child: @swift_call_expression_child_type ref -); - -swift_call_expression_def( - unique int id: @swift_call_expression -); - -#keyset[swift_call_suffix, index] -swift_call_suffix_name( - int swift_call_suffix: @swift_call_suffix ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -@swift_call_suffix_child_type = @swift_lambda_literal | @swift_value_arguments - -#keyset[swift_call_suffix, index] -swift_call_suffix_child( - int swift_call_suffix: @swift_call_suffix ref, - int index: int ref, - unique int child: @swift_call_suffix_child_type ref -); - -swift_call_suffix_def( - unique int id: @swift_call_suffix -); - -#keyset[swift_capture_list, index] -swift_capture_list_child( - int swift_capture_list: @swift_capture_list ref, - int index: int ref, - unique int child: @swift_capture_list_item ref -); - -swift_capture_list_def( - unique int id: @swift_capture_list -); - -@swift_capture_list_item_name_type = @swift_token_self_expression | @swift_token_simple_identifier - -swift_capture_list_item_value( - unique int swift_capture_list_item: @swift_capture_list_item ref, - unique int value: @swift_expression ref -); - -swift_capture_list_item_child( - unique int swift_capture_list_item: @swift_capture_list_item ref, - unique int child: @swift_token_ownership_modifier ref -); - -swift_capture_list_item_def( - unique int id: @swift_capture_list_item, - int name: @swift_capture_list_item_name_type ref -); - -swift_catch_block_error( - unique int swift_catch_block: @swift_catch_block ref, - unique int error: @swift_pattern ref -); - -@swift_catch_block_child_type = @swift_statements | @swift_token_catch_keyword | @swift_where_clause - -#keyset[swift_catch_block, index] -swift_catch_block_child( - int swift_catch_block: @swift_catch_block ref, - int index: int ref, - unique int child: @swift_catch_block_child_type ref -); - -swift_catch_block_def( - unique int id: @swift_catch_block -); - -case @swift_check_expression.op of - 0 = @swift_check_expression_is -; - - -swift_check_expression_def( - unique int id: @swift_check_expression, - int op: int ref, - int target: @swift_expression ref, - int type__: @swift_type__ ref -); - -@swift_class_body_child_type = @swift_token_multiline_comment | @swift_type_level_declaration - -#keyset[swift_class_body, index] -swift_class_body_child( - int swift_class_body: @swift_class_body ref, - int index: int ref, - unique int child: @swift_class_body_child_type ref -); - -swift_class_body_def( - unique int id: @swift_class_body -); - -@swift_class_declaration_body_type = @swift_class_body | @swift_enum_class_body - -case @swift_class_declaration.declaration_kind of - 0 = @swift_class_declaration_actor -| 1 = @swift_class_declaration_class -| 2 = @swift_class_declaration_enum -| 3 = @swift_class_declaration_extension -| 4 = @swift_class_declaration_struct -; - - -@swift_class_declaration_name_type = @swift_token_type_identifier | @swift_unannotated_type - -@swift_class_declaration_child_type = @swift_attribute | @swift_inheritance_specifier | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_class_declaration, index] -swift_class_declaration_child( - int swift_class_declaration: @swift_class_declaration ref, - int index: int ref, - unique int child: @swift_class_declaration_child_type ref -); - -swift_class_declaration_def( - unique int id: @swift_class_declaration, - int body: @swift_class_declaration_body_type ref, - int declaration_kind: int ref, - int name: @swift_class_declaration_name_type ref -); - -case @swift_comparison_expression.op of - 0 = @swift_comparison_expression_langle -| 1 = @swift_comparison_expression_langleequal -| 2 = @swift_comparison_expression_rangle -| 3 = @swift_comparison_expression_rangleequal -; - - -swift_comparison_expression_def( - unique int id: @swift_comparison_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_computed_getter_child_type = @swift_attribute | @swift_getter_specifier | @swift_statements - -#keyset[swift_computed_getter, index] -swift_computed_getter_child( - int swift_computed_getter: @swift_computed_getter ref, - int index: int ref, - unique int child: @swift_computed_getter_child_type ref -); - -swift_computed_getter_def( - unique int id: @swift_computed_getter -); - -@swift_computed_modify_child_type = @swift_attribute | @swift_modify_specifier | @swift_statements - -#keyset[swift_computed_modify, index] -swift_computed_modify_child( - int swift_computed_modify: @swift_computed_modify ref, - int index: int ref, - unique int child: @swift_computed_modify_child_type ref -); - -swift_computed_modify_def( - unique int id: @swift_computed_modify -); - -@swift_computed_property_child_type = @swift_computed_getter | @swift_computed_modify | @swift_computed_setter | @swift_statements - -#keyset[swift_computed_property, index] -swift_computed_property_child( - int swift_computed_property: @swift_computed_property ref, - int index: int ref, - unique int child: @swift_computed_property_child_type ref -); - -swift_computed_property_def( - unique int id: @swift_computed_property -); - -@swift_computed_setter_child_type = @swift_attribute | @swift_setter_specifier | @swift_statements | @swift_token_simple_identifier - -#keyset[swift_computed_setter, index] -swift_computed_setter_child( - int swift_computed_setter: @swift_computed_setter ref, - int index: int ref, - unique int child: @swift_computed_setter_child_type ref -); - -swift_computed_setter_def( - unique int id: @swift_computed_setter -); - -case @swift_conjunction_expression.op of - 0 = @swift_conjunction_expression_ampersandampersand -; - - -swift_conjunction_expression_def( - unique int id: @swift_conjunction_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_constructor_expression_constructed_type_type = @swift_array_type | @swift_dictionary_type | @swift_user_type - -swift_constructor_expression_def( - unique int id: @swift_constructor_expression, - int constructed_type: @swift_constructor_expression_constructed_type_type ref, - int child: @swift_constructor_suffix ref -); - -#keyset[swift_constructor_suffix, index] -swift_constructor_suffix_name( - int swift_constructor_suffix: @swift_constructor_suffix ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -@swift_constructor_suffix_child_type = @swift_lambda_literal | @swift_value_arguments - -#keyset[swift_constructor_suffix, index] -swift_constructor_suffix_child( - int swift_constructor_suffix: @swift_constructor_suffix ref, - int index: int ref, - unique int child: @swift_constructor_suffix_child_type ref -); - -swift_constructor_suffix_def( - unique int id: @swift_constructor_suffix -); - -swift_control_transfer_statement_result( - unique int swift_control_transfer_statement: @swift_control_transfer_statement ref, - unique int result: @swift_expression ref -); - -@swift_control_transfer_statement_child_type = @swift_expression | @swift_token_throw_keyword - -#keyset[swift_control_transfer_statement, index] -swift_control_transfer_statement_child( - int swift_control_transfer_statement: @swift_control_transfer_statement ref, - int index: int ref, - unique int child: @swift_control_transfer_statement_child_type ref -); - -swift_control_transfer_statement_def( - unique int id: @swift_control_transfer_statement -); - -swift_deinit_declaration_child( - unique int swift_deinit_declaration: @swift_deinit_declaration ref, - unique int child: @swift_modifiers ref -); - -swift_deinit_declaration_def( - unique int id: @swift_deinit_declaration, - int body: @swift_function_body ref -); - -@swift_deprecated_operator_declaration_body_child_type = @swift_line_string_literal | @swift_multi_line_string_literal | @swift_raw_string_literal | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_simple_identifier - -#keyset[swift_deprecated_operator_declaration_body, index] -swift_deprecated_operator_declaration_body_child( - int swift_deprecated_operator_declaration_body: @swift_deprecated_operator_declaration_body ref, - int index: int ref, - unique int child: @swift_deprecated_operator_declaration_body_child_type ref -); - -swift_deprecated_operator_declaration_body_def( - unique int id: @swift_deprecated_operator_declaration_body -); - -#keyset[swift_dictionary_literal, index] -swift_dictionary_literal_key( - int swift_dictionary_literal: @swift_dictionary_literal ref, - int index: int ref, - unique int key__: @swift_expression ref -); - -#keyset[swift_dictionary_literal, index] -swift_dictionary_literal_value( - int swift_dictionary_literal: @swift_dictionary_literal ref, - int index: int ref, - unique int value: @swift_expression ref -); - -swift_dictionary_literal_def( - unique int id: @swift_dictionary_literal -); - -swift_dictionary_type_def( - unique int id: @swift_dictionary_type, - int key__: @swift_type__ ref, - int value: @swift_type__ ref -); - -@swift_didset_clause_child_type = @swift_modifiers | @swift_statements | @swift_token_simple_identifier - -#keyset[swift_didset_clause, index] -swift_didset_clause_child( - int swift_didset_clause: @swift_didset_clause ref, - int index: int ref, - unique int child: @swift_didset_clause_child_type ref -); - -swift_didset_clause_def( - unique int id: @swift_didset_clause -); - -@swift_directive_child_type = @swift_token_boolean_literal | @swift_token_integer_literal | @swift_token_simple_identifier - -#keyset[swift_directive, index] -swift_directive_child( - int swift_directive: @swift_directive ref, - int index: int ref, - unique int child: @swift_directive_child_type ref -); - -swift_directive_def( - unique int id: @swift_directive -); - -swift_directly_assignable_expression_def( - unique int id: @swift_directly_assignable_expression, - int child: @swift_expression ref -); - -case @swift_disjunction_expression.op of - 0 = @swift_disjunction_expression_pipepipe -; - - -swift_disjunction_expression_def( - unique int id: @swift_disjunction_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_do_statement_child_type = @swift_catch_block | @swift_statements - -#keyset[swift_do_statement, index] -swift_do_statement_child( - int swift_do_statement: @swift_do_statement ref, - int index: int ref, - unique int child: @swift_do_statement_child_type ref -); - -swift_do_statement_def( - unique int id: @swift_do_statement -); - -@swift_enum_class_body_child_type = @swift_enum_entry | @swift_type_level_declaration - -#keyset[swift_enum_class_body, index] -swift_enum_class_body_child( - int swift_enum_class_body: @swift_enum_class_body ref, - int index: int ref, - unique int child: @swift_enum_class_body_child_type ref -); - -swift_enum_class_body_def( - unique int id: @swift_enum_class_body -); - -#keyset[swift_enum_entry, index] -swift_enum_entry_data_contents( - int swift_enum_entry: @swift_enum_entry ref, - int index: int ref, - unique int data_contents: @swift_enum_type_parameters ref -); - -#keyset[swift_enum_entry, index] -swift_enum_entry_name( - int swift_enum_entry: @swift_enum_entry ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -#keyset[swift_enum_entry, index] -swift_enum_entry_raw_value( - int swift_enum_entry: @swift_enum_entry ref, - int index: int ref, - unique int raw_value: @swift_expression ref -); - -swift_enum_entry_child( - unique int swift_enum_entry: @swift_enum_entry ref, - unique int child: @swift_modifiers ref -); - -swift_enum_entry_def( - unique int id: @swift_enum_entry -); - -@swift_enum_type_parameters_child_type = @swift_expression | @swift_token_wildcard_pattern | @swift_type__ - -#keyset[swift_enum_type_parameters, index] -swift_enum_type_parameters_child( - int swift_enum_type_parameters: @swift_enum_type_parameters ref, - int index: int ref, - unique int child: @swift_enum_type_parameters_child_type ref -); - -swift_enum_type_parameters_def( - unique int id: @swift_enum_type_parameters -); - -@swift_equality_constraint_constrained_type_type = @swift_identifier | @swift_nested_type_identifier - -#keyset[swift_equality_constraint, index] -swift_equality_constraint_child( - int swift_equality_constraint: @swift_equality_constraint ref, - int index: int ref, - unique int child: @swift_attribute ref -); - -swift_equality_constraint_def( - unique int id: @swift_equality_constraint, - int constrained_type: @swift_equality_constraint_constrained_type_type ref, - int must_equal: @swift_type__ ref -); - -case @swift_equality_expression.op of - 0 = @swift_equality_expression_bangequal -| 1 = @swift_equality_expression_bangequalequal -| 2 = @swift_equality_expression_equalequal -| 3 = @swift_equality_expression_equalequalequal -; - - -swift_equality_expression_def( - unique int id: @swift_equality_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -swift_existential_type_def( - unique int id: @swift_existential_type, - int child: @swift_unannotated_type ref -); - -@swift_expression = @swift_additive_expression | @swift_array_literal | @swift_as_expression | @swift_assignment | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_check_expression | @swift_comparison_expression | @swift_conjunction_expression | @swift_constructor_expression | @swift_dictionary_literal | @swift_directive | @swift_disjunction_expression | @swift_equality_expression | @swift_if_statement | @swift_infix_expression | @swift_key_path_expression | @swift_key_path_string_expression | @swift_lambda_literal | @swift_line_string_literal | @swift_macro_invocation | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_nil_coalescing_expression | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_optional_chain_marker | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_referenceable_operator | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_diagnostic | @swift_token_fully_open_range | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_self_expression | @swift_token_simple_identifier | @swift_token_special_literal | @swift_token_super_expression | @swift_try_expression | @swift_tuple_expression | @swift_value_pack_expansion | @swift_value_parameter_pack - -swift_external_macro_definition_def( - unique int id: @swift_external_macro_definition, - int child: @swift_value_arguments ref -); - -@swift_for_statement_child_type = @swift_statements | @swift_token_try_operator | @swift_type_annotation | @swift_where_clause - -#keyset[swift_for_statement, index] -swift_for_statement_child( - int swift_for_statement: @swift_for_statement ref, - int index: int ref, - unique int child: @swift_for_statement_child_type ref -); - -swift_for_statement_def( - unique int id: @swift_for_statement, - int collection: @swift_expression ref, - int item: @swift_pattern ref -); - -swift_function_body_child( - unique int swift_function_body: @swift_function_body ref, - unique int child: @swift_statements ref -); - -swift_function_body_def( - unique int id: @swift_function_body -); - -#keyset[swift_function_declaration, index] -swift_function_declaration_default_value( - int swift_function_declaration: @swift_function_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -@swift_function_declaration_name_type = @swift_referenceable_operator | @swift_token_simple_identifier - -@swift_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_function_declaration_return_type( - unique int swift_function_declaration: @swift_function_declaration ref, - unique int return_type: @swift_function_declaration_return_type_type ref -); - -@swift_function_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_throws_clause | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_token_throws | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_function_declaration, index] -swift_function_declaration_child( - int swift_function_declaration: @swift_function_declaration ref, - int index: int ref, - unique int child: @swift_function_declaration_child_type ref -); - -swift_function_declaration_def( - unique int id: @swift_function_declaration, - int body: @swift_function_body ref, - int name: @swift_function_declaration_name_type ref -); - -@swift_function_type_child_type = @swift_throws_clause | @swift_token_throws - -swift_function_type_child( - unique int swift_function_type: @swift_function_type ref, - unique int child: @swift_function_type_child_type ref -); - -swift_function_type_def( - unique int id: @swift_function_type, - int params: @swift_unannotated_type ref, - int return_type: @swift_type__ ref -); - -@swift_getter_specifier_child_type = @swift_throws_clause | @swift_token_mutation_modifier | @swift_token_throws - -#keyset[swift_getter_specifier, index] -swift_getter_specifier_child( - int swift_getter_specifier: @swift_getter_specifier ref, - int index: int ref, - unique int child: @swift_getter_specifier_child_type ref -); - -swift_getter_specifier_def( - unique int id: @swift_getter_specifier -); - -@swift_global_declaration = @swift_associatedtype_declaration | @swift_class_declaration | @swift_function_declaration | @swift_import_declaration | @swift_init_declaration | @swift_macro_declaration | @swift_operator_declaration | @swift_precedence_group_declaration | @swift_property_declaration | @swift_protocol_declaration | @swift_typealias_declaration - -#keyset[swift_guard_statement, index] -swift_guard_statement_condition( - int swift_guard_statement: @swift_guard_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -@swift_guard_statement_child_type = @swift_statements | @swift_token_else - -#keyset[swift_guard_statement, index] -swift_guard_statement_child( - int swift_guard_statement: @swift_guard_statement ref, - int index: int ref, - unique int child: @swift_guard_statement_child_type ref -); - -swift_guard_statement_def( - unique int id: @swift_guard_statement -); - -#keyset[swift_identifier, index] -swift_identifier_child( - int swift_identifier: @swift_identifier ref, - int index: int ref, - unique int child: @swift_token_simple_identifier ref -); - -swift_identifier_def( - unique int id: @swift_identifier -); - -@swift_if_condition_child_type = @swift_availability_condition | @swift_expression | @swift_if_let_binding - -swift_if_condition_def( - unique int id: @swift_if_condition, - int child: @swift_if_condition_child_type ref -); - -swift_if_let_binding_bound_identifier( - unique int swift_if_let_binding: @swift_if_let_binding ref, - unique int bound_identifier: @swift_token_simple_identifier ref -); - -@swift_if_let_binding_child_type = @swift_expression | @swift_pattern | @swift_token_wildcard_pattern | @swift_type__ | @swift_type_annotation | @swift_user_type | @swift_value_binding_pattern | @swift_where_clause - -#keyset[swift_if_let_binding, index] -swift_if_let_binding_child( - int swift_if_let_binding: @swift_if_let_binding ref, - int index: int ref, - unique int child: @swift_if_let_binding_child_type ref -); - -swift_if_let_binding_def( - unique int id: @swift_if_let_binding -); - -#keyset[swift_if_statement, index] -swift_if_statement_condition( - int swift_if_statement: @swift_if_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -@swift_if_statement_child_type = @swift_if_statement | @swift_statements | @swift_token_else - -#keyset[swift_if_statement, index] -swift_if_statement_child( - int swift_if_statement: @swift_if_statement ref, - int index: int ref, - unique int child: @swift_if_statement_child_type ref -); - -swift_if_statement_def( - unique int id: @swift_if_statement -); - -swift_implicitly_unwrapped_type_def( - unique int id: @swift_implicitly_unwrapped_type, - int child: @swift_type__ ref -); - -@swift_import_declaration_child_type = @swift_identifier | @swift_modifiers - -#keyset[swift_import_declaration, index] -swift_import_declaration_child( - int swift_import_declaration: @swift_import_declaration ref, - int index: int ref, - unique int child: @swift_import_declaration_child_type ref -); - -swift_import_declaration_def( - unique int id: @swift_import_declaration -); - -swift_infix_expression_def( - unique int id: @swift_infix_expression, - int lhs: @swift_expression ref, - int op: @swift_token_custom_operator ref, - int rhs: @swift_expression ref -); - -@swift_inheritance_constraint_constrained_type_type = @swift_identifier | @swift_nested_type_identifier - -@swift_inheritance_constraint_inherits_from_type = @swift_implicitly_unwrapped_type | @swift_type__ - -#keyset[swift_inheritance_constraint, index] -swift_inheritance_constraint_child( - int swift_inheritance_constraint: @swift_inheritance_constraint ref, - int index: int ref, - unique int child: @swift_attribute ref -); - -swift_inheritance_constraint_def( - unique int id: @swift_inheritance_constraint, - int constrained_type: @swift_inheritance_constraint_constrained_type_type ref, - int inherits_from: @swift_inheritance_constraint_inherits_from_type ref -); - -@swift_inheritance_specifier_inherits_from_type = @swift_function_type | @swift_suppressed_constraint | @swift_user_type - -swift_inheritance_specifier_def( - unique int id: @swift_inheritance_specifier, - int inherits_from: @swift_inheritance_specifier_inherits_from_type ref -); - -swift_init_declaration_body( - unique int swift_init_declaration: @swift_init_declaration ref, - unique int body: @swift_function_body ref -); - -#keyset[swift_init_declaration, index] -swift_init_declaration_default_value( - int swift_init_declaration: @swift_init_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -case @swift_init_declaration.name of - 0 = @swift_init_declaration_init -; - - -@swift_init_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_throws_clause | @swift_token_bang | @swift_token_throws | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_init_declaration, index] -swift_init_declaration_child( - int swift_init_declaration: @swift_init_declaration ref, - int index: int ref, - unique int child: @swift_init_declaration_child_type ref -); - -swift_init_declaration_def( - unique int id: @swift_init_declaration, - int name: int ref -); - -swift_interpolated_expression_name( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int name: @swift_value_argument_label ref -); - -#keyset[swift_interpolated_expression, index] -swift_interpolated_expression_reference_specifier( - int swift_interpolated_expression: @swift_interpolated_expression ref, - int index: int ref, - unique int reference_specifier: @swift_value_argument_label ref -); - -swift_interpolated_expression_value( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int value: @swift_expression ref -); - -swift_interpolated_expression_child( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int child: @swift_type_modifiers ref -); - -swift_interpolated_expression_def( - unique int id: @swift_interpolated_expression -); - -@swift_key_path_expression_child_type = @swift_array_type | @swift_dictionary_type | @swift_token_bang | @swift_token_simple_identifier | @swift_token_type_identifier | @swift_type_arguments | @swift_value_argument - -#keyset[swift_key_path_expression, index] -swift_key_path_expression_child( - int swift_key_path_expression: @swift_key_path_expression ref, - int index: int ref, - unique int child: @swift_key_path_expression_child_type ref -); - -swift_key_path_expression_def( - unique int id: @swift_key_path_expression -); - -swift_key_path_string_expression_def( - unique int id: @swift_key_path_string_expression, - int child: @swift_expression ref -); - -@swift_lambda_function_type_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_lambda_function_type_return_type( - unique int swift_lambda_function_type: @swift_lambda_function_type ref, - unique int return_type: @swift_lambda_function_type_return_type_type ref -); - -@swift_lambda_function_type_child_type = @swift_lambda_function_type_parameters | @swift_throws_clause | @swift_token_throws - -#keyset[swift_lambda_function_type, index] -swift_lambda_function_type_child( - int swift_lambda_function_type: @swift_lambda_function_type ref, - int index: int ref, - unique int child: @swift_lambda_function_type_child_type ref -); - -swift_lambda_function_type_def( - unique int id: @swift_lambda_function_type -); - -#keyset[swift_lambda_function_type_parameters, index] -swift_lambda_function_type_parameters_child( - int swift_lambda_function_type_parameters: @swift_lambda_function_type_parameters ref, - int index: int ref, - unique int child: @swift_lambda_parameter ref -); - -swift_lambda_function_type_parameters_def( - unique int id: @swift_lambda_function_type_parameters -); - -swift_lambda_literal_captures( - unique int swift_lambda_literal: @swift_lambda_literal ref, - unique int captures: @swift_capture_list ref -); - -swift_lambda_literal_type( - unique int swift_lambda_literal: @swift_lambda_literal ref, - unique int type__: @swift_lambda_function_type ref -); - -@swift_lambda_literal_child_type = @swift_attribute | @swift_statements - -#keyset[swift_lambda_literal, index] -swift_lambda_literal_child( - int swift_lambda_literal: @swift_lambda_literal ref, - int index: int ref, - unique int child: @swift_lambda_literal_child_type ref -); - -swift_lambda_literal_def( - unique int id: @swift_lambda_literal -); - -swift_lambda_parameter_external_name( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int external_name: @swift_token_simple_identifier ref -); - -swift_lambda_parameter_name( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int name: @swift_token_simple_identifier ref -); - -@swift_lambda_parameter_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_lambda_parameter_type( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int type__: @swift_lambda_parameter_type_type ref -); - -@swift_lambda_parameter_child_type = @swift_parameter_modifiers | @swift_token_self_expression - -swift_lambda_parameter_child( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int child: @swift_lambda_parameter_child_type ref -); - -swift_lambda_parameter_def( - unique int id: @swift_lambda_parameter -); - -#keyset[swift_line_string_literal, index] -swift_line_string_literal_interpolation( - int swift_line_string_literal: @swift_line_string_literal ref, - int index: int ref, - unique int interpolation: @swift_interpolated_expression ref -); - -@swift_line_string_literal_text_type = @swift_token_line_str_text | @swift_token_str_escaped_char - -#keyset[swift_line_string_literal, index] -swift_line_string_literal_text( - int swift_line_string_literal: @swift_line_string_literal ref, - int index: int ref, - unique int text: @swift_line_string_literal_text_type ref -); - -swift_line_string_literal_def( - unique int id: @swift_line_string_literal -); - -@swift_local_declaration = @swift_class_declaration | @swift_function_declaration | @swift_property_declaration | @swift_typealias_declaration - -#keyset[swift_macro_declaration, index] -swift_macro_declaration_default_value( - int swift_macro_declaration: @swift_macro_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -swift_macro_declaration_definition( - unique int swift_macro_declaration: @swift_macro_declaration ref, - unique int definition: @swift_macro_definition ref -); - -@swift_macro_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_token_simple_identifier | @swift_type_constraints | @swift_type_parameters | @swift_unannotated_type - -#keyset[swift_macro_declaration, index] -swift_macro_declaration_child( - int swift_macro_declaration: @swift_macro_declaration ref, - int index: int ref, - unique int child: @swift_macro_declaration_child_type ref -); - -swift_macro_declaration_def( - unique int id: @swift_macro_declaration -); - -@swift_macro_definition_body_type = @swift_expression | @swift_external_macro_definition - -swift_macro_definition_def( - unique int id: @swift_macro_definition, - int body: @swift_macro_definition_body_type ref -); - -@swift_macro_invocation_child_type = @swift_call_suffix | @swift_token_simple_identifier | @swift_type_parameters - -#keyset[swift_macro_invocation, index] -swift_macro_invocation_child( - int swift_macro_invocation: @swift_macro_invocation ref, - int index: int ref, - unique int child: @swift_macro_invocation_child_type ref -); - -swift_macro_invocation_def( - unique int id: @swift_macro_invocation -); - -swift_metatype_def( - unique int id: @swift_metatype, - int child: @swift_unannotated_type ref -); - -@swift_modifiers_child_type = @swift_attribute | @swift_token_function_modifier | @swift_token_inheritance_modifier | @swift_token_member_modifier | @swift_token_mutation_modifier | @swift_token_ownership_modifier | @swift_token_parameter_modifier | @swift_token_property_behavior_modifier | @swift_token_property_modifier | @swift_token_visibility_modifier - -#keyset[swift_modifiers, index] -swift_modifiers_child( - int swift_modifiers: @swift_modifiers ref, - int index: int ref, - unique int child: @swift_modifiers_child_type ref -); - -swift_modifiers_def( - unique int id: @swift_modifiers -); - -swift_modify_specifier_child( - unique int swift_modify_specifier: @swift_modify_specifier ref, - unique int child: @swift_token_mutation_modifier ref -); - -swift_modify_specifier_def( - unique int id: @swift_modify_specifier -); - -#keyset[swift_multi_line_string_literal, index] -swift_multi_line_string_literal_interpolation( - int swift_multi_line_string_literal: @swift_multi_line_string_literal ref, - int index: int ref, - unique int interpolation: @swift_interpolated_expression ref -); - -@swift_multi_line_string_literal_text_type = @swift_reserved_word | @swift_token_multi_line_str_text | @swift_token_str_escaped_char - -#keyset[swift_multi_line_string_literal, index] -swift_multi_line_string_literal_text( - int swift_multi_line_string_literal: @swift_multi_line_string_literal ref, - int index: int ref, - unique int text: @swift_multi_line_string_literal_text_type ref -); - -swift_multi_line_string_literal_def( - unique int id: @swift_multi_line_string_literal -); - -case @swift_multiplicative_expression.op of - 0 = @swift_multiplicative_expression_percent -| 1 = @swift_multiplicative_expression_star -| 2 = @swift_multiplicative_expression_slash -; - - -swift_multiplicative_expression_def( - unique int id: @swift_multiplicative_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_navigation_expression_target_type = @swift_array_type | @swift_dictionary_type | @swift_existential_type | @swift_expression | @swift_opaque_type | @swift_reserved_word | @swift_user_type - -#keyset[swift_navigation_expression, index] -swift_navigation_expression_target( - int swift_navigation_expression: @swift_navigation_expression ref, - int index: int ref, - unique int target: @swift_navigation_expression_target_type ref -); - -swift_navigation_expression_def( - unique int id: @swift_navigation_expression, - int suffix: @swift_navigation_suffix ref -); - -@swift_navigation_suffix_suffix_type = @swift_token_integer_literal | @swift_token_simple_identifier - -swift_navigation_suffix_def( - unique int id: @swift_navigation_suffix, - int suffix: @swift_navigation_suffix_suffix_type ref -); - -@swift_nested_type_identifier_child_type = @swift_token_simple_identifier | @swift_unannotated_type - -#keyset[swift_nested_type_identifier, index] -swift_nested_type_identifier_child( - int swift_nested_type_identifier: @swift_nested_type_identifier ref, - int index: int ref, - unique int child: @swift_nested_type_identifier_child_type ref -); - -swift_nested_type_identifier_def( - unique int id: @swift_nested_type_identifier -); - -swift_nil_coalescing_expression_def( - unique int id: @swift_nil_coalescing_expression, - int if_nil: @swift_expression ref, - int value: @swift_expression ref -); - -swift_opaque_type_def( - unique int id: @swift_opaque_type, - int child: @swift_unannotated_type ref -); - -swift_open_end_range_expression_def( - unique int id: @swift_open_end_range_expression, - int start: @swift_expression ref -); - -swift_open_start_range_expression_def( - unique int id: @swift_open_start_range_expression, - int end: @swift_expression ref -); - -@swift_operator_declaration_child_type = @swift_deprecated_operator_declaration_body | @swift_referenceable_operator | @swift_token_simple_identifier - -#keyset[swift_operator_declaration, index] -swift_operator_declaration_child( - int swift_operator_declaration: @swift_operator_declaration ref, - int index: int ref, - unique int child: @swift_operator_declaration_child_type ref -); - -swift_operator_declaration_def( - unique int id: @swift_operator_declaration -); - -swift_optional_chain_marker_def( - unique int id: @swift_optional_chain_marker, - int child: @swift_expression ref -); - -@swift_optional_type_wrapped_type = @swift_array_type | @swift_dictionary_type | @swift_tuple_type | @swift_user_type - -swift_optional_type_def( - unique int id: @swift_optional_type, - int wrapped: @swift_optional_type_wrapped_type ref -); - -swift_parameter_external_name( - unique int swift_parameter: @swift_parameter ref, - unique int external_name: @swift_token_simple_identifier ref -); - -@swift_parameter_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_parameter_child( - unique int swift_parameter: @swift_parameter ref, - unique int child: @swift_parameter_modifiers ref -); - -swift_parameter_def( - unique int id: @swift_parameter, - int name: @swift_token_simple_identifier ref, - int type__: @swift_parameter_type_type ref -); - -#keyset[swift_parameter_modifiers, index] -swift_parameter_modifiers_child( - int swift_parameter_modifiers: @swift_parameter_modifiers ref, - int index: int ref, - unique int child: @swift_token_parameter_modifier ref -); - -swift_parameter_modifiers_def( - unique int id: @swift_parameter_modifiers -); - -swift_pattern_bound_identifier( - unique int swift_pattern: @swift_pattern ref, - unique int bound_identifier: @swift_token_simple_identifier ref -); - -@swift_pattern_child_type = @swift_expression | @swift_pattern | @swift_token_wildcard_pattern | @swift_type__ | @swift_user_type | @swift_value_binding_pattern - -#keyset[swift_pattern, index] -swift_pattern_child( - int swift_pattern: @swift_pattern ref, - int index: int ref, - unique int child: @swift_pattern_child_type ref -); - -swift_pattern_def( - unique int id: @swift_pattern -); - -#keyset[swift_playground_literal, index] -swift_playground_literal_child( - int swift_playground_literal: @swift_playground_literal ref, - int index: int ref, - unique int child: @swift_expression ref -); - -swift_playground_literal_def( - unique int id: @swift_playground_literal -); - -@swift_postfix_expression_operation_type = @swift_reserved_word | @swift_token_bang - -swift_postfix_expression_def( - unique int id: @swift_postfix_expression, - int operation: @swift_postfix_expression_operation_type ref, - int target: @swift_expression ref -); - -@swift_precedence_group_attribute_child_type = @swift_token_boolean_literal | @swift_token_simple_identifier - -#keyset[swift_precedence_group_attribute, index] -swift_precedence_group_attribute_child( - int swift_precedence_group_attribute: @swift_precedence_group_attribute ref, - int index: int ref, - unique int child: @swift_precedence_group_attribute_child_type ref -); - -swift_precedence_group_attribute_def( - unique int id: @swift_precedence_group_attribute -); - -#keyset[swift_precedence_group_attributes, index] -swift_precedence_group_attributes_child( - int swift_precedence_group_attributes: @swift_precedence_group_attributes ref, - int index: int ref, - unique int child: @swift_precedence_group_attribute ref -); - -swift_precedence_group_attributes_def( - unique int id: @swift_precedence_group_attributes -); - -@swift_precedence_group_declaration_child_type = @swift_precedence_group_attributes | @swift_token_simple_identifier - -#keyset[swift_precedence_group_declaration, index] -swift_precedence_group_declaration_child( - int swift_precedence_group_declaration: @swift_precedence_group_declaration ref, - int index: int ref, - unique int child: @swift_precedence_group_declaration_child_type ref -); - -swift_precedence_group_declaration_def( - unique int id: @swift_precedence_group_declaration -); - -@swift_prefix_expression_operation_type = @swift_reserved_word | @swift_token_bang | @swift_token_custom_operator - -swift_prefix_expression_def( - unique int id: @swift_prefix_expression, - int operation: @swift_prefix_expression_operation_type ref, - int target: @swift_expression ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_computed_value( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int computed_value: @swift_computed_property ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_name( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int name: @swift_pattern ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_value( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int value: @swift_expression ref -); - -@swift_property_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_type_annotation | @swift_type_constraints | @swift_value_binding_pattern | @swift_willset_didset_block - -#keyset[swift_property_declaration, index] -swift_property_declaration_child( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int child: @swift_property_declaration_child_type ref -); - -swift_property_declaration_def( - unique int id: @swift_property_declaration -); - -#keyset[swift_protocol_body, index] -swift_protocol_body_child( - int swift_protocol_body: @swift_protocol_body ref, - int index: int ref, - unique int child: @swift_protocol_member_declaration ref -); - -swift_protocol_body_def( - unique int id: @swift_protocol_body -); - -#keyset[swift_protocol_composition_type, index] -swift_protocol_composition_type_child( - int swift_protocol_composition_type: @swift_protocol_composition_type ref, - int index: int ref, - unique int child: @swift_unannotated_type ref -); - -swift_protocol_composition_type_def( - unique int id: @swift_protocol_composition_type -); - -case @swift_protocol_declaration.declaration_kind of - 0 = @swift_protocol_declaration_protocol -; - - -@swift_protocol_declaration_child_type = @swift_attribute | @swift_inheritance_specifier | @swift_modifiers | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_protocol_declaration, index] -swift_protocol_declaration_child( - int swift_protocol_declaration: @swift_protocol_declaration ref, - int index: int ref, - unique int child: @swift_protocol_declaration_child_type ref -); - -swift_protocol_declaration_def( - unique int id: @swift_protocol_declaration, - int body: @swift_protocol_body ref, - int declaration_kind: int ref, - int name: @swift_token_type_identifier ref -); - -swift_protocol_function_declaration_body( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int body: @swift_function_body ref -); - -#keyset[swift_protocol_function_declaration, index] -swift_protocol_function_declaration_default_value( - int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -@swift_protocol_function_declaration_name_type = @swift_referenceable_operator | @swift_token_simple_identifier - -@swift_protocol_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_protocol_function_declaration_return_type( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int return_type: @swift_protocol_function_declaration_return_type_type ref -); - -@swift_protocol_function_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_parameter | @swift_throws_clause | @swift_token_throws | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_protocol_function_declaration, index] -swift_protocol_function_declaration_child( - int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - int index: int ref, - unique int child: @swift_protocol_function_declaration_child_type ref -); - -swift_protocol_function_declaration_def( - unique int id: @swift_protocol_function_declaration, - int name: @swift_protocol_function_declaration_name_type ref -); - -@swift_protocol_member_declaration = @swift_associatedtype_declaration | @swift_deinit_declaration | @swift_init_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_subscript_declaration | @swift_typealias_declaration - -@swift_protocol_property_declaration_child_type = @swift_modifiers | @swift_protocol_property_requirements | @swift_type_annotation | @swift_type_constraints - -#keyset[swift_protocol_property_declaration, index] -swift_protocol_property_declaration_child( - int swift_protocol_property_declaration: @swift_protocol_property_declaration ref, - int index: int ref, - unique int child: @swift_protocol_property_declaration_child_type ref -); - -swift_protocol_property_declaration_def( - unique int id: @swift_protocol_property_declaration, - int name: @swift_pattern ref -); - -@swift_protocol_property_requirements_child_type = @swift_getter_specifier | @swift_setter_specifier - -#keyset[swift_protocol_property_requirements, index] -swift_protocol_property_requirements_child( - int swift_protocol_property_requirements: @swift_protocol_property_requirements ref, - int index: int ref, - unique int child: @swift_protocol_property_requirements_child_type ref -); - -swift_protocol_property_requirements_def( - unique int id: @swift_protocol_property_requirements -); - -case @swift_range_expression.op of - 0 = @swift_range_expression_dotdotdot -| 1 = @swift_range_expression_dotdotlangle -; - - -swift_range_expression_def( - unique int id: @swift_range_expression, - int end: @swift_expression ref, - int op: int ref, - int start: @swift_expression ref -); - -#keyset[swift_raw_str_interpolation, index] -swift_raw_str_interpolation_interpolation( - int swift_raw_str_interpolation: @swift_raw_str_interpolation ref, - int index: int ref, - unique int interpolation: @swift_interpolated_expression ref -); - -swift_raw_str_interpolation_def( - unique int id: @swift_raw_str_interpolation, - int child: @swift_token_raw_str_interpolation_start ref -); - -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_interpolation( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int interpolation: @swift_raw_str_interpolation ref -); - -@swift_raw_string_literal_text_type = @swift_token_raw_str_end_part | @swift_token_raw_str_part - -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_text( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int text: @swift_raw_string_literal_text_type ref -); - -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_child( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int child: @swift_token_raw_str_continuing_indicator ref -); - -swift_raw_string_literal_def( - unique int id: @swift_raw_string_literal -); - -@swift_referenceable_operator_child_type = @swift_token_bang | @swift_token_custom_operator - -swift_referenceable_operator_child( - unique int swift_referenceable_operator: @swift_referenceable_operator ref, - unique int child: @swift_referenceable_operator_child_type ref -); - -swift_referenceable_operator_def( - unique int id: @swift_referenceable_operator -); - -#keyset[swift_repeat_while_statement, index] -swift_repeat_while_statement_condition( - int swift_repeat_while_statement: @swift_repeat_while_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -swift_repeat_while_statement_child( - unique int swift_repeat_while_statement: @swift_repeat_while_statement ref, - unique int child: @swift_statements ref -); - -swift_repeat_while_statement_def( - unique int id: @swift_repeat_while_statement -); - -swift_selector_expression_def( - unique int id: @swift_selector_expression, - int child: @swift_expression ref -); - -swift_setter_specifier_child( - unique int swift_setter_specifier: @swift_setter_specifier ref, - unique int child: @swift_token_mutation_modifier ref -); - -swift_setter_specifier_def( - unique int id: @swift_setter_specifier -); - -@swift_source_file_child_type = @swift_do_statement | @swift_expression | @swift_for_statement | @swift_global_declaration | @swift_guard_statement | @swift_repeat_while_statement | @swift_token_shebang_line | @swift_token_statement_label | @swift_token_throw_keyword | @swift_while_statement - -#keyset[swift_source_file, index] -swift_source_file_child( - int swift_source_file: @swift_source_file ref, - int index: int ref, - unique int child: @swift_source_file_child_type ref -); - -swift_source_file_def( - unique int id: @swift_source_file -); - -@swift_statements_child_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement - -#keyset[swift_statements, index] -swift_statements_child( - int swift_statements: @swift_statements ref, - int index: int ref, - unique int child: @swift_statements_child_type ref -); - -swift_statements_def( - unique int id: @swift_statements -); - -#keyset[swift_subscript_declaration, index] -swift_subscript_declaration_default_value( - int swift_subscript_declaration: @swift_subscript_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - -@swift_subscript_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_subscript_declaration_return_type( - unique int swift_subscript_declaration: @swift_subscript_declaration ref, - unique int return_type: @swift_subscript_declaration_return_type_type ref -); - -@swift_subscript_declaration_child_type = @swift_attribute | @swift_computed_property | @swift_modifiers | @swift_parameter | @swift_type_constraints | @swift_type_parameters - -#keyset[swift_subscript_declaration, index] -swift_subscript_declaration_child( - int swift_subscript_declaration: @swift_subscript_declaration ref, - int index: int ref, - unique int child: @swift_subscript_declaration_child_type ref -); - -swift_subscript_declaration_def( - unique int id: @swift_subscript_declaration -); - -swift_suppressed_constraint_def( - unique int id: @swift_suppressed_constraint, - int suppressed: @swift_token_type_identifier ref -); - -@swift_switch_entry_child_type = @swift_expression | @swift_modifiers | @swift_statements | @swift_switch_pattern | @swift_token_default_keyword | @swift_token_where_keyword - -#keyset[swift_switch_entry, index] -swift_switch_entry_child( - int swift_switch_entry: @swift_switch_entry ref, - int index: int ref, - unique int child: @swift_switch_entry_child_type ref -); - -swift_switch_entry_def( - unique int id: @swift_switch_entry -); - -swift_switch_pattern_def( - unique int id: @swift_switch_pattern, - int child: @swift_pattern ref -); - -#keyset[swift_switch_statement, index] -swift_switch_statement_child( - int swift_switch_statement: @swift_switch_statement ref, - int index: int ref, - unique int child: @swift_switch_entry ref -); - -swift_switch_statement_def( - unique int id: @swift_switch_statement, - int expr: @swift_expression ref -); - -swift_ternary_expression_def( - unique int id: @swift_ternary_expression, - int condition: @swift_expression ref, - int if_false: @swift_expression ref, - int if_true: @swift_expression ref -); - -swift_throws_clause_def( - unique int id: @swift_throws_clause, - int type__: @swift_unannotated_type ref -); - -swift_try_expression_def( - unique int id: @swift_try_expression, - int expr: @swift_expression ref, - int child: @swift_token_try_operator ref -); - -#keyset[swift_tuple_expression, index] -swift_tuple_expression_name( - int swift_tuple_expression: @swift_tuple_expression ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -#keyset[swift_tuple_expression, index] -swift_tuple_expression_value( - int swift_tuple_expression: @swift_tuple_expression ref, - int index: int ref, - unique int value: @swift_expression ref -); - -swift_tuple_expression_def( - unique int id: @swift_tuple_expression -); - -#keyset[swift_tuple_type, index] -swift_tuple_type_element( - int swift_tuple_type: @swift_tuple_type ref, - int index: int ref, - unique int element: @swift_tuple_type_item ref -); - -swift_tuple_type_child( - unique int swift_tuple_type: @swift_tuple_type ref, - unique int child: @swift_tuple_type_item ref -); - -swift_tuple_type_def( - unique int id: @swift_tuple_type -); - -swift_tuple_type_item_name( - unique int swift_tuple_type_item: @swift_tuple_type_item ref, - unique int name: @swift_token_simple_identifier ref -); - -swift_tuple_type_item_type( - unique int swift_tuple_type_item: @swift_tuple_type_item ref, - unique int type__: @swift_type__ ref -); - -@swift_tuple_type_item_child_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type | @swift_parameter_modifiers | @swift_token_wildcard_pattern - -#keyset[swift_tuple_type_item, index] -swift_tuple_type_item_child( - int swift_tuple_type_item: @swift_tuple_type_item ref, - int index: int ref, - unique int child: @swift_tuple_type_item_child_type ref -); - -swift_tuple_type_item_def( - unique int id: @swift_tuple_type_item -); - -swift_type_modifiers( - unique int swift_type__: @swift_type__ ref, - unique int modifiers: @swift_type_modifiers ref -); - -swift_type_def( - unique int id: @swift_type__, - int name: @swift_unannotated_type ref -); - -@swift_type_annotation_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_type_annotation_def( - unique int id: @swift_type_annotation, - int type__: @swift_type_annotation_type_type ref -); - -#keyset[swift_type_arguments, index] -swift_type_arguments_child( - int swift_type_arguments: @swift_type_arguments ref, - int index: int ref, - unique int child: @swift_type__ ref -); - -swift_type_arguments_def( - unique int id: @swift_type_arguments -); - -@swift_type_constraint_child_type = @swift_equality_constraint | @swift_inheritance_constraint - -swift_type_constraint_def( - unique int id: @swift_type_constraint, - int child: @swift_type_constraint_child_type ref -); - -@swift_type_constraints_child_type = @swift_token_where_keyword | @swift_type_constraint - -#keyset[swift_type_constraints, index] -swift_type_constraints_child( - int swift_type_constraints: @swift_type_constraints ref, - int index: int ref, - unique int child: @swift_type_constraints_child_type ref -); - -swift_type_constraints_def( - unique int id: @swift_type_constraints -); - -@swift_type_level_declaration = @swift_associatedtype_declaration | @swift_class_declaration | @swift_deinit_declaration | @swift_function_declaration | @swift_import_declaration | @swift_init_declaration | @swift_operator_declaration | @swift_precedence_group_declaration | @swift_property_declaration | @swift_protocol_declaration | @swift_subscript_declaration | @swift_typealias_declaration - -#keyset[swift_type_modifiers, index] -swift_type_modifiers_child( - int swift_type_modifiers: @swift_type_modifiers ref, - int index: int ref, - unique int child: @swift_attribute ref -); - -swift_type_modifiers_def( - unique int id: @swift_type_modifiers -); - -swift_type_pack_expansion_def( - unique int id: @swift_type_pack_expansion, - int child: @swift_unannotated_type ref -); - -@swift_type_parameter_child_type = @swift_token_type_identifier | @swift_type__ | @swift_type_parameter_modifiers | @swift_type_parameter_pack - -#keyset[swift_type_parameter, index] -swift_type_parameter_child( - int swift_type_parameter: @swift_type_parameter ref, - int index: int ref, - unique int child: @swift_type_parameter_child_type ref -); - -swift_type_parameter_def( - unique int id: @swift_type_parameter -); - -#keyset[swift_type_parameter_modifiers, index] -swift_type_parameter_modifiers_child( - int swift_type_parameter_modifiers: @swift_type_parameter_modifiers ref, - int index: int ref, - unique int child: @swift_attribute ref -); - -swift_type_parameter_modifiers_def( - unique int id: @swift_type_parameter_modifiers -); - -swift_type_parameter_pack_def( - unique int id: @swift_type_parameter_pack, - int child: @swift_unannotated_type ref -); - -@swift_type_parameters_child_type = @swift_type_constraints | @swift_type_parameter - -#keyset[swift_type_parameters, index] -swift_type_parameters_child( - int swift_type_parameters: @swift_type_parameters ref, - int index: int ref, - unique int child: @swift_type_parameters_child_type ref -); - -swift_type_parameters_def( - unique int id: @swift_type_parameters -); - -@swift_typealias_declaration_child_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier | @swift_type_parameters - -#keyset[swift_typealias_declaration, index] -swift_typealias_declaration_child( - int swift_typealias_declaration: @swift_typealias_declaration ref, - int index: int ref, - unique int child: @swift_typealias_declaration_child_type ref -); - -swift_typealias_declaration_def( - unique int id: @swift_typealias_declaration, - int name: @swift_token_type_identifier ref, - int value: @swift_type__ ref -); - -@swift_unannotated_type = @swift_array_type | @swift_dictionary_type | @swift_existential_type | @swift_function_type | @swift_metatype | @swift_opaque_type | @swift_optional_type | @swift_protocol_composition_type | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type - -@swift_user_type_child_type = @swift_token_type_identifier | @swift_type_arguments - -#keyset[swift_user_type, index] -swift_user_type_child( - int swift_user_type: @swift_user_type ref, - int index: int ref, - unique int child: @swift_user_type_child_type ref -); - -swift_user_type_def( - unique int id: @swift_user_type -); - -swift_value_argument_name( - unique int swift_value_argument: @swift_value_argument ref, - unique int name: @swift_value_argument_label ref -); - -#keyset[swift_value_argument, index] -swift_value_argument_reference_specifier( - int swift_value_argument: @swift_value_argument ref, - int index: int ref, - unique int reference_specifier: @swift_value_argument_label ref -); - -swift_value_argument_value( - unique int swift_value_argument: @swift_value_argument ref, - unique int value: @swift_expression ref -); - -swift_value_argument_child( - unique int swift_value_argument: @swift_value_argument ref, - unique int child: @swift_type_modifiers ref -); - -swift_value_argument_def( - unique int id: @swift_value_argument -); - -swift_value_argument_label_def( - unique int id: @swift_value_argument_label, - int child: @swift_token_simple_identifier ref -); - -#keyset[swift_value_arguments, index] -swift_value_arguments_child( - int swift_value_arguments: @swift_value_arguments ref, - int index: int ref, - unique int child: @swift_value_argument ref -); - -swift_value_arguments_def( - unique int id: @swift_value_arguments -); - -case @swift_value_binding_pattern.mutability of - 0 = @swift_value_binding_pattern_let -| 1 = @swift_value_binding_pattern_var -; - - -swift_value_binding_pattern_def( - unique int id: @swift_value_binding_pattern, - int mutability: int ref -); - -swift_value_pack_expansion_def( - unique int id: @swift_value_pack_expansion, - int child: @swift_expression ref -); - -swift_value_parameter_pack_def( - unique int id: @swift_value_parameter_pack, - int child: @swift_expression ref -); - -@swift_where_clause_child_type = @swift_expression | @swift_token_where_keyword - -#keyset[swift_where_clause, index] -swift_where_clause_child( - int swift_where_clause: @swift_where_clause ref, - int index: int ref, - unique int child: @swift_where_clause_child_type ref -); - -swift_where_clause_def( - unique int id: @swift_where_clause -); - -#keyset[swift_while_statement, index] -swift_while_statement_condition( - int swift_while_statement: @swift_while_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -swift_while_statement_child( - unique int swift_while_statement: @swift_while_statement ref, - unique int child: @swift_statements ref -); - -swift_while_statement_def( - unique int id: @swift_while_statement -); - -@swift_willset_clause_child_type = @swift_modifiers | @swift_statements | @swift_token_simple_identifier - -#keyset[swift_willset_clause, index] -swift_willset_clause_child( - int swift_willset_clause: @swift_willset_clause ref, - int index: int ref, - unique int child: @swift_willset_clause_child_type ref -); - -swift_willset_clause_def( - unique int id: @swift_willset_clause -); - -@swift_willset_didset_block_child_type = @swift_didset_clause | @swift_willset_clause - -#keyset[swift_willset_didset_block, index] -swift_willset_didset_block_child( - int swift_willset_didset_block: @swift_willset_didset_block ref, - int index: int ref, - unique int child: @swift_willset_didset_block_child_type ref -======= /*- Unified dbscheme -*/ +#keyset[unified_apply_pattern, index] +unified_apply_pattern_argument( + int unified_apply_pattern: @unified_apply_pattern ref, + int index: int ref, + unique int argument: @unified_pattern ref +); + +unified_apply_pattern_def( + unique int id: @unified_apply_pattern, + int constructor: @unified_expr ref +); + unified_binary_expr_def( unique int id: @unified_binary_expr, int left: @unified_expr ref, - int operator: @unified_token_binary_operator ref, + int operator: @unified_token_operator ref, int right: @unified_expr ref ); -@unified_expr = @unified_binary_expr | @unified_token_name_expr | @unified_token_unsupported_node +#keyset[unified_block_stmt, index] +unified_block_stmt_body( + int unified_block_stmt: @unified_block_stmt ref, + int index: int ref, + unique int body: @unified_stmt ref +); + +unified_block_stmt_def( + unique int id: @unified_block_stmt +); + +#keyset[unified_call_expr, index] +unified_call_expr_argument( + int unified_call_expr: @unified_call_expr ref, + int index: int ref, + unique int argument: @unified_expr ref +); + +unified_call_expr_def( + unique int id: @unified_call_expr, + int function: @unified_expr ref +); + +@unified_condition = @unified_expr_condition | @unified_let_pattern_condition | @unified_sequence_condition | @unified_token_unsupported_node + +@unified_expr = @unified_binary_expr | @unified_call_expr | @unified_lambda_expr | @unified_member_access_expr | @unified_name_expr | @unified_token_int_literal | @unified_token_string_literal | @unified_token_unsupported_node | @unified_unary_expr + +unified_expr_condition_def( + unique int id: @unified_expr_condition, + int expr: @unified_expr ref +); + +unified_expr_stmt_def( + unique int id: @unified_expr_stmt, + int expr: @unified_expr ref +); + +unified_guard_if_stmt_def( + unique int id: @unified_guard_if_stmt, + int condition: @unified_condition ref, + int else: @unified_stmt ref +); + +unified_if_stmt_else( + unique int unified_if_stmt: @unified_if_stmt ref, + unique int else: @unified_stmt ref +); + +unified_if_stmt_then( + unique int unified_if_stmt: @unified_if_stmt ref, + unique int then: @unified_stmt ref +); + +unified_if_stmt_def( + unique int id: @unified_if_stmt, + int condition: @unified_condition ref +); + +@unified_lambda_expr_body_type = @unified_expr | @unified_stmt + +#keyset[unified_lambda_expr, index] +unified_lambda_expr_parameter( + int unified_lambda_expr: @unified_lambda_expr ref, + int index: int ref, + unique int parameter: @unified_parameter ref +); + +unified_lambda_expr_def( + unique int id: @unified_lambda_expr, + int body: @unified_lambda_expr_body_type ref +); + +unified_let_pattern_condition_def( + unique int id: @unified_let_pattern_condition, + int pattern: @unified_pattern ref, + int value: @unified_expr ref +); + +unified_member_access_expr_def( + unique int id: @unified_member_access_expr, + int member: @unified_token_identifier ref, + int target: @unified_expr ref +); + +unified_name_expr_def( + unique int id: @unified_name_expr, + int identifier: @unified_token_identifier ref +); + +unified_parameter_def( + unique int id: @unified_parameter, + int pattern: @unified_pattern ref +); + +@unified_pattern = @unified_apply_pattern | @unified_token_ignore_pattern | @unified_token_unsupported_node | @unified_tuple_pattern | @unified_var_pattern + +#keyset[unified_sequence_condition, index] +unified_sequence_condition_stmt( + int unified_sequence_condition: @unified_sequence_condition ref, + int index: int ref, + unique int stmt: @unified_stmt ref +); + +unified_sequence_condition_def( + unique int id: @unified_sequence_condition, + int condition: @unified_condition ref +); + +@unified_stmt = @unified_block_stmt | @unified_expr_stmt | @unified_guard_if_stmt | @unified_if_stmt | @unified_token_empty_stmt | @unified_token_unsupported_node | @unified_variable_declaration_stmt + +@unified_top_level_body_type = @unified_expr | @unified_stmt #keyset[unified_top_level, index] unified_top_level_body( int unified_top_level: @unified_top_level ref, int index: int ref, - unique int body: @unified_expr ref + unique int body: @unified_top_level_body_type ref ); unified_top_level_def( unique int id: @unified_top_level ->>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) +); + +#keyset[unified_tuple_pattern, index] +unified_tuple_pattern_element( + int unified_tuple_pattern: @unified_tuple_pattern ref, + int index: int ref, + unique int element: @unified_pattern ref +); + +unified_tuple_pattern_def( + unique int id: @unified_tuple_pattern ); unified_unary_expr_def( unique int id: @unified_unary_expr, int operand: @unified_expr ref, - int operator: @unified_token_unary_operator ref + int operator: @unified_token_operator ref +); + +unified_var_pattern_def( + unique int id: @unified_var_pattern, + int identifier: @unified_token_identifier ref +); + +#keyset[unified_variable_declaration_stmt, index] +unified_variable_declaration_stmt_variable_declarator( + int unified_variable_declaration_stmt: @unified_variable_declaration_stmt ref, + int index: int ref, + unique int variable_declarator: @unified_variable_declarator ref +); + +unified_variable_declaration_stmt_def( + unique int id: @unified_variable_declaration_stmt +); + +unified_variable_declarator_value( + unique int unified_variable_declarator: @unified_variable_declarator ref, + unique int value: @unified_expr ref +); + +unified_variable_declarator_def( + unique int id: @unified_variable_declarator, + int pattern: @unified_pattern ref ); unified_tokeninfo( @@ -2091,69 +323,18 @@ unified_tokeninfo( string value: string ref ); -<<<<<<< HEAD -case @swift_token.kind of - 0 = @swift_reserved_word -| 1 = @swift_token_as_operator -| 2 = @swift_token_bang -| 3 = @swift_token_bin_literal -| 4 = @swift_token_boolean_literal -| 5 = @swift_token_catch_keyword -| 6 = @swift_token_comment -| 7 = @swift_token_custom_operator -| 8 = @swift_token_default_keyword -| 9 = @swift_token_diagnostic -| 10 = @swift_token_else -| 11 = @swift_token_fully_open_range -| 12 = @swift_token_function_modifier -| 13 = @swift_token_hex_literal -| 14 = @swift_token_inheritance_modifier -| 15 = @swift_token_integer_literal -| 16 = @swift_token_line_str_text -| 17 = @swift_token_member_modifier -| 18 = @swift_token_multi_line_str_text -| 19 = @swift_token_multiline_comment -| 20 = @swift_token_mutation_modifier -| 21 = @swift_token_oct_literal -| 22 = @swift_token_ownership_modifier -| 23 = @swift_token_parameter_modifier -| 24 = @swift_token_property_behavior_modifier -| 25 = @swift_token_property_modifier -| 26 = @swift_token_raw_str_continuing_indicator -| 27 = @swift_token_raw_str_end_part -| 28 = @swift_token_raw_str_interpolation_start -| 29 = @swift_token_raw_str_part -| 30 = @swift_token_real_literal -| 31 = @swift_token_regex_literal -| 32 = @swift_token_self_expression -| 33 = @swift_token_shebang_line -| 34 = @swift_token_simple_identifier -| 35 = @swift_token_special_literal -| 36 = @swift_token_statement_label -| 37 = @swift_token_str_escaped_char -| 38 = @swift_token_super_expression -| 39 = @swift_token_throw_keyword -| 40 = @swift_token_throws -| 41 = @swift_token_try_operator -| 42 = @swift_token_type_identifier -| 43 = @swift_token_visibility_modifier -| 44 = @swift_token_where_keyword -| 45 = @swift_token_wildcard_pattern -; - - -@swift_ast_node = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_associatedtype_declaration | @swift_attribute | @swift_availability_condition | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_call_suffix | @swift_capture_list | @swift_capture_list_item | @swift_catch_block | @swift_check_expression | @swift_class_body | @swift_class_declaration | @swift_comparison_expression | @swift_computed_getter | @swift_computed_modify | @swift_computed_property | @swift_computed_setter | @swift_conjunction_expression | @swift_constructor_expression | @swift_constructor_suffix | @swift_control_transfer_statement | @swift_deinit_declaration | @swift_deprecated_operator_declaration_body | @swift_dictionary_literal | @swift_dictionary_type | @swift_didset_clause | @swift_directive | @swift_directly_assignable_expression | @swift_disjunction_expression | @swift_do_statement | @swift_enum_class_body | @swift_enum_entry | @swift_enum_type_parameters | @swift_equality_constraint | @swift_equality_expression | @swift_existential_type | @swift_external_macro_definition | @swift_for_statement | @swift_function_body | @swift_function_declaration | @swift_function_type | @swift_getter_specifier | @swift_guard_statement | @swift_identifier | @swift_if_condition | @swift_if_let_binding | @swift_if_statement | @swift_implicitly_unwrapped_type | @swift_import_declaration | @swift_infix_expression | @swift_inheritance_constraint | @swift_inheritance_specifier | @swift_init_declaration | @swift_interpolated_expression | @swift_key_path_expression | @swift_key_path_string_expression | @swift_lambda_function_type | @swift_lambda_function_type_parameters | @swift_lambda_literal | @swift_lambda_parameter | @swift_line_string_literal | @swift_macro_declaration | @swift_macro_definition | @swift_macro_invocation | @swift_metatype | @swift_modifiers | @swift_modify_specifier | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_navigation_suffix | @swift_nested_type_identifier | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_operator_declaration | @swift_optional_chain_marker | @swift_optional_type | @swift_parameter | @swift_parameter_modifiers | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_precedence_group_attribute | @swift_precedence_group_attributes | @swift_precedence_group_declaration | @swift_prefix_expression | @swift_property_declaration | @swift_protocol_body | @swift_protocol_composition_type | @swift_protocol_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_protocol_property_requirements | @swift_range_expression | @swift_raw_str_interpolation | @swift_raw_string_literal | @swift_referenceable_operator | @swift_repeat_while_statement | @swift_selector_expression | @swift_setter_specifier | @swift_source_file | @swift_statements | @swift_subscript_declaration | @swift_suppressed_constraint | @swift_switch_entry | @swift_switch_pattern | @swift_switch_statement | @swift_ternary_expression | @swift_throws_clause | @swift_token | @swift_try_expression | @swift_tuple_expression | @swift_tuple_type | @swift_tuple_type_item | @swift_type__ | @swift_type_annotation | @swift_type_arguments | @swift_type_constraint | @swift_type_constraints | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter | @swift_type_parameter_modifiers | @swift_type_parameter_pack | @swift_type_parameters | @swift_typealias_declaration | @swift_user_type | @swift_value_argument | @swift_value_argument_label | @swift_value_arguments | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause | @swift_while_statement | @swift_willset_clause | @swift_willset_didset_block -======= case @unified_token.kind of - 1 = @unified_token_binary_operator -| 2 = @unified_token_name_expr -| 3 = @unified_token_unary_operator -| 4 = @unified_token_unsupported_node + 1 = @unified_token_empty_stmt +| 2 = @unified_token_identifier +| 3 = @unified_token_ignore_pattern +| 4 = @unified_token_int_literal +| 5 = @unified_token_operator +| 6 = @unified_token_string_literal +| 7 = @unified_token_unsupported_node ; -@unified_ast_node = @unified_binary_expr | @unified_token | @unified_top_level | @unified_unary_expr ->>>>>>> e92db5117d5 (Unified extractor: add AST schema, swift translation rules, and corpus framework) +@unified_ast_node = @unified_apply_pattern | @unified_binary_expr | @unified_block_stmt | @unified_call_expr | @unified_expr_condition | @unified_expr_stmt | @unified_guard_if_stmt | @unified_if_stmt | @unified_lambda_expr | @unified_let_pattern_condition | @unified_member_access_expr | @unified_name_expr | @unified_parameter | @unified_sequence_condition | @unified_token | @unified_top_level | @unified_tuple_pattern | @unified_unary_expr | @unified_var_pattern | @unified_variable_declaration_stmt | @unified_variable_declarator unified_ast_node_location( unique int node: @unified_ast_node ref, diff --git a/unified/ql/test/library-tests/BasicTest/name_expr.swift b/unified/ql/test/library-tests/BasicTest/name_expr.swift new file mode 100644 index 00000000000..613f3a62861 --- /dev/null +++ b/unified/ql/test/library-tests/BasicTest/name_expr.swift @@ -0,0 +1 @@ +var x = y + 2; diff --git a/unified/ql/test/library-tests/BasicTest/test.expected b/unified/ql/test/library-tests/BasicTest/test.expected index c36864e10d5..1d6bb8def2b 100644 --- a/unified/ql/test/library-tests/BasicTest/test.expected +++ b/unified/ql/test/library-tests/BasicTest/test.expected @@ -1,17 +1,18 @@ nameExpr +| name_expr.swift:1:9:1:9 | NameExpr | y | unsupported -| test.swift:1:1:1:17 | import Foundation | import Foundation | -| test.swift:3:1:3:38 | // Generic struct with type constraint | // Generic struct with type constraint | -| test.swift:4:1:14:1 | struct Container {\n var items: [T] = []\n\n mutating func add(_ item: T) {\n items.append(item)\n }\n\n func contains(_ item: T) -> Bool {\n return items.contains(item)\n }\n} | struct Container {\n var items: [T] = []\n\n mutating func add(_ item: T) {\n items.append(item)\n }\n\n func contains(_ item: T) -> Bool {\n return items.contains(item)\n }\n} | -| test.swift:16:1:16:32 | // Protocol with associated type | // Protocol with associated type | -| test.swift:17:1:21:1 | protocol DataSource {\n associatedtype Element\n var count: Int { get }\n func item(at index: Int) -> Element?\n} | protocol DataSource {\n associatedtype Element\n var count: Int { get }\n func item(at index: Int) -> Element?\n} | -| test.swift:23:1:23:37 | // Generic function with where clause | // Generic function with where clause | -| test.swift:24:1:32:1 | func merge(_ first: T, _ second: T) -> [T.Element] where T.Element: Equatable {\n var result = Array(first)\n for item in second {\n if !result.contains(item) {\n result.append(item)\n }\n }\n return result\n} | func merge(_ first: T, _ second: T) -> [T.Element] where T.Element: Equatable {\n var result = Array(first)\n for item in second {\n if !result.contains(item) {\n result.append(item)\n }\n }\n return result\n} | -| test.swift:34:1:34:49 | // Class with inheritance and computed properties | // Class with inheritance and computed properties | -| test.swift:35:1:55:1 | class DataManager: DataSource {\n typealias Element = T\n private var data: [T] = []\n\n var count: Int {\n return data.count\n }\n\n var isEmpty: Bool {\n data.isEmpty\n }\n\n func item(at index: Int) -> T? {\n guard index >= 0 && index < data.count else { return nil }\n return data[index]\n }\n\n func add(_ item: T) {\n data.append(item)\n }\n} | class DataManager: DataSource {\n typealias Element = T\n private var data: [T] = []\n\n var count: Int {\n return data.count\n }\n\n var isEmpty: Bool {\n data.isEmpty\n }\n\n func item(at index: Int) -> T? {\n guard index >= 0 && index < data.count else { return nil }\n return data[index]\n }\n\n func add(_ item: T) {\n data.append(item)\n }\n} | -| test.swift:57:1:57:30 | // Enum with associated values | // Enum with associated values | -| test.swift:58:1:70:1 | enum Result {\n case success(Success)\n case failure(Failure)\n\n func map(_ transform: (Success) -> U) -> Result {\n switch self {\n case .success(let value):\n return .success(transform(value))\n case .failure(let error):\n return .failure(error)\n }\n }\n} | enum Result {\n case success(Success)\n case failure(Failure)\n\n func map(_ transform: (Success) -> U) -> Result {\n switch self {\n case .success(let value):\n return .success(transform(value))\n case .failure(let error):\n return .failure(error)\n }\n }\n} | -| test.swift:72:1:72:37 | // Extension with generic constraints | // Extension with generic constraints | -| test.swift:73:1:82:1 | extension Array where Element: Comparable {\n func isSorted() -> Bool {\n for i in 0..<(count - 1) {\n if self[i] > self[i + 1] {\n return false\n }\n }\n return true\n }\n} | extension Array where Element: Comparable {\n func isSorted() -> Bool {\n for i in 0..<(count - 1) {\n if self[i] > self[i + 1] {\n return false\n }\n }\n return true\n }\n} | -| test.swift:84:1:84:24 | // Higher-order function | // Higher-order function | -| test.swift:85:1:88:1 | func combine(_ values: [T], transform: (T, T) -> T) -> T? {\n guard !values.isEmpty else { return nil }\n return values.dropFirst().reduce(values[0], transform)\n} | func combine(_ values: [T], transform: (T, T) -> T) -> T? {\n guard !values.isEmpty else { return nil }\n return values.dropFirst().reduce(values[0], transform)\n} | +| test.swift:1:1:1:17 | | | +| test.swift:3:1:3:38 | | | +| test.swift:4:1:14:1 | | | +| test.swift:16:1:16:32 | | | +| test.swift:17:1:21:1 | | | +| test.swift:23:1:23:37 | | | +| test.swift:24:1:32:1 | | | +| test.swift:34:1:34:49 | | | +| test.swift:35:1:55:1 | | | +| test.swift:57:1:57:30 | | | +| test.swift:58:1:70:1 | | | +| test.swift:72:1:72:37 | | | +| test.swift:73:1:82:1 | | | +| test.swift:84:1:84:24 | | | +| test.swift:85:1:88:1 | | | diff --git a/unified/ql/test/library-tests/BasicTest/test.ql b/unified/ql/test/library-tests/BasicTest/test.ql index 6fdd392cfd2..ca422d03978 100644 --- a/unified/ql/test/library-tests/BasicTest/test.ql +++ b/unified/ql/test/library-tests/BasicTest/test.ql @@ -1,5 +1,5 @@ import codeql.unified.Ast::Unified -query predicate nameExpr(NameExpr node, string value) { value = node.getValue() } +query predicate nameExpr(NameExpr node, string value) { value = node.getIdentifier().getValue() } query predicate unsupported(UnsupportedNode node, string value) { value = node.getValue() } From 554bdf14b2305ea9b1fdbc6d14221ef15ba6c50d Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 13 May 2026 11:19:51 +0200 Subject: [PATCH 067/226] Yeast: fix warning about unnecessary mutability --- shared/yeast-macros/src/parse.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index 7842ef6fb8c..608c332d47e 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -120,7 +120,7 @@ fn parse_query_fields(tokens: &mut Tokens) -> Result> { let mut field_elems: std::collections::HashMap> = std::collections::HashMap::new(); let mut bare_children: Vec = Vec::new(); - let mut push_field_elem = |order: &mut Vec, + let push_field_elem = |order: &mut Vec, map: &mut std::collections::HashMap>, name: String, elem: TokenStream| { From 5d6dc5c3c34e3e0e82809b70ecc05df6c88467b7 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 13 May 2026 13:06:34 +0000 Subject: [PATCH 068/226] unified: Clean up statements/block mess Introduces (by making it named) a `block` node, and conversely makes `statements` anonymous. This enables us to sensibly distinguish between the "then" and "else" branch of an `if_statement`, which we were not able to previously. --- .../extractor/tree-sitter-swift/grammar.js | 51 +++++++++---------- .../tree-sitter-swift/node-types.yml | 46 ++++++++--------- 2 files changed, 45 insertions(+), 52 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 566b7d5567a..2112413b0c6 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -979,7 +979,7 @@ module.exports = grammar({ seq( choice("{", "^{"), optional($._lambda_type_declaration), - field("body", optional($.statements)), + optional($._statements), "}" ) ), @@ -1041,14 +1041,14 @@ module.exports = grammar({ ), self_expression: ($) => "self", super_expression: ($) => seq("super"), - _else_options: ($) => choice($._block, field("else_branch", $.if_statement)), + _else_options: ($) => choice(field("else_branch", $.block), field("else_branch", $.if_statement)), if_statement: ($) => prec.right( PRECS["if"], seq( "if", sep1(field("condition", $.if_condition), ","), - $._block, + field("body", $.block), optional(seq(field("else_keyword", $["else"]), $._else_options)) ) ), @@ -1067,7 +1067,7 @@ module.exports = grammar({ "guard", sep1(field("condition", $.if_condition), ","), field("else_keyword", $["else"]), - $._block + field("body", $.block) ) ), switch_statement: ($) => @@ -1094,18 +1094,18 @@ module.exports = grammar({ field("default", $.default_keyword) ), ":", - field("body", $.statements), + $._statements, optional("fallthrough") ), switch_pattern: ($) => field("pattern", alias($._binding_pattern_with_expr, $.pattern)), do_statement: ($) => - prec.right(PRECS["do"], seq("do", $._block, repeat(field("catch", $.catch_block)))), + prec.right(PRECS["do"], seq("do", field("body", $.block), repeat(field("catch", $.catch_block)))), catch_block: ($) => seq( field("keyword", $.catch_keyword), field("error", optional(alias($._binding_pattern_no_expr, $.pattern))), field("where", optional($.where_clause)), - $._block + field("body", $.block) ), where_clause: ($) => prec.left(seq(field("keyword", $.where_keyword), field("expr", $.expression))), key_path_expression: ($) => @@ -1181,7 +1181,7 @@ module.exports = grammar({ //////////////////////////////// // Statements - https://docs.swift.org/swift-book/ReferenceManual/Statements.html //////////////////////////////// - statements: ($) => + _statements: ($) => prec.left( // Left precedence is required in switch statements seq( @@ -1204,7 +1204,7 @@ module.exports = grammar({ $._labeled_statement, $._throw_statement ), - _block: ($) => prec(PRECS.block, seq("{", field("body", optional($.statements)), "}")), + block: ($) => prec(PRECS.block, seq("{", optional($._statements), "}")), _labeled_statement: ($) => seq( optional($.statement_label), @@ -1231,7 +1231,7 @@ module.exports = grammar({ "in", field("collection", $._for_statement_collection), field("where", optional($.where_clause)), - $._block + field("body", $.block) ) ), _for_statement_collection: ($) => @@ -1248,9 +1248,7 @@ module.exports = grammar({ seq( "while", sep1(field("condition", $.if_condition), ","), - "{", - field("body", optional($.statements)), - "}" + field("body", $.block) ) ), repeat_while_statement: ($) => @@ -1258,9 +1256,7 @@ module.exports = grammar({ PRECS.loop, seq( "repeat", - "{", - field("body", optional($.statements)), - "}", + field("body", $.block), // Make sure we make it to the `while` before assuming this is a parameter pack. repeat($._implicit_semi), "while", @@ -1443,14 +1439,14 @@ module.exports = grammar({ field("modifiers", optional($.modifiers)), "willSet", optional(seq("(", field("parameter", $.simple_identifier), ")")), - $._block + field("body", $.block) ), didset_clause: ($) => seq( field("modifiers", optional($.modifiers)), "didSet", optional(seq("(", field("parameter", $.simple_identifier), ")")), - $._block + field("body", $.block) ), typealias_declaration: ($) => seq(field("modifiers", optional($.modifiers)), $._modifierless_typealias_declaration), @@ -1464,13 +1460,13 @@ module.exports = grammar({ ), function_declaration: ($) => prec.right( - seq($._bodyless_function_declaration, field("body", $.function_body)) + seq($._bodyless_function_declaration, field("body", $.block)) ), _modifierless_function_declaration: ($) => prec.right( seq( $._modifierless_function_declaration_no_body, - field("body", $.function_body) + field("body", $.block) ) ), _bodyless_function_declaration: ($) => @@ -1496,7 +1492,6 @@ module.exports = grammar({ field("type_constraints", optional($.type_constraints)) ) ), - function_body: ($) => $._block, macro_declaration: ($) => seq( $._macro_head, @@ -1742,7 +1737,7 @@ module.exports = grammar({ protocol_function_declaration: ($) => seq( $._bodyless_function_declaration, - optional(field("body", $.function_body)) + optional(field("body", $.block)) ), init_declaration: ($) => prec.right( @@ -1756,12 +1751,12 @@ module.exports = grammar({ field("async", optional($._async_keyword)), field("throws", optional(choice($.throws_clause, $.throws))), field("type_constraints", optional($.type_constraints)), - optional(field("body", $.function_body)) + optional(field("body", $.block)) ) ), deinit_declaration: ($) => prec.right( - seq(field("modifiers", optional($.modifiers)), "deinit", field("body", $.function_body)) + seq(field("modifiers", optional($.modifiers)), "deinit", field("body", $.block)) ), subscript_declaration: ($) => prec.right( @@ -1784,7 +1779,7 @@ module.exports = grammar({ seq( "{", choice( - field("body", optional($.statements)), + optional($._statements), repeat( field("accessor", choice($.computed_getter, $.computed_setter, $.computed_modify)) ) @@ -1792,15 +1787,15 @@ module.exports = grammar({ "}" ), computed_getter: ($) => - seq(repeat(field("attribute", $.attribute)), field("specifier", $.getter_specifier), optional($._block)), + seq(repeat(field("attribute", $.attribute)), field("specifier", $.getter_specifier), optional(field("body", $.block))), computed_modify: ($) => - seq(repeat(field("attribute", $.attribute)), field("specifier", $.modify_specifier), optional($._block)), + seq(repeat(field("attribute", $.attribute)), field("specifier", $.modify_specifier), optional(field("body", $.block))), computed_setter: ($) => seq( repeat(field("attribute", $.attribute)), field("specifier", $.setter_specifier), optional(seq("(", field("parameter", $.simple_identifier), ")")), - optional($._block) + optional(field("body", $.block)) ), getter_specifier: ($) => seq(field("mutation", optional($.mutation_modifier)), "get", optional($._getter_effects)), diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 47f56435d03..125a26a7679 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -155,6 +155,8 @@ named: lhs: expression op: ["&", "<<", ">>", "^", "|"] rhs: expression + block: + statement*: [control_transfer_statement, do_statement, expression, for_statement, guard_statement, local_declaration, repeat_while_statement, statement_label, while_statement] boolean_literal: call_expression: function: expression @@ -174,7 +176,7 @@ named: name: simple_identifier type?: user_type catch_block: - body?: statements + body: block error?: pattern keyword: catch_keyword where?: where_clause @@ -209,18 +211,18 @@ named: version*: integer_literal computed_getter: attribute*: attribute - body?: statements + body?: block specifier: getter_specifier computed_modify: attribute*: attribute - body?: statements + body?: block specifier: modify_specifier computed_property: accessor*: [computed_getter, computed_modify, computed_setter] - body?: statements + statement*: [control_transfer_statement, do_statement, expression, for_statement, guard_statement, local_declaration, repeat_while_statement, statement_label, while_statement] computed_setter: attribute*: attribute - body?: statements + body?: block parameter?: simple_identifier specifier: setter_specifier conjunction_expression: @@ -240,7 +242,7 @@ named: custom_operator: default_keyword: deinit_declaration: - body: function_body + body: block modifiers?: modifiers deprecated_operator_declaration_body: entry*: [bin_literal, boolean_literal, hex_literal, integer_literal, line_string_literal, multi_line_string_literal, "nil", oct_literal, raw_string_literal, real_literal, regex_literal, simple_identifier] @@ -252,7 +254,7 @@ named: key: type value: type didset_clause: - body?: statements + body: block modifiers?: modifiers parameter?: simple_identifier directive: @@ -264,7 +266,7 @@ named: op: "||" rhs: expression do_statement: - body?: statements + body: block catch*: catch_block else: enum_class_body: @@ -294,19 +296,17 @@ named: external_macro_definition: arguments: value_arguments for_statement: - body?: statements + body: block collection: expression item: pattern try?: try_operator type?: type_annotation where?: where_clause fully_open_range: - function_body: - body?: statements function_declaration: async?: "async" attribute*: attribute - body: function_body + body: block default_value*: expression modifiers*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier] name: [referenceable_operator, simple_identifier] @@ -325,7 +325,7 @@ named: effect*: [async_keyword, throws, throws_clause] mutation?: mutation_modifier guard_statement: - body?: statements + body: block condition+: if_condition else_keyword: else hex_literal: @@ -339,9 +339,9 @@ named: value?: expression where?: where_clause if_statement: - body*: statements + body: block condition+: if_condition - else_branch?: if_statement + else_branch?: [block, if_statement] else_keyword?: else implicitly_unwrapped_type: name: type @@ -363,7 +363,7 @@ named: async?: "async" attribute*: attribute bang?: bang - body?: function_body + body?: block default_value*: expression modifiers?: modifiers name: "init" @@ -397,8 +397,8 @@ named: parameter+: lambda_parameter lambda_literal: attribute*: attribute - body?: statements captures?: capture_list + statement*: [control_transfer_statement, do_statement, expression, for_statement, guard_statement, local_declaration, repeat_while_statement, statement_label, while_statement] type?: lambda_function_type lambda_parameter: external_name?: simple_identifier @@ -528,7 +528,7 @@ named: protocol_function_declaration: async?: "async" attribute*: attribute - body?: function_body + body?: block default_value*: expression modifiers?: modifiers name: [referenceable_operator, simple_identifier] @@ -565,7 +565,7 @@ named: operator: ["!=", "!==", "%", "%=", "&", "*", "*=", "+", "++", "+=", "-", "--", "-=", "/", "/=", "<", "<<", "<=", "=", "==", "===", ">", ">=", ">>", "^", bang, custom_operator, "|", "~"] regex_literal: repeat_while_statement: - body?: statements + body: block condition+: if_condition selector_expression: expr: expression @@ -582,8 +582,6 @@ named: statement*: [do_statement, expression, for_statement, global_declaration, guard_statement, repeat_while_statement, statement_label, throw_keyword, while_statement] special_literal: statement_label: - statements: - statement+: [control_transfer_statement, do_statement, expression, for_statement, guard_statement, local_declaration, repeat_while_statement, statement_label, while_statement] str_escaped_char: subscript_declaration: attribute*: attribute @@ -598,10 +596,10 @@ named: suppressed_constraint: suppressed: type_identifier switch_entry: - body: statements default?: default_keyword modifiers?: modifiers pattern*: switch_pattern + statement+: [control_transfer_statement, do_statement, expression, for_statement, guard_statement, local_declaration, repeat_while_statement, statement_label, while_statement] where?: where_clause switch_pattern: pattern: pattern @@ -694,11 +692,11 @@ named: keyword: where_keyword where_keyword: while_statement: - body?: statements + body: block condition+: if_condition wildcard_pattern: willset_clause: - body?: statements + body: block modifiers?: modifiers parameter?: simple_identifier willset_didset_block: From ea6f3a9568223b554c7c4434051859c335dcff2a Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 13 May 2026 13:20:58 +0000 Subject: [PATCH 069/226] unified: Encapsulate function parameters The field representation would have made it difficult to figure out which parameters correspond to which default values and attributes, so instead we now encapsulate these in a new `function_parameter` node. --- .../extractor/tree-sitter-swift/grammar.js | 4 ++-- .../tree-sitter-swift/node-types.yml | 24 +++++++------------ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 2112413b0c6..50c1a08c66c 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1611,9 +1611,9 @@ module.exports = grammar({ ), _function_value_parameters: ($) => repeat1( - seq("(", optional(sep1Opt($._function_value_parameter, ",")), ")") + seq("(", optional(sep1Opt(field("parameter", $.function_parameter), ",")), ")") ), - _function_value_parameter: ($) => + function_parameter: ($) => seq( field("attribute", optional($.attribute)), field("parameter", $.parameter), diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 125a26a7679..1f2e27ea337 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -305,17 +305,19 @@ named: fully_open_range: function_declaration: async?: "async" - attribute*: attribute body: block - default_value*: expression modifiers*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier] name: [referenceable_operator, simple_identifier] - parameter*: parameter + parameter*: function_parameter return_type?: [implicitly_unwrapped_type, type] throws?: [throws, throws_clause] type_constraints?: type_constraints type_parameters?: type_parameters function_modifier: + function_parameter: + attribute?: attribute + default_value?: expression + parameter: parameter function_type: async?: "async" params: unannotated_type @@ -361,13 +363,11 @@ named: inherits_from: [function_type, suppressed_constraint, user_type] init_declaration: async?: "async" - attribute*: attribute bang?: bang body?: block - default_value*: expression modifiers?: modifiers name: "init" - parameter*: parameter + parameter*: function_parameter throws?: [throws, throws_clause] type_constraints?: type_constraints type_parameters?: type_parameters @@ -410,12 +410,10 @@ named: interpolation*: interpolated_expression text*: [line_str_text, str_escaped_char] macro_declaration: - attribute*: attribute - default_value*: expression definition?: macro_definition modifiers?: modifiers name: simple_identifier - parameter*: parameter + parameter*: function_parameter return_type?: unannotated_type type_constraints?: type_constraints type_parameters?: type_parameters @@ -527,12 +525,10 @@ named: type_parameters?: type_parameters protocol_function_declaration: async?: "async" - attribute*: attribute body?: block - default_value*: expression modifiers?: modifiers name: [referenceable_operator, simple_identifier] - parameter*: parameter + parameter*: function_parameter return_type?: [implicitly_unwrapped_type, type] throws?: [throws, throws_clause] type_constraints?: type_constraints @@ -584,11 +580,9 @@ named: statement_label: str_escaped_char: subscript_declaration: - attribute*: attribute body: computed_property - default_value*: expression modifiers?: modifiers - parameter*: parameter + parameter*: function_parameter return_type?: [implicitly_unwrapped_type, type] type_constraints?: type_constraints type_parameters?: type_parameters From c8f7c3d7f2d199f593104f91bfb125e0c854e8a4 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 13 May 2026 13:49:30 +0000 Subject: [PATCH 070/226] unified: Group more paired items Same as in the preceding commit, these items do not make sense as separate fields on the parent node, so we materialise (or create new) intermediate nodes to group them together. --- .../extractor/tree-sitter-swift/grammar.js | 27 ++++++++++--------- .../tree-sitter-swift/node-types.yml | 19 ++++++++----- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 50c1a08c66c..385aeb4d867 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -105,8 +105,8 @@ module.exports = grammar({ // { (foo, bar) ... [$.expression, $.lambda_parameter], [$._primary_expression, $.lambda_parameter], - // (start: start, end: end) - [$._tuple_type_item_identifier, $.tuple_expression], + // (foo) where foo could be a binding pattern or a tuple expression item. + [$._binding_pattern_with_expr, $.tuple_expression_item], // After a `{` in a function or switch context, it's ambigous whether we're starting a set of local statements or // applying some modifiers to a capture or pattern. [$.modifiers], @@ -931,26 +931,25 @@ module.exports = grammar({ PRECS.tuple, seq( "(", - sep1Opt( - seq( - optional(seq(field("name", $.simple_identifier), ":")), - field("value", $.expression) - ), - "," - ), + sep1Opt(field("element", $.tuple_expression_item), ","), ")" ) ), + tuple_expression_item: ($) => + seq( + optional(seq(field("name", $.simple_identifier), ":")), + field("value", $.expression) + ), array_literal: ($) => seq("[", optional(sep1Opt(field("element", $.expression), ",")), "]"), dictionary_literal: ($) => seq( "[", - choice(":", sep1Opt($._dictionary_literal_item, ",")), + choice(":", sep1Opt(field("element", $.dictionary_literal_item), ",")), optional(","), "]" ), - _dictionary_literal_item: ($) => + dictionary_literal_item: ($) => seq(field("key", $.expression), ":", field("value", $.expression)), special_literal: ($) => seq( @@ -968,11 +967,13 @@ module.exports = grammar({ playground_literal: ($) => seq( $._hash_symbol, - choice("colorLiteral", "fileLiteral", "imageLiteral"), + field("kind", choice("colorLiteral", "fileLiteral", "imageLiteral")), "(", - sep1Opt(seq(field("name", $.simple_identifier), ":", field("value", $.expression)), ","), + sep1Opt(field("argument", $.playground_literal_argument), ","), ")" ), + playground_literal_argument: ($) => + seq(field("name", $.simple_identifier), ":", field("value", $.expression)), lambda_literal: ($) => prec.left( PRECS.lambda, diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 1f2e27ea337..64e69142fb0 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -248,8 +248,10 @@ named: entry*: [bin_literal, boolean_literal, hex_literal, integer_literal, line_string_literal, multi_line_string_literal, "nil", oct_literal, raw_string_literal, real_literal, regex_literal, simple_identifier] diagnostic: dictionary_literal: - key*: expression - value*: expression + element*: dictionary_literal_item + dictionary_literal_item: + key: expression + value: expression dictionary_type: key: type value: type @@ -483,8 +485,11 @@ named: bound_identifier?: simple_identifier kind: [binding_pattern, case_pattern, expression, tuple_pattern, type_casting_pattern, wildcard_pattern] playground_literal: - name+: simple_identifier - value+: expression + argument+: playground_literal_argument + kind: ["colorLiteral", "fileLiteral", "imageLiteral"] + playground_literal_argument: + name: simple_identifier + value: expression postfix_expression: operation: ["++", "--", bang] target: expression @@ -613,8 +618,10 @@ named: operator: try_operator try_operator: tuple_expression: - name*: simple_identifier - value+: expression + element+: tuple_expression_item + tuple_expression_item: + name?: simple_identifier + value: expression tuple_pattern: item+: tuple_pattern_item tuple_pattern_item: From 9787a8b072802b3ba5777c218f47b4e87ee08f32 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 13 May 2026 13:51:25 +0000 Subject: [PATCH 071/226] unified: Group enum entries Same as in the preceding commit. --- unified/extractor/tree-sitter-swift/grammar.js | 13 ++++++------- unified/extractor/tree-sitter-swift/node-types.yml | 8 +++++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 385aeb4d867..8b6bf33b62e 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1681,15 +1681,14 @@ module.exports = grammar({ field("modifiers", optional($.modifiers)), optional("indirect"), "case", - sep1( - seq( - field("name", $.simple_identifier), - optional($._enum_entry_suffix) - ), - "," - ), + sep1(field("case", $.enum_case_entry), ","), optional(";") ), + enum_case_entry: ($) => + seq( + field("name", $.simple_identifier), + optional($._enum_entry_suffix) + ), _enum_entry_suffix: ($) => choice( field("data_contents", $.enum_type_parameters), diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 64e69142fb0..8f136ead220 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -271,13 +271,15 @@ named: body: block catch*: catch_block else: + enum_case_entry: + data_contents?: enum_type_parameters + name: simple_identifier + raw_value?: expression enum_class_body: member*: [enum_entry, type_level_declaration] enum_entry: - data_contents*: enum_type_parameters + case+: enum_case_entry modifiers?: modifiers - name+: simple_identifier - raw_value*: expression enum_type_parameter: default_value?: expression external_name?: wildcard_pattern From caef72b0476bda5012e9d3b7303f4e3de25cd77a Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 13 May 2026 13:54:21 +0000 Subject: [PATCH 072/226] unified: Introduced named `property_binding` node This groups together a bunch of related values that would otherwise be impossible to match up correctly. --- unified/extractor/tree-sitter-swift/grammar.js | 4 ++-- unified/extractor/tree-sitter-swift/node-types.yml | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index 8b6bf33b62e..f92ff68e5e5 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1400,10 +1400,10 @@ module.exports = grammar({ prec.right( seq( $._possibly_async_binding_pattern_kind, - sep1($._single_modifierless_property_declaration, ",") + sep1(field("declarator", $.property_binding), ",") ) ), - _single_modifierless_property_declaration: ($) => + property_binding: ($) => prec.left( seq( field("name", alias($._no_expr_pattern_already_bound, $.pattern)), diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index 8f136ead220..b6271b38a8c 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -507,15 +507,17 @@ named: operation: ["&", "+", "++", "-", "--", ".", bang, custom_operator, "~"] target: expression property_behavior_modifier: + property_binding: + computed_value?: computed_property + name: pattern + observers?: willset_didset_block + type?: type_annotation + type_constraints?: type_constraints + value?: expression property_declaration: binding: value_binding_pattern - computed_value*: computed_property + declarator+: property_binding modifiers*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier] - name+: pattern - observers*: willset_didset_block - type*: type_annotation - type_constraints*: type_constraints - value*: expression property_modifier: protocol_body: member*: protocol_member_declaration From f4f85b58ca7181cb5b0d3a3e954bee972b762d48 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 13 May 2026 14:22:06 +0000 Subject: [PATCH 073/226] unified: Remove some pointless fields All of these fields have contents that are uniquely determined by the node they appear on, so they convey no information. --- unified/extractor/tree-sitter-swift/grammar.js | 8 ++++---- unified/extractor/tree-sitter-swift/node-types.yml | 6 +----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index f92ff68e5e5..b6197b345e0 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -1050,7 +1050,7 @@ module.exports = grammar({ "if", sep1(field("condition", $.if_condition), ","), field("body", $.block), - optional(seq(field("else_keyword", $["else"]), $._else_options)) + optional(seq(alias($["else"], "else"), $._else_options)) ) ), if_condition: ($) => @@ -1067,7 +1067,7 @@ module.exports = grammar({ seq( "guard", sep1(field("condition", $.if_condition), ","), - field("else_keyword", $["else"]), + alias($["else"], "else"), field("body", $.block) ) ), @@ -1712,7 +1712,7 @@ module.exports = grammar({ prec.right( seq( field("modifiers", optional($.modifiers)), - field("declaration_kind", "protocol"), + "protocol", field("name", alias($.simple_identifier, $.type_identifier)), field("type_parameters", optional($.type_parameters)), optional(seq(":", $._inheritance_specifiers)), @@ -1744,7 +1744,7 @@ module.exports = grammar({ seq( field("modifiers", optional($.modifiers)), optional("class"), - field("name", "init"), + "init", optional(choice($._quest, field("bang", $.bang))), field("type_parameters", optional($.type_parameters)), $._function_value_parameters, diff --git a/unified/extractor/tree-sitter-swift/node-types.yml b/unified/extractor/tree-sitter-swift/node-types.yml index b6271b38a8c..8e1a4209d74 100644 --- a/unified/extractor/tree-sitter-swift/node-types.yml +++ b/unified/extractor/tree-sitter-swift/node-types.yml @@ -270,7 +270,6 @@ named: do_statement: body: block catch*: catch_block - else: enum_case_entry: data_contents?: enum_type_parameters name: simple_identifier @@ -333,7 +332,6 @@ named: guard_statement: body: block condition+: if_condition - else_keyword: else hex_literal: identifier: part+: simple_identifier @@ -348,7 +346,6 @@ named: body: block condition+: if_condition else_branch?: [block, if_statement] - else_keyword?: else implicitly_unwrapped_type: name: type import_declaration: @@ -370,7 +367,6 @@ named: bang?: bang body?: block modifiers?: modifiers - name: "init" parameter*: function_parameter throws?: [throws, throws_clause] type_constraints?: type_constraints @@ -526,7 +522,6 @@ named: protocol_declaration: attribute*: attribute body: protocol_body - declaration_kind: "protocol" inherits*: inheritance_specifier modifiers?: modifiers name: type_identifier @@ -794,6 +789,7 @@ unnamed: - "dsohandle" - "dynamic" - "each" + - "else" - "enum" - "extension" - "externalMacro" From dd9c066c6139ccc4eeba6610a780e8cfffef7d8a Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 13 May 2026 14:24:12 +0000 Subject: [PATCH 074/226] unified: Regenerate files --- unified/ql/lib/codeql/unified/Ast.qll | 430 +++++++++++----------- unified/ql/lib/unified.dbscheme | 510 +++++++++++--------------- 2 files changed, 429 insertions(+), 511 deletions(-) diff --git a/unified/ql/lib/codeql/unified/Ast.qll b/unified/ql/lib/codeql/unified/Ast.qll index db2e73df01b..1835f2c449a 100644 --- a/unified/ql/lib/codeql/unified/Ast.qll +++ b/unified/ql/lib/codeql/unified/Ast.qll @@ -364,6 +364,18 @@ module Swift { } } + /** A class representing `block` nodes. */ + class Block extends @swift_block, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "Block" } + + /** Gets the node corresponding to the field `statement`. */ + final AstNode getStatement(int i) { swift_block_statement(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_block_statement(this, _, result) } + } + /** A class representing `boolean_literal` tokens. */ class BooleanLiteral extends @swift_token_boolean_literal, Token { /** Gets the name of the primary QL class for this element. */ @@ -471,22 +483,22 @@ module Swift { final override string getAPrimaryQlClass() { result = "CatchBlock" } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_catch_block_body(this, result) } + final Block getBody() { swift_catch_block_def(this, result, _) } /** Gets the node corresponding to the field `error`. */ final Pattern getError() { swift_catch_block_error(this, result) } /** Gets the node corresponding to the field `keyword`. */ - final CatchKeyword getKeyword() { swift_catch_block_def(this, result) } + final CatchKeyword getKeyword() { swift_catch_block_def(this, _, result) } /** Gets the node corresponding to the field `where`. */ final WhereClause getWhere() { swift_catch_block_where(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_catch_block_body(this, result) or + swift_catch_block_def(this, result, _) or swift_catch_block_error(this, result) or - swift_catch_block_def(this, result) or + swift_catch_block_def(this, _, result) or swift_catch_block_where(this, result) } } @@ -677,7 +689,7 @@ module Swift { final Attribute getAttribute(int i) { swift_computed_getter_attribute(this, i, result) } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_computed_getter_body(this, result) } + final Block getBody() { swift_computed_getter_body(this, result) } /** Gets the node corresponding to the field `specifier`. */ final GetterSpecifier getSpecifier() { swift_computed_getter_def(this, result) } @@ -699,7 +711,7 @@ module Swift { final Attribute getAttribute(int i) { swift_computed_modify_attribute(this, i, result) } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_computed_modify_body(this, result) } + final Block getBody() { swift_computed_modify_body(this, result) } /** Gets the node corresponding to the field `specifier`. */ final ModifySpecifier getSpecifier() { swift_computed_modify_def(this, result) } @@ -720,13 +732,13 @@ module Swift { /** Gets the node corresponding to the field `accessor`. */ final AstNode getAccessor(int i) { swift_computed_property_accessor(this, i, result) } - /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_computed_property_body(this, result) } + /** Gets the node corresponding to the field `statement`. */ + final AstNode getStatement(int i) { swift_computed_property_statement(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_computed_property_accessor(this, _, result) or - swift_computed_property_body(this, result) + swift_computed_property_statement(this, _, result) } } @@ -739,7 +751,7 @@ module Swift { final Attribute getAttribute(int i) { swift_computed_setter_attribute(this, i, result) } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_computed_setter_body(this, result) } + final Block getBody() { swift_computed_setter_body(this, result) } /** Gets the node corresponding to the field `parameter`. */ final SimpleIdentifier getParameter() { swift_computed_setter_parameter(this, result) } @@ -857,7 +869,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "DeinitDeclaration" } /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_deinit_declaration_def(this, result) } + final Block getBody() { swift_deinit_declaration_def(this, result) } /** Gets the node corresponding to the field `modifiers`. */ final Modifiers getModifiers() { swift_deinit_declaration_modifiers(this, result) } @@ -897,16 +909,30 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "DictionaryLiteral" } + /** Gets the node corresponding to the field `element`. */ + final DictionaryLiteralItem getElement(int i) { + swift_dictionary_literal_element(this, i, result) + } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_dictionary_literal_element(this, _, result) } + } + + /** A class representing `dictionary_literal_item` nodes. */ + class DictionaryLiteralItem extends @swift_dictionary_literal_item, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "DictionaryLiteralItem" } + /** Gets the node corresponding to the field `key`. */ - final Expression getKey(int i) { swift_dictionary_literal_key(this, i, result) } + final Expression getKey() { swift_dictionary_literal_item_def(this, result, _) } /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_dictionary_literal_value(this, i, result) } + final Expression getValue() { swift_dictionary_literal_item_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_dictionary_literal_key(this, _, result) or - swift_dictionary_literal_value(this, _, result) + swift_dictionary_literal_item_def(this, result, _) or + swift_dictionary_literal_item_def(this, _, result) } } @@ -933,7 +959,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "DidsetClause" } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_didset_clause_body(this, result) } + final Block getBody() { swift_didset_clause_def(this, result) } /** Gets the node corresponding to the field `modifiers`. */ final Modifiers getModifiers() { swift_didset_clause_modifiers(this, result) } @@ -943,7 +969,7 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_didset_clause_body(this, result) or + swift_didset_clause_def(this, result) or swift_didset_clause_modifiers(this, result) or swift_didset_clause_parameter(this, result) } @@ -1006,21 +1032,37 @@ module Swift { final override string getAPrimaryQlClass() { result = "DoStatement" } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_do_statement_body(this, result) } + final Block getBody() { swift_do_statement_def(this, result) } /** Gets the node corresponding to the field `catch`. */ final CatchBlock getCatch(int i) { swift_do_statement_catch(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_do_statement_body(this, result) or swift_do_statement_catch(this, _, result) + swift_do_statement_def(this, result) or swift_do_statement_catch(this, _, result) } } - /** A class representing `else` tokens. */ - class Else extends @swift_token_else, Token { + /** A class representing `enum_case_entry` nodes. */ + class EnumCaseEntry extends @swift_enum_case_entry, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Else" } + final override string getAPrimaryQlClass() { result = "EnumCaseEntry" } + + /** Gets the node corresponding to the field `data_contents`. */ + final EnumTypeParameters getDataContents() { swift_enum_case_entry_data_contents(this, result) } + + /** Gets the node corresponding to the field `name`. */ + final SimpleIdentifier getName() { swift_enum_case_entry_def(this, result) } + + /** Gets the node corresponding to the field `raw_value`. */ + final Expression getRawValue() { swift_enum_case_entry_raw_value(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_enum_case_entry_data_contents(this, result) or + swift_enum_case_entry_def(this, result) or + swift_enum_case_entry_raw_value(this, result) + } } /** A class representing `enum_class_body` nodes. */ @@ -1040,26 +1082,15 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "EnumEntry" } - /** Gets the node corresponding to the field `data_contents`. */ - final EnumTypeParameters getDataContents(int i) { - swift_enum_entry_data_contents(this, i, result) - } + /** Gets the node corresponding to the field `case`. */ + final EnumCaseEntry getCase(int i) { swift_enum_entry_case(this, i, result) } /** Gets the node corresponding to the field `modifiers`. */ final Modifiers getModifiers() { swift_enum_entry_modifiers(this, result) } - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_enum_entry_name(this, i, result) } - - /** Gets the node corresponding to the field `raw_value`. */ - final Expression getRawValue(int i) { swift_enum_entry_raw_value(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_enum_entry_data_contents(this, _, result) or - swift_enum_entry_modifiers(this, result) or - swift_enum_entry_name(this, _, result) or - swift_enum_entry_raw_value(this, _, result) + swift_enum_entry_case(this, _, result) or swift_enum_entry_modifiers(this, result) } } @@ -1192,13 +1223,13 @@ module Swift { final override string getAPrimaryQlClass() { result = "ForStatement" } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_for_statement_body(this, result) } + final Block getBody() { swift_for_statement_def(this, result, _, _) } /** Gets the node corresponding to the field `collection`. */ - final Expression getCollection() { swift_for_statement_def(this, result, _) } + final Expression getCollection() { swift_for_statement_def(this, _, result, _) } /** Gets the node corresponding to the field `item`. */ - final Pattern getItem() { swift_for_statement_def(this, _, result) } + final Pattern getItem() { swift_for_statement_def(this, _, _, result) } /** Gets the node corresponding to the field `try`. */ final TryOperator getTry() { swift_for_statement_try(this, result) } @@ -1211,9 +1242,9 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_for_statement_body(this, result) or - swift_for_statement_def(this, result, _) or - swift_for_statement_def(this, _, result) or + swift_for_statement_def(this, result, _, _) or + swift_for_statement_def(this, _, result, _) or + swift_for_statement_def(this, _, _, result) or swift_for_statement_try(this, result) or swift_for_statement_type(this, result) or swift_for_statement_where(this, result) @@ -1226,18 +1257,6 @@ module Swift { final override string getAPrimaryQlClass() { result = "FullyOpenRange" } } - /** A class representing `function_body` nodes. */ - class FunctionBody extends @swift_function_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionBody" } - - /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_function_body_body(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_function_body_body(this, result) } - } - /** A class representing `function_declaration` nodes. */ class FunctionDeclaration extends @swift_function_declaration, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -1246,16 +1265,8 @@ module Swift { /** Gets the node corresponding to the field `async`. */ final ReservedWord getAsync() { swift_function_declaration_async(this, result) } - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_function_declaration_attribute(this, i, result) } - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_function_declaration_def(this, result, _) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_function_declaration_default_value(this, i, result) - } + final Block getBody() { swift_function_declaration_def(this, result, _) } /** Gets the node corresponding to the field `modifiers`. */ final AstNode getModifiers(int i) { swift_function_declaration_modifiers(this, i, result) } @@ -1264,7 +1275,9 @@ module Swift { final AstNode getName() { swift_function_declaration_def(this, _, result) } /** Gets the node corresponding to the field `parameter`. */ - final Parameter getParameter(int i) { swift_function_declaration_parameter(this, i, result) } + final FunctionParameter getParameter(int i) { + swift_function_declaration_parameter(this, i, result) + } /** Gets the node corresponding to the field `return_type`. */ final AstNode getReturnType() { swift_function_declaration_return_type(this, result) } @@ -1285,9 +1298,7 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_function_declaration_async(this, result) or - swift_function_declaration_attribute(this, _, result) or swift_function_declaration_def(this, result, _) or - swift_function_declaration_default_value(this, _, result) or swift_function_declaration_modifiers(this, _, result) or swift_function_declaration_def(this, _, result) or swift_function_declaration_parameter(this, _, result) or @@ -1304,6 +1315,28 @@ module Swift { final override string getAPrimaryQlClass() { result = "FunctionModifier" } } + /** A class representing `function_parameter` nodes. */ + class FunctionParameter extends @swift_function_parameter, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "FunctionParameter" } + + /** Gets the node corresponding to the field `attribute`. */ + final Attribute getAttribute() { swift_function_parameter_attribute(this, result) } + + /** Gets the node corresponding to the field `default_value`. */ + final Expression getDefaultValue() { swift_function_parameter_default_value(this, result) } + + /** Gets the node corresponding to the field `parameter`. */ + final Parameter getParameter() { swift_function_parameter_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_function_parameter_attribute(this, result) or + swift_function_parameter_default_value(this, result) or + swift_function_parameter_def(this, result) + } + } + /** A class representing `function_type` nodes. */ class FunctionType extends @swift_function_type, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -1356,19 +1389,14 @@ module Swift { final override string getAPrimaryQlClass() { result = "GuardStatement" } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_guard_statement_body(this, result) } + final Block getBody() { swift_guard_statement_def(this, result) } /** Gets the node corresponding to the field `condition`. */ final IfCondition getCondition(int i) { swift_guard_statement_condition(this, i, result) } - /** Gets the node corresponding to the field `else_keyword`. */ - final Else getElseKeyword() { swift_guard_statement_def(this, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_guard_statement_body(this, result) or - swift_guard_statement_condition(this, _, result) or - swift_guard_statement_def(this, result) + swift_guard_statement_def(this, result) or swift_guard_statement_condition(this, _, result) } } @@ -1434,23 +1462,19 @@ module Swift { final override string getAPrimaryQlClass() { result = "IfStatement" } /** Gets the node corresponding to the field `body`. */ - final Statements getBody(int i) { swift_if_statement_body(this, i, result) } + final Block getBody() { swift_if_statement_def(this, result) } /** Gets the node corresponding to the field `condition`. */ final IfCondition getCondition(int i) { swift_if_statement_condition(this, i, result) } /** Gets the node corresponding to the field `else_branch`. */ - final IfStatement getElseBranch() { swift_if_statement_else_branch(this, result) } - - /** Gets the node corresponding to the field `else_keyword`. */ - final Else getElseKeyword() { swift_if_statement_else_keyword(this, result) } + final AstNode getElseBranch() { swift_if_statement_else_branch(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_if_statement_body(this, _, result) or + swift_if_statement_def(this, result) or swift_if_statement_condition(this, _, result) or - swift_if_statement_else_branch(this, result) or - swift_if_statement_else_keyword(this, result) + swift_if_statement_else_branch(this, result) } } @@ -1553,30 +1577,19 @@ module Swift { /** Gets the node corresponding to the field `async`. */ final ReservedWord getAsync() { swift_init_declaration_async(this, result) } - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_init_declaration_attribute(this, i, result) } - /** Gets the node corresponding to the field `bang`. */ final Bang getBang() { swift_init_declaration_bang(this, result) } /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_init_declaration_body(this, result) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_init_declaration_default_value(this, i, result) - } + final Block getBody() { swift_init_declaration_body(this, result) } /** Gets the node corresponding to the field `modifiers`. */ final Modifiers getModifiers() { swift_init_declaration_modifiers(this, result) } - /** Gets the node corresponding to the field `name`. */ - final string getName() { - exists(int value | swift_init_declaration_def(this, value) | (result = "init" and value = 0)) - } - /** Gets the node corresponding to the field `parameter`. */ - final Parameter getParameter(int i) { swift_init_declaration_parameter(this, i, result) } + final FunctionParameter getParameter(int i) { + swift_init_declaration_parameter(this, i, result) + } /** Gets the node corresponding to the field `throws`. */ final AstNode getThrows() { swift_init_declaration_throws(this, result) } @@ -1594,10 +1607,8 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_init_declaration_async(this, result) or - swift_init_declaration_attribute(this, _, result) or swift_init_declaration_bang(this, result) or swift_init_declaration_body(this, result) or - swift_init_declaration_default_value(this, _, result) or swift_init_declaration_modifiers(this, result) or swift_init_declaration_parameter(this, _, result) or swift_init_declaration_throws(this, result) or @@ -1762,20 +1773,20 @@ module Swift { /** Gets the node corresponding to the field `attribute`. */ final Attribute getAttribute(int i) { swift_lambda_literal_attribute(this, i, result) } - /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_lambda_literal_body(this, result) } - /** Gets the node corresponding to the field `captures`. */ final CaptureList getCaptures() { swift_lambda_literal_captures(this, result) } + /** Gets the node corresponding to the field `statement`. */ + final AstNode getStatement(int i) { swift_lambda_literal_statement(this, i, result) } + /** Gets the node corresponding to the field `type`. */ final LambdaFunctionType getType() { swift_lambda_literal_type(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_lambda_literal_attribute(this, _, result) or - swift_lambda_literal_body(this, result) or swift_lambda_literal_captures(this, result) or + swift_lambda_literal_statement(this, _, result) or swift_lambda_literal_type(this, result) } } @@ -1839,14 +1850,6 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "MacroDeclaration" } - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_macro_declaration_attribute(this, i, result) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_macro_declaration_default_value(this, i, result) - } - /** Gets the node corresponding to the field `definition`. */ final MacroDefinition getDefinition() { swift_macro_declaration_definition(this, result) } @@ -1857,7 +1860,9 @@ module Swift { final SimpleIdentifier getName() { swift_macro_declaration_def(this, result) } /** Gets the node corresponding to the field `parameter`. */ - final Parameter getParameter(int i) { swift_macro_declaration_parameter(this, i, result) } + final FunctionParameter getParameter(int i) { + swift_macro_declaration_parameter(this, i, result) + } /** Gets the node corresponding to the field `return_type`. */ final UnannotatedType getReturnType() { swift_macro_declaration_return_type(this, result) } @@ -1874,8 +1879,6 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_macro_declaration_attribute(this, _, result) or - swift_macro_declaration_default_value(this, _, result) or swift_macro_declaration_definition(this, result) or swift_macro_declaration_modifiers(this, result) or swift_macro_declaration_def(this, result) or @@ -2295,16 +2298,41 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "PlaygroundLiteral" } + /** Gets the node corresponding to the field `argument`. */ + final PlaygroundLiteralArgument getArgument(int i) { + swift_playground_literal_argument(this, i, result) + } + + /** Gets the node corresponding to the field `kind`. */ + final string getKind() { + exists(int value | swift_playground_literal_def(this, value) | + result = "colorLiteral" and value = 0 + or + result = "fileLiteral" and value = 1 + or + result = "imageLiteral" and value = 2 + ) + } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_playground_literal_argument(this, _, result) } + } + + /** A class representing `playground_literal_argument` nodes. */ + class PlaygroundLiteralArgument extends @swift_playground_literal_argument, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "PlaygroundLiteralArgument" } + /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_playground_literal_name(this, i, result) } + final SimpleIdentifier getName() { swift_playground_literal_argument_def(this, result, _) } /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_playground_literal_value(this, i, result) } + final Expression getValue() { swift_playground_literal_argument_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_playground_literal_name(this, _, result) or - swift_playground_literal_value(this, _, result) + swift_playground_literal_argument_def(this, result, _) or + swift_playground_literal_argument_def(this, _, result) } } @@ -2402,6 +2430,44 @@ module Swift { final override string getAPrimaryQlClass() { result = "PropertyBehaviorModifier" } } + /** A class representing `property_binding` nodes. */ + class PropertyBinding extends @swift_property_binding, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "PropertyBinding" } + + /** Gets the node corresponding to the field `computed_value`. */ + final ComputedProperty getComputedValue() { + swift_property_binding_computed_value(this, result) + } + + /** Gets the node corresponding to the field `name`. */ + final Pattern getName() { swift_property_binding_def(this, result) } + + /** Gets the node corresponding to the field `observers`. */ + final WillsetDidsetBlock getObservers() { swift_property_binding_observers(this, result) } + + /** Gets the node corresponding to the field `type`. */ + final TypeAnnotation getType() { swift_property_binding_type(this, result) } + + /** Gets the node corresponding to the field `type_constraints`. */ + final TypeConstraints getTypeConstraints() { + swift_property_binding_type_constraints(this, result) + } + + /** Gets the node corresponding to the field `value`. */ + final Expression getValue() { swift_property_binding_value(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_property_binding_computed_value(this, result) or + swift_property_binding_def(this, result) or + swift_property_binding_observers(this, result) or + swift_property_binding_type(this, result) or + swift_property_binding_type_constraints(this, result) or + swift_property_binding_value(this, result) + } + } + /** A class representing `property_declaration` nodes. */ class PropertyDeclaration extends @swift_property_declaration, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -2410,43 +2476,19 @@ module Swift { /** Gets the node corresponding to the field `binding`. */ final ValueBindingPattern getBinding() { swift_property_declaration_def(this, result) } - /** Gets the node corresponding to the field `computed_value`. */ - final ComputedProperty getComputedValue(int i) { - swift_property_declaration_computed_value(this, i, result) + /** Gets the node corresponding to the field `declarator`. */ + final PropertyBinding getDeclarator(int i) { + swift_property_declaration_declarator(this, i, result) } /** Gets the node corresponding to the field `modifiers`. */ final AstNode getModifiers(int i) { swift_property_declaration_modifiers(this, i, result) } - /** Gets the node corresponding to the field `name`. */ - final Pattern getName(int i) { swift_property_declaration_name(this, i, result) } - - /** Gets the node corresponding to the field `observers`. */ - final WillsetDidsetBlock getObservers(int i) { - swift_property_declaration_observers(this, i, result) - } - - /** Gets the node corresponding to the field `type`. */ - final TypeAnnotation getType(int i) { swift_property_declaration_type(this, i, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints(int i) { - swift_property_declaration_type_constraints(this, i, result) - } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_property_declaration_value(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_property_declaration_def(this, result) or - swift_property_declaration_computed_value(this, _, result) or - swift_property_declaration_modifiers(this, _, result) or - swift_property_declaration_name(this, _, result) or - swift_property_declaration_observers(this, _, result) or - swift_property_declaration_type(this, _, result) or - swift_property_declaration_type_constraints(this, _, result) or - swift_property_declaration_value(this, _, result) + swift_property_declaration_declarator(this, _, result) or + swift_property_declaration_modifiers(this, _, result) } } @@ -2491,14 +2533,7 @@ module Swift { final Attribute getAttribute(int i) { swift_protocol_declaration_attribute(this, i, result) } /** Gets the node corresponding to the field `body`. */ - final ProtocolBody getBody() { swift_protocol_declaration_def(this, result, _, _) } - - /** Gets the node corresponding to the field `declaration_kind`. */ - final string getDeclarationKind() { - exists(int value | swift_protocol_declaration_def(this, _, value, _) | - (result = "protocol" and value = 0) - ) - } + final ProtocolBody getBody() { swift_protocol_declaration_def(this, result, _) } /** Gets the node corresponding to the field `inherits`. */ final InheritanceSpecifier getInherits(int i) { @@ -2509,7 +2544,7 @@ module Swift { final Modifiers getModifiers() { swift_protocol_declaration_modifiers(this, result) } /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_protocol_declaration_def(this, _, _, result) } + final TypeIdentifier getName() { swift_protocol_declaration_def(this, _, result) } /** Gets the node corresponding to the field `type_constraints`. */ final TypeConstraints getTypeConstraints() { @@ -2524,10 +2559,10 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_protocol_declaration_attribute(this, _, result) or - swift_protocol_declaration_def(this, result, _, _) or + swift_protocol_declaration_def(this, result, _) or swift_protocol_declaration_inherits(this, _, result) or swift_protocol_declaration_modifiers(this, result) or - swift_protocol_declaration_def(this, _, _, result) or + swift_protocol_declaration_def(this, _, result) or swift_protocol_declaration_type_constraints(this, result) or swift_protocol_declaration_type_parameters(this, result) } @@ -2541,18 +2576,8 @@ module Swift { /** Gets the node corresponding to the field `async`. */ final ReservedWord getAsync() { swift_protocol_function_declaration_async(this, result) } - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { - swift_protocol_function_declaration_attribute(this, i, result) - } - /** Gets the node corresponding to the field `body`. */ - final FunctionBody getBody() { swift_protocol_function_declaration_body(this, result) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_protocol_function_declaration_default_value(this, i, result) - } + final Block getBody() { swift_protocol_function_declaration_body(this, result) } /** Gets the node corresponding to the field `modifiers`. */ final Modifiers getModifiers() { swift_protocol_function_declaration_modifiers(this, result) } @@ -2561,7 +2586,7 @@ module Swift { final AstNode getName() { swift_protocol_function_declaration_def(this, result) } /** Gets the node corresponding to the field `parameter`. */ - final Parameter getParameter(int i) { + final FunctionParameter getParameter(int i) { swift_protocol_function_declaration_parameter(this, i, result) } @@ -2584,9 +2609,7 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { swift_protocol_function_declaration_async(this, result) or - swift_protocol_function_declaration_attribute(this, _, result) or swift_protocol_function_declaration_body(this, result) or - swift_protocol_function_declaration_default_value(this, _, result) or swift_protocol_function_declaration_modifiers(this, result) or swift_protocol_function_declaration_def(this, result) or swift_protocol_function_declaration_parameter(this, _, result) or @@ -2776,7 +2799,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "RepeatWhileStatement" } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_repeat_while_statement_body(this, result) } + final Block getBody() { swift_repeat_while_statement_def(this, result) } /** Gets the node corresponding to the field `condition`. */ final IfCondition getCondition(int i) { @@ -2785,7 +2808,7 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_repeat_while_statement_body(this, result) or + swift_repeat_while_statement_def(this, result) or swift_repeat_while_statement_condition(this, _, result) } } @@ -2878,18 +2901,6 @@ module Swift { final override string getAPrimaryQlClass() { result = "StatementLabel" } } - /** A class representing `statements` nodes. */ - class Statements extends @swift_statements, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Statements" } - - /** Gets the node corresponding to the field `statement`. */ - final AstNode getStatement(int i) { swift_statements_statement(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_statements_statement(this, _, result) } - } - /** A class representing `str_escaped_char` tokens. */ class StrEscapedChar extends @swift_token_str_escaped_char, Token { /** Gets the name of the primary QL class for this element. */ @@ -2901,22 +2912,16 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SubscriptDeclaration" } - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_subscript_declaration_attribute(this, i, result) } - /** Gets the node corresponding to the field `body`. */ final ComputedProperty getBody() { swift_subscript_declaration_def(this, result) } - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue(int i) { - swift_subscript_declaration_default_value(this, i, result) - } - /** Gets the node corresponding to the field `modifiers`. */ final Modifiers getModifiers() { swift_subscript_declaration_modifiers(this, result) } /** Gets the node corresponding to the field `parameter`. */ - final Parameter getParameter(int i) { swift_subscript_declaration_parameter(this, i, result) } + final FunctionParameter getParameter(int i) { + swift_subscript_declaration_parameter(this, i, result) + } /** Gets the node corresponding to the field `return_type`. */ final AstNode getReturnType() { swift_subscript_declaration_return_type(this, result) } @@ -2933,9 +2938,7 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_subscript_declaration_attribute(this, _, result) or swift_subscript_declaration_def(this, result) or - swift_subscript_declaration_default_value(this, _, result) or swift_subscript_declaration_modifiers(this, result) or swift_subscript_declaration_parameter(this, _, result) or swift_subscript_declaration_return_type(this, result) or @@ -2967,9 +2970,6 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SwitchEntry" } - /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_switch_entry_def(this, result) } - /** Gets the node corresponding to the field `default`. */ final DefaultKeyword getDefault() { swift_switch_entry_default(this, result) } @@ -2979,15 +2979,18 @@ module Swift { /** Gets the node corresponding to the field `pattern`. */ final SwitchPattern getPattern(int i) { swift_switch_entry_pattern(this, i, result) } + /** Gets the node corresponding to the field `statement`. */ + final AstNode getStatement(int i) { swift_switch_entry_statement(this, i, result) } + /** Gets the node corresponding to the field `where`. */ final WhereClause getWhere() { swift_switch_entry_where(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_switch_entry_def(this, result) or swift_switch_entry_default(this, result) or swift_switch_entry_modifiers(this, result) or swift_switch_entry_pattern(this, _, result) or + swift_switch_entry_statement(this, _, result) or swift_switch_entry_where(this, result) } } @@ -3095,15 +3098,28 @@ module Swift { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TupleExpression" } + /** Gets the node corresponding to the field `element`. */ + final TupleExpressionItem getElement(int i) { swift_tuple_expression_element(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_tuple_expression_element(this, _, result) } + } + + /** A class representing `tuple_expression_item` nodes. */ + class TupleExpressionItem extends @swift_tuple_expression_item, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "TupleExpressionItem" } + /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_tuple_expression_name(this, i, result) } + final SimpleIdentifier getName() { swift_tuple_expression_item_name(this, result) } /** Gets the node corresponding to the field `value`. */ - final Expression getValue(int i) { swift_tuple_expression_value(this, i, result) } + final Expression getValue() { swift_tuple_expression_item_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_tuple_expression_name(this, _, result) or swift_tuple_expression_value(this, _, result) + swift_tuple_expression_item_name(this, result) or + swift_tuple_expression_item_def(this, result) } } @@ -3533,14 +3549,14 @@ module Swift { final override string getAPrimaryQlClass() { result = "WhileStatement" } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_while_statement_body(this, result) } + final Block getBody() { swift_while_statement_def(this, result) } /** Gets the node corresponding to the field `condition`. */ final IfCondition getCondition(int i) { swift_while_statement_condition(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_while_statement_body(this, result) or swift_while_statement_condition(this, _, result) + swift_while_statement_def(this, result) or swift_while_statement_condition(this, _, result) } } @@ -3556,7 +3572,7 @@ module Swift { final override string getAPrimaryQlClass() { result = "WillsetClause" } /** Gets the node corresponding to the field `body`. */ - final Statements getBody() { swift_willset_clause_body(this, result) } + final Block getBody() { swift_willset_clause_def(this, result) } /** Gets the node corresponding to the field `modifiers`. */ final Modifiers getModifiers() { swift_willset_clause_modifiers(this, result) } @@ -3566,7 +3582,7 @@ module Swift { /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_willset_clause_body(this, result) or + swift_willset_clause_def(this, result) or swift_willset_clause_modifiers(this, result) or swift_willset_clause_parameter(this, result) } diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme index 0c3f023b001..5cf748c1571 100644 --- a/unified/ql/lib/unified.dbscheme +++ b/unified/ql/lib/unified.dbscheme @@ -295,6 +295,19 @@ swift_bitwise_operation_def( int rhs: @swift_expression ref ); +@swift_block_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement + +#keyset[swift_block, index] +swift_block_statement( + int swift_block: @swift_block ref, + int index: int ref, + unique int statement: @swift_block_statement_type ref +); + +swift_block_def( + unique int id: @swift_block +); + swift_call_expression_def( unique int id: @swift_call_expression, int function: @swift_expression ref, @@ -367,11 +380,6 @@ swift_case_pattern_def( int name: @swift_token_simple_identifier ref ); -swift_catch_block_body( - unique int swift_catch_block: @swift_catch_block ref, - unique int body: @swift_statements ref -); - swift_catch_block_error( unique int swift_catch_block: @swift_catch_block ref, unique int error: @swift_pattern ref @@ -384,6 +392,7 @@ swift_catch_block_where( swift_catch_block_def( unique int id: @swift_catch_block, + int body: @swift_block ref, int keyword: @swift_token_catch_keyword ref ); @@ -530,7 +539,7 @@ swift_computed_getter_attribute( swift_computed_getter_body( unique int swift_computed_getter: @swift_computed_getter ref, - unique int body: @swift_statements ref + unique int body: @swift_block ref ); swift_computed_getter_def( @@ -547,7 +556,7 @@ swift_computed_modify_attribute( swift_computed_modify_body( unique int swift_computed_modify: @swift_computed_modify ref, - unique int body: @swift_statements ref + unique int body: @swift_block ref ); swift_computed_modify_def( @@ -564,9 +573,13 @@ swift_computed_property_accessor( unique int accessor: @swift_computed_property_accessor_type ref ); -swift_computed_property_body( - unique int swift_computed_property: @swift_computed_property ref, - unique int body: @swift_statements ref +@swift_computed_property_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement + +#keyset[swift_computed_property, index] +swift_computed_property_statement( + int swift_computed_property: @swift_computed_property ref, + int index: int ref, + unique int statement: @swift_computed_property_statement_type ref ); swift_computed_property_def( @@ -582,7 +595,7 @@ swift_computed_setter_attribute( swift_computed_setter_body( unique int swift_computed_setter: @swift_computed_setter ref, - unique int body: @swift_statements ref + unique int body: @swift_block ref ); swift_computed_setter_parameter( @@ -657,7 +670,7 @@ swift_deinit_declaration_modifiers( swift_deinit_declaration_def( unique int id: @swift_deinit_declaration, - int body: @swift_function_body ref + int body: @swift_block ref ); @swift_deprecated_operator_declaration_body_entry_type = @swift_line_string_literal | @swift_multi_line_string_literal | @swift_raw_string_literal | @swift_reserved_word | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_simple_identifier @@ -674,34 +687,28 @@ swift_deprecated_operator_declaration_body_def( ); #keyset[swift_dictionary_literal, index] -swift_dictionary_literal_key( +swift_dictionary_literal_element( int swift_dictionary_literal: @swift_dictionary_literal ref, int index: int ref, - unique int key__: @swift_expression ref -); - -#keyset[swift_dictionary_literal, index] -swift_dictionary_literal_value( - int swift_dictionary_literal: @swift_dictionary_literal ref, - int index: int ref, - unique int value: @swift_expression ref + unique int element: @swift_dictionary_literal_item ref ); swift_dictionary_literal_def( unique int id: @swift_dictionary_literal ); +swift_dictionary_literal_item_def( + unique int id: @swift_dictionary_literal_item, + int key__: @swift_expression ref, + int value: @swift_expression ref +); + swift_dictionary_type_def( unique int id: @swift_dictionary_type, int key__: @swift_type__ ref, int value: @swift_type__ ref ); -swift_didset_clause_body( - unique int swift_didset_clause: @swift_didset_clause ref, - unique int body: @swift_statements ref -); - swift_didset_clause_modifiers( unique int swift_didset_clause: @swift_didset_clause ref, unique int modifiers: @swift_modifiers ref @@ -713,7 +720,8 @@ swift_didset_clause_parameter( ); swift_didset_clause_def( - unique int id: @swift_didset_clause + unique int id: @swift_didset_clause, + int body: @swift_block ref ); swift_directive_condition( @@ -742,11 +750,6 @@ swift_disjunction_expression_def( int rhs: @swift_expression ref ); -swift_do_statement_body( - unique int swift_do_statement: @swift_do_statement ref, - unique int body: @swift_statements ref -); - #keyset[swift_do_statement, index] swift_do_statement_catch( int swift_do_statement: @swift_do_statement ref, @@ -755,7 +758,23 @@ swift_do_statement_catch( ); swift_do_statement_def( - unique int id: @swift_do_statement + unique int id: @swift_do_statement, + int body: @swift_block ref +); + +swift_enum_case_entry_data_contents( + unique int swift_enum_case_entry: @swift_enum_case_entry ref, + unique int data_contents: @swift_enum_type_parameters ref +); + +swift_enum_case_entry_raw_value( + unique int swift_enum_case_entry: @swift_enum_case_entry ref, + unique int raw_value: @swift_expression ref +); + +swift_enum_case_entry_def( + unique int id: @swift_enum_case_entry, + int name: @swift_token_simple_identifier ref ); @swift_enum_class_body_member_type = @swift_enum_entry | @swift_type_level_declaration @@ -772,10 +791,10 @@ swift_enum_class_body_def( ); #keyset[swift_enum_entry, index] -swift_enum_entry_data_contents( +swift_enum_entry_case( int swift_enum_entry: @swift_enum_entry ref, int index: int ref, - unique int data_contents: @swift_enum_type_parameters ref + unique int case__: @swift_enum_case_entry ref ); swift_enum_entry_modifiers( @@ -783,20 +802,6 @@ swift_enum_entry_modifiers( unique int modifiers: @swift_modifiers ref ); -#keyset[swift_enum_entry, index] -swift_enum_entry_name( - int swift_enum_entry: @swift_enum_entry ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -#keyset[swift_enum_entry, index] -swift_enum_entry_raw_value( - int swift_enum_entry: @swift_enum_entry ref, - int index: int ref, - unique int raw_value: @swift_expression ref -); - swift_enum_entry_def( unique int id: @swift_enum_entry ); @@ -874,11 +879,6 @@ swift_external_macro_definition_def( int arguments: @swift_value_arguments ref ); -swift_for_statement_body( - unique int swift_for_statement: @swift_for_statement ref, - unique int body: @swift_statements ref -); - swift_for_statement_try( unique int swift_for_statement: @swift_for_statement ref, unique int try: @swift_token_try_operator ref @@ -896,38 +896,16 @@ swift_for_statement_where( swift_for_statement_def( unique int id: @swift_for_statement, + int body: @swift_block ref, int collection: @swift_expression ref, int item: @swift_pattern ref ); -swift_function_body_body( - unique int swift_function_body: @swift_function_body ref, - unique int body: @swift_statements ref -); - -swift_function_body_def( - unique int id: @swift_function_body -); - swift_function_declaration_async( unique int swift_function_declaration: @swift_function_declaration ref, unique int async: @swift_reserved_word ref ); -#keyset[swift_function_declaration, index] -swift_function_declaration_attribute( - int swift_function_declaration: @swift_function_declaration ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -#keyset[swift_function_declaration, index] -swift_function_declaration_default_value( - int swift_function_declaration: @swift_function_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - @swift_function_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier #keyset[swift_function_declaration, index] @@ -943,7 +921,7 @@ swift_function_declaration_modifiers( swift_function_declaration_parameter( int swift_function_declaration: @swift_function_declaration ref, int index: int ref, - unique int parameter: @swift_parameter ref + unique int parameter: @swift_function_parameter ref ); @swift_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ @@ -972,10 +950,25 @@ swift_function_declaration_type_parameters( swift_function_declaration_def( unique int id: @swift_function_declaration, - int body: @swift_function_body ref, + int body: @swift_block ref, int name: @swift_function_declaration_name_type ref ); +swift_function_parameter_attribute( + unique int swift_function_parameter: @swift_function_parameter ref, + unique int attribute: @swift_attribute ref +); + +swift_function_parameter_default_value( + unique int swift_function_parameter: @swift_function_parameter ref, + unique int default_value: @swift_expression ref +); + +swift_function_parameter_def( + unique int id: @swift_function_parameter, + int parameter: @swift_parameter ref +); + swift_function_type_async( unique int swift_function_type: @swift_function_type ref, unique int async: @swift_reserved_word ref @@ -1014,11 +1007,6 @@ swift_getter_specifier_def( @swift_global_declaration = @swift_associatedtype_declaration | @swift_class_declaration | @swift_function_declaration | @swift_import_declaration | @swift_init_declaration | @swift_macro_declaration | @swift_operator_declaration | @swift_precedence_group_declaration | @swift_property_declaration | @swift_protocol_declaration | @swift_typealias_declaration -swift_guard_statement_body( - unique int swift_guard_statement: @swift_guard_statement ref, - unique int body: @swift_statements ref -); - #keyset[swift_guard_statement, index] swift_guard_statement_condition( int swift_guard_statement: @swift_guard_statement ref, @@ -1028,7 +1016,7 @@ swift_guard_statement_condition( swift_guard_statement_def( unique int id: @swift_guard_statement, - int else_keyword: @swift_token_else ref + int body: @swift_block ref ); #keyset[swift_identifier, index] @@ -1069,13 +1057,6 @@ swift_if_let_binding_def( int pattern: @swift_pattern ref ); -#keyset[swift_if_statement, index] -swift_if_statement_body( - int swift_if_statement: @swift_if_statement ref, - int index: int ref, - unique int body: @swift_statements ref -); - #keyset[swift_if_statement, index] swift_if_statement_condition( int swift_if_statement: @swift_if_statement ref, @@ -1083,18 +1064,16 @@ swift_if_statement_condition( unique int condition: @swift_if_condition ref ); +@swift_if_statement_else_branch_type = @swift_block | @swift_if_statement + swift_if_statement_else_branch( unique int swift_if_statement: @swift_if_statement ref, - unique int else_branch: @swift_if_statement ref -); - -swift_if_statement_else_keyword( - unique int swift_if_statement: @swift_if_statement ref, - unique int else_keyword: @swift_token_else ref + unique int else_branch: @swift_if_statement_else_branch_type ref ); swift_if_statement_def( - unique int id: @swift_if_statement + unique int id: @swift_if_statement, + int body: @swift_block ref ); swift_implicitly_unwrapped_type_def( @@ -1148,13 +1127,6 @@ swift_init_declaration_async( unique int async: @swift_reserved_word ref ); -#keyset[swift_init_declaration, index] -swift_init_declaration_attribute( - int swift_init_declaration: @swift_init_declaration ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - swift_init_declaration_bang( unique int swift_init_declaration: @swift_init_declaration ref, unique int bang: @swift_token_bang ref @@ -1162,14 +1134,7 @@ swift_init_declaration_bang( swift_init_declaration_body( unique int swift_init_declaration: @swift_init_declaration ref, - unique int body: @swift_function_body ref -); - -#keyset[swift_init_declaration, index] -swift_init_declaration_default_value( - int swift_init_declaration: @swift_init_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref + unique int body: @swift_block ref ); swift_init_declaration_modifiers( @@ -1177,16 +1142,11 @@ swift_init_declaration_modifiers( unique int modifiers: @swift_modifiers ref ); -case @swift_init_declaration.name of - 0 = @swift_init_declaration_init -; - - #keyset[swift_init_declaration, index] swift_init_declaration_parameter( int swift_init_declaration: @swift_init_declaration ref, int index: int ref, - unique int parameter: @swift_parameter ref + unique int parameter: @swift_function_parameter ref ); @swift_init_declaration_throws_type = @swift_throws_clause | @swift_token_throws @@ -1207,8 +1167,7 @@ swift_init_declaration_type_parameters( ); swift_init_declaration_def( - unique int id: @swift_init_declaration, - int name: int ref + unique int id: @swift_init_declaration ); swift_interpolated_expression_name( @@ -1338,16 +1297,20 @@ swift_lambda_literal_attribute( unique int attribute: @swift_attribute ref ); -swift_lambda_literal_body( - unique int swift_lambda_literal: @swift_lambda_literal ref, - unique int body: @swift_statements ref -); - swift_lambda_literal_captures( unique int swift_lambda_literal: @swift_lambda_literal ref, unique int captures: @swift_capture_list ref ); +@swift_lambda_literal_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement + +#keyset[swift_lambda_literal, index] +swift_lambda_literal_statement( + int swift_lambda_literal: @swift_lambda_literal ref, + int index: int ref, + unique int statement: @swift_lambda_literal_statement_type ref +); + swift_lambda_literal_type( unique int swift_lambda_literal: @swift_lambda_literal ref, unique int type__: @swift_lambda_function_type ref @@ -1403,20 +1366,6 @@ swift_line_string_literal_def( @swift_local_declaration = @swift_class_declaration | @swift_function_declaration | @swift_property_declaration | @swift_typealias_declaration -#keyset[swift_macro_declaration, index] -swift_macro_declaration_attribute( - int swift_macro_declaration: @swift_macro_declaration ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -#keyset[swift_macro_declaration, index] -swift_macro_declaration_default_value( - int swift_macro_declaration: @swift_macro_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - swift_macro_declaration_definition( unique int swift_macro_declaration: @swift_macro_declaration ref, unique int definition: @swift_macro_definition ref @@ -1431,7 +1380,7 @@ swift_macro_declaration_modifiers( swift_macro_declaration_parameter( int swift_macro_declaration: @swift_macro_declaration ref, int index: int ref, - unique int parameter: @swift_parameter ref + unique int parameter: @swift_function_parameter ref ); swift_macro_declaration_return_type( @@ -1670,21 +1619,28 @@ swift_pattern_def( ); #keyset[swift_playground_literal, index] -swift_playground_literal_name( +swift_playground_literal_argument( int swift_playground_literal: @swift_playground_literal ref, int index: int ref, - unique int name: @swift_token_simple_identifier ref + unique int argument: @swift_playground_literal_argument ref ); -#keyset[swift_playground_literal, index] -swift_playground_literal_value( - int swift_playground_literal: @swift_playground_literal ref, - int index: int ref, - unique int value: @swift_expression ref -); +case @swift_playground_literal.kind of + 0 = @swift_playground_literal_color_literal +| 1 = @swift_playground_literal_file_literal +| 2 = @swift_playground_literal_image_literal +; + swift_playground_literal_def( - unique int id: @swift_playground_literal + unique int id: @swift_playground_literal, + int kind: int ref +); + +swift_playground_literal_argument_def( + unique int id: @swift_playground_literal_argument, + int name: @swift_token_simple_identifier ref, + int value: @swift_expression ref ); @swift_postfix_expression_operation_type = @swift_reserved_word | @swift_token_bang @@ -1732,11 +1688,41 @@ swift_prefix_expression_def( int target: @swift_expression ref ); +swift_property_binding_computed_value( + unique int swift_property_binding: @swift_property_binding ref, + unique int computed_value: @swift_computed_property ref +); + +swift_property_binding_observers( + unique int swift_property_binding: @swift_property_binding ref, + unique int observers: @swift_willset_didset_block ref +); + +swift_property_binding_type( + unique int swift_property_binding: @swift_property_binding ref, + unique int type__: @swift_type_annotation ref +); + +swift_property_binding_type_constraints( + unique int swift_property_binding: @swift_property_binding ref, + unique int type_constraints: @swift_type_constraints ref +); + +swift_property_binding_value( + unique int swift_property_binding: @swift_property_binding ref, + unique int value: @swift_expression ref +); + +swift_property_binding_def( + unique int id: @swift_property_binding, + int name: @swift_pattern ref +); + #keyset[swift_property_declaration, index] -swift_property_declaration_computed_value( +swift_property_declaration_declarator( int swift_property_declaration: @swift_property_declaration ref, int index: int ref, - unique int computed_value: @swift_computed_property ref + unique int declarator: @swift_property_binding ref ); @swift_property_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier @@ -1748,41 +1734,6 @@ swift_property_declaration_modifiers( unique int modifiers: @swift_property_declaration_modifiers_type ref ); -#keyset[swift_property_declaration, index] -swift_property_declaration_name( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int name: @swift_pattern ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_observers( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int observers: @swift_willset_didset_block ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_type( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int type__: @swift_type_annotation ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_type_constraints( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int type_constraints: @swift_type_constraints ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_value( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int value: @swift_expression ref -); - swift_property_declaration_def( unique int id: @swift_property_declaration, int binding: @swift_value_binding_pattern ref @@ -1817,11 +1768,6 @@ swift_protocol_declaration_attribute( unique int attribute: @swift_attribute ref ); -case @swift_protocol_declaration.declaration_kind of - 0 = @swift_protocol_declaration_protocol -; - - #keyset[swift_protocol_declaration, index] swift_protocol_declaration_inherits( int swift_protocol_declaration: @swift_protocol_declaration ref, @@ -1847,7 +1793,6 @@ swift_protocol_declaration_type_parameters( swift_protocol_declaration_def( unique int id: @swift_protocol_declaration, int body: @swift_protocol_body ref, - int declaration_kind: int ref, int name: @swift_token_type_identifier ref ); @@ -1856,23 +1801,9 @@ swift_protocol_function_declaration_async( unique int async: @swift_reserved_word ref ); -#keyset[swift_protocol_function_declaration, index] -swift_protocol_function_declaration_attribute( - int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - swift_protocol_function_declaration_body( unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int body: @swift_function_body ref -); - -#keyset[swift_protocol_function_declaration, index] -swift_protocol_function_declaration_default_value( - int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref + unique int body: @swift_block ref ); swift_protocol_function_declaration_modifiers( @@ -1886,7 +1817,7 @@ swift_protocol_function_declaration_modifiers( swift_protocol_function_declaration_parameter( int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, int index: int ref, - unique int parameter: @swift_parameter ref + unique int parameter: @swift_function_parameter ref ); @swift_protocol_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ @@ -2013,11 +1944,6 @@ swift_referenceable_operator_def( int operator: @swift_referenceable_operator_operator_type ref ); -swift_repeat_while_statement_body( - unique int swift_repeat_while_statement: @swift_repeat_while_statement ref, - unique int body: @swift_statements ref -); - #keyset[swift_repeat_while_statement, index] swift_repeat_while_statement_condition( int swift_repeat_while_statement: @swift_repeat_while_statement ref, @@ -2026,7 +1952,8 @@ swift_repeat_while_statement_condition( ); swift_repeat_while_statement_def( - unique int id: @swift_repeat_while_statement + unique int id: @swift_repeat_while_statement, + int body: @swift_block ref ); swift_selector_expression_def( @@ -2071,33 +1998,6 @@ swift_source_file_def( unique int id: @swift_source_file ); -@swift_statements_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement - -#keyset[swift_statements, index] -swift_statements_statement( - int swift_statements: @swift_statements ref, - int index: int ref, - unique int statement: @swift_statements_statement_type ref -); - -swift_statements_def( - unique int id: @swift_statements -); - -#keyset[swift_subscript_declaration, index] -swift_subscript_declaration_attribute( - int swift_subscript_declaration: @swift_subscript_declaration ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -#keyset[swift_subscript_declaration, index] -swift_subscript_declaration_default_value( - int swift_subscript_declaration: @swift_subscript_declaration ref, - int index: int ref, - unique int default_value: @swift_expression ref -); - swift_subscript_declaration_modifiers( unique int swift_subscript_declaration: @swift_subscript_declaration ref, unique int modifiers: @swift_modifiers ref @@ -2107,7 +2007,7 @@ swift_subscript_declaration_modifiers( swift_subscript_declaration_parameter( int swift_subscript_declaration: @swift_subscript_declaration ref, int index: int ref, - unique int parameter: @swift_parameter ref + unique int parameter: @swift_function_parameter ref ); @swift_subscript_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ @@ -2154,14 +2054,22 @@ swift_switch_entry_pattern( unique int pattern: @swift_switch_pattern ref ); +@swift_switch_entry_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement + +#keyset[swift_switch_entry, index] +swift_switch_entry_statement( + int swift_switch_entry: @swift_switch_entry ref, + int index: int ref, + unique int statement: @swift_switch_entry_statement_type ref +); + swift_switch_entry_where( unique int swift_switch_entry: @swift_switch_entry ref, unique int where: @swift_where_clause ref ); swift_switch_entry_def( - unique int id: @swift_switch_entry, - int body: @swift_statements ref + unique int id: @swift_switch_entry ); swift_switch_pattern_def( @@ -2200,23 +2108,26 @@ swift_try_expression_def( ); #keyset[swift_tuple_expression, index] -swift_tuple_expression_name( +swift_tuple_expression_element( int swift_tuple_expression: @swift_tuple_expression ref, int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -#keyset[swift_tuple_expression, index] -swift_tuple_expression_value( - int swift_tuple_expression: @swift_tuple_expression ref, - int index: int ref, - unique int value: @swift_expression ref + unique int element: @swift_tuple_expression_item ref ); swift_tuple_expression_def( unique int id: @swift_tuple_expression ); +swift_tuple_expression_item_name( + unique int swift_tuple_expression_item: @swift_tuple_expression_item ref, + unique int name: @swift_token_simple_identifier ref +); + +swift_tuple_expression_item_def( + unique int id: @swift_tuple_expression_item, + int value: @swift_expression ref +); + #keyset[swift_tuple_pattern, index] swift_tuple_pattern_item( int swift_tuple_pattern: @swift_tuple_pattern ref, @@ -2497,11 +2408,6 @@ swift_where_clause_def( int keyword: @swift_token_where_keyword ref ); -swift_while_statement_body( - unique int swift_while_statement: @swift_while_statement ref, - unique int body: @swift_statements ref -); - #keyset[swift_while_statement, index] swift_while_statement_condition( int swift_while_statement: @swift_while_statement ref, @@ -2510,12 +2416,8 @@ swift_while_statement_condition( ); swift_while_statement_def( - unique int id: @swift_while_statement -); - -swift_willset_clause_body( - unique int swift_willset_clause: @swift_willset_clause ref, - unique int body: @swift_statements ref + unique int id: @swift_while_statement, + int body: @swift_block ref ); swift_willset_clause_modifiers( @@ -2529,7 +2431,8 @@ swift_willset_clause_parameter( ); swift_willset_clause_def( - unique int id: @swift_willset_clause + unique int id: @swift_willset_clause, + int body: @swift_block ref ); swift_willset_didset_block_didset( @@ -2564,46 +2467,45 @@ case @swift_token.kind of | 8 = @swift_token_custom_operator | 9 = @swift_token_default_keyword | 10 = @swift_token_diagnostic -| 11 = @swift_token_else -| 12 = @swift_token_fully_open_range -| 13 = @swift_token_function_modifier -| 14 = @swift_token_hex_literal -| 15 = @swift_token_inheritance_modifier -| 16 = @swift_token_integer_literal -| 17 = @swift_token_line_str_text -| 18 = @swift_token_member_modifier -| 19 = @swift_token_multi_line_str_text -| 20 = @swift_token_multiline_comment -| 21 = @swift_token_mutation_modifier -| 22 = @swift_token_oct_literal -| 23 = @swift_token_ownership_modifier -| 24 = @swift_token_parameter_modifier -| 25 = @swift_token_property_behavior_modifier -| 26 = @swift_token_property_modifier -| 27 = @swift_token_raw_str_continuing_indicator -| 28 = @swift_token_raw_str_end_part -| 29 = @swift_token_raw_str_interpolation_start -| 30 = @swift_token_raw_str_part -| 31 = @swift_token_real_literal -| 32 = @swift_token_regex_literal -| 33 = @swift_token_self_expression -| 34 = @swift_token_shebang_line -| 35 = @swift_token_simple_identifier -| 36 = @swift_token_special_literal -| 37 = @swift_token_statement_label -| 38 = @swift_token_str_escaped_char -| 39 = @swift_token_super_expression -| 40 = @swift_token_throw_keyword -| 41 = @swift_token_throws -| 42 = @swift_token_try_operator -| 43 = @swift_token_type_identifier -| 44 = @swift_token_visibility_modifier -| 45 = @swift_token_where_keyword -| 46 = @swift_token_wildcard_pattern +| 11 = @swift_token_fully_open_range +| 12 = @swift_token_function_modifier +| 13 = @swift_token_hex_literal +| 14 = @swift_token_inheritance_modifier +| 15 = @swift_token_integer_literal +| 16 = @swift_token_line_str_text +| 17 = @swift_token_member_modifier +| 18 = @swift_token_multi_line_str_text +| 19 = @swift_token_multiline_comment +| 20 = @swift_token_mutation_modifier +| 21 = @swift_token_oct_literal +| 22 = @swift_token_ownership_modifier +| 23 = @swift_token_parameter_modifier +| 24 = @swift_token_property_behavior_modifier +| 25 = @swift_token_property_modifier +| 26 = @swift_token_raw_str_continuing_indicator +| 27 = @swift_token_raw_str_end_part +| 28 = @swift_token_raw_str_interpolation_start +| 29 = @swift_token_raw_str_part +| 30 = @swift_token_real_literal +| 31 = @swift_token_regex_literal +| 32 = @swift_token_self_expression +| 33 = @swift_token_shebang_line +| 34 = @swift_token_simple_identifier +| 35 = @swift_token_special_literal +| 36 = @swift_token_statement_label +| 37 = @swift_token_str_escaped_char +| 38 = @swift_token_super_expression +| 39 = @swift_token_throw_keyword +| 40 = @swift_token_throws +| 41 = @swift_token_try_operator +| 42 = @swift_token_type_identifier +| 43 = @swift_token_visibility_modifier +| 44 = @swift_token_where_keyword +| 45 = @swift_token_wildcard_pattern ; -@swift_ast_node = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_associatedtype_declaration | @swift_attribute | @swift_availability_condition | @swift_await_expression | @swift_binding_pattern | @swift_bitwise_operation | @swift_call_expression | @swift_call_suffix | @swift_capture_list | @swift_capture_list_item | @swift_case_pattern | @swift_catch_block | @swift_check_expression | @swift_class_body | @swift_class_declaration | @swift_comparison_expression | @swift_compilation_condition | @swift_computed_getter | @swift_computed_modify | @swift_computed_property | @swift_computed_setter | @swift_conjunction_expression | @swift_constructor_expression | @swift_constructor_suffix | @swift_control_transfer_statement | @swift_deinit_declaration | @swift_deprecated_operator_declaration_body | @swift_dictionary_literal | @swift_dictionary_type | @swift_didset_clause | @swift_directive | @swift_directly_assignable_expression | @swift_disjunction_expression | @swift_do_statement | @swift_enum_class_body | @swift_enum_entry | @swift_enum_type_parameter | @swift_enum_type_parameters | @swift_equality_constraint | @swift_equality_expression | @swift_existential_type | @swift_external_macro_definition | @swift_for_statement | @swift_function_body | @swift_function_declaration | @swift_function_type | @swift_getter_specifier | @swift_guard_statement | @swift_identifier | @swift_if_condition | @swift_if_let_binding | @swift_if_statement | @swift_implicitly_unwrapped_type | @swift_import_declaration | @swift_infix_expression | @swift_inheritance_constraint | @swift_inheritance_specifier | @swift_init_declaration | @swift_interpolated_expression | @swift_key_path_component | @swift_key_path_expression | @swift_key_path_postfix | @swift_key_path_string_expression | @swift_lambda_function_type | @swift_lambda_function_type_parameters | @swift_lambda_literal | @swift_lambda_parameter | @swift_line_string_literal | @swift_macro_declaration | @swift_macro_definition | @swift_macro_invocation | @swift_metatype | @swift_modifiers | @swift_modify_specifier | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_navigation_suffix | @swift_nested_type_identifier | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_operator_declaration | @swift_optional_chain_marker | @swift_optional_type | @swift_parameter | @swift_parameter_modifiers | @swift_parenthesized_type | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_precedence_group_attribute | @swift_precedence_group_attributes | @swift_precedence_group_declaration | @swift_prefix_expression | @swift_property_declaration | @swift_protocol_body | @swift_protocol_composition_type | @swift_protocol_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_protocol_property_requirements | @swift_range_expression | @swift_raw_str_interpolation | @swift_raw_string_literal | @swift_referenceable_operator | @swift_repeat_while_statement | @swift_selector_expression | @swift_setter_specifier | @swift_simple_user_type | @swift_source_file | @swift_statements | @swift_subscript_declaration | @swift_suppressed_constraint | @swift_switch_entry | @swift_switch_pattern | @swift_switch_statement | @swift_ternary_expression | @swift_throws_clause | @swift_token | @swift_try_expression | @swift_tuple_expression | @swift_tuple_pattern | @swift_tuple_pattern_item | @swift_tuple_type | @swift_tuple_type_item | @swift_type__ | @swift_type_annotation | @swift_type_arguments | @swift_type_casting_pattern | @swift_type_constraint | @swift_type_constraints | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter | @swift_type_parameter_modifiers | @swift_type_parameter_pack | @swift_type_parameters | @swift_typealias_declaration | @swift_user_type | @swift_value_argument | @swift_value_argument_label | @swift_value_arguments | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause | @swift_while_statement | @swift_willset_clause | @swift_willset_didset_block +@swift_ast_node = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_associatedtype_declaration | @swift_attribute | @swift_availability_condition | @swift_await_expression | @swift_binding_pattern | @swift_bitwise_operation | @swift_block | @swift_call_expression | @swift_call_suffix | @swift_capture_list | @swift_capture_list_item | @swift_case_pattern | @swift_catch_block | @swift_check_expression | @swift_class_body | @swift_class_declaration | @swift_comparison_expression | @swift_compilation_condition | @swift_computed_getter | @swift_computed_modify | @swift_computed_property | @swift_computed_setter | @swift_conjunction_expression | @swift_constructor_expression | @swift_constructor_suffix | @swift_control_transfer_statement | @swift_deinit_declaration | @swift_deprecated_operator_declaration_body | @swift_dictionary_literal | @swift_dictionary_literal_item | @swift_dictionary_type | @swift_didset_clause | @swift_directive | @swift_directly_assignable_expression | @swift_disjunction_expression | @swift_do_statement | @swift_enum_case_entry | @swift_enum_class_body | @swift_enum_entry | @swift_enum_type_parameter | @swift_enum_type_parameters | @swift_equality_constraint | @swift_equality_expression | @swift_existential_type | @swift_external_macro_definition | @swift_for_statement | @swift_function_declaration | @swift_function_parameter | @swift_function_type | @swift_getter_specifier | @swift_guard_statement | @swift_identifier | @swift_if_condition | @swift_if_let_binding | @swift_if_statement | @swift_implicitly_unwrapped_type | @swift_import_declaration | @swift_infix_expression | @swift_inheritance_constraint | @swift_inheritance_specifier | @swift_init_declaration | @swift_interpolated_expression | @swift_key_path_component | @swift_key_path_expression | @swift_key_path_postfix | @swift_key_path_string_expression | @swift_lambda_function_type | @swift_lambda_function_type_parameters | @swift_lambda_literal | @swift_lambda_parameter | @swift_line_string_literal | @swift_macro_declaration | @swift_macro_definition | @swift_macro_invocation | @swift_metatype | @swift_modifiers | @swift_modify_specifier | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_navigation_suffix | @swift_nested_type_identifier | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_operator_declaration | @swift_optional_chain_marker | @swift_optional_type | @swift_parameter | @swift_parameter_modifiers | @swift_parenthesized_type | @swift_pattern | @swift_playground_literal | @swift_playground_literal_argument | @swift_postfix_expression | @swift_precedence_group_attribute | @swift_precedence_group_attributes | @swift_precedence_group_declaration | @swift_prefix_expression | @swift_property_binding | @swift_property_declaration | @swift_protocol_body | @swift_protocol_composition_type | @swift_protocol_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_protocol_property_requirements | @swift_range_expression | @swift_raw_str_interpolation | @swift_raw_string_literal | @swift_referenceable_operator | @swift_repeat_while_statement | @swift_selector_expression | @swift_setter_specifier | @swift_simple_user_type | @swift_source_file | @swift_subscript_declaration | @swift_suppressed_constraint | @swift_switch_entry | @swift_switch_pattern | @swift_switch_statement | @swift_ternary_expression | @swift_throws_clause | @swift_token | @swift_try_expression | @swift_tuple_expression | @swift_tuple_expression_item | @swift_tuple_pattern | @swift_tuple_pattern_item | @swift_tuple_type | @swift_tuple_type_item | @swift_type__ | @swift_type_annotation | @swift_type_arguments | @swift_type_casting_pattern | @swift_type_constraint | @swift_type_constraints | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter | @swift_type_parameter_modifiers | @swift_type_parameter_pack | @swift_type_parameters | @swift_typealias_declaration | @swift_user_type | @swift_value_argument | @swift_value_argument_label | @swift_value_arguments | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause | @swift_while_statement | @swift_willset_clause | @swift_willset_didset_block swift_ast_node_location( unique int node: @swift_ast_node ref, From cb0fc786c74e282d985a2dda66628614dceddbb3 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 18 May 2026 13:05:14 +0200 Subject: [PATCH 075/226] Ruby: Minor cleanup, Callable is a StmtSequence. --- ruby/ql/lib/codeql/ruby/ast/Method.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/Method.qll b/ruby/ql/lib/codeql/ruby/ast/Method.qll index 147782e3d08..1594b6e6311 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Method.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Method.qll @@ -342,7 +342,7 @@ class Lambda extends Callable, BodyStmt, TLambda { } /** A block. */ -class Block extends Callable, StmtSequence, Scope, TBlock { +class Block extends Callable, Scope, TBlock { /** * Gets a local variable declared by this block. * For example `local` in `{ | param; local| puts param }`. @@ -358,8 +358,6 @@ class Block extends Callable, StmtSequence, Scope, TBlock { override AstNode getAChild(string pred) { result = Callable.super.getAChild(pred) or - result = StmtSequence.super.getAChild(pred) - or pred = "getLocalVariable" and result = this.getLocalVariable(_) } } From 42aaae7cf3ff429d2ae47691d2c324e2c2984da1 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 May 2026 09:27:55 +0200 Subject: [PATCH 076/226] C#: Add test case for property calls and update test expected for other files. --- .../properties/PrintAst.expected | 47 +++++++++++++++++++ .../properties/Properties17.expected | 1 + .../properties/Properties19.expected | 7 +++ .../library-tests/properties/Properties19.ql | 8 ++++ .../library-tests/properties/properties.cs | 27 +++++++++++ 5 files changed, 90 insertions(+) create mode 100644 csharp/ql/test/library-tests/properties/Properties19.expected create mode 100644 csharp/ql/test/library-tests/properties/Properties19.ql diff --git a/csharp/ql/test/library-tests/properties/PrintAst.expected b/csharp/ql/test/library-tests/properties/PrintAst.expected index 711e417558e..ef482ed33d0 100644 --- a/csharp/ql/test/library-tests/properties/PrintAst.expected +++ b/csharp/ql/test/library-tests/properties/PrintAst.expected @@ -246,3 +246,50 @@ properties.cs: # 133| 0: [FieldAccess] access to field Prop.field # 133| 1: [ParameterAccess] access to parameter value # 130| 7: [Field] Prop.field +# 137| 11: [RefStruct] S +# 139| 6: [Field] x +# 139| -1: [TypeMention] int +# 141| 7: [InstanceConstructor] S +#-----| 2: (Parameters) +# 141| 0: [Parameter] v +# 141| -1: [TypeMention] int +# 142| 4: [BlockStmt] {...} +# 143| 0: [ExprStmt] ...; +# 143| 0: [AssignExpr] ... = ... +# 143| 0: [FieldAccess] access to field x +# 143| 1: [RefExpr] ref ... +# 143| 0: [ParameterAccess] access to parameter v +# 146| 8: [Property] Prop +# 146| -1: [TypeMention] int +# 148| 3: [Getter] get_Prop +# 148| 4: [BlockStmt] {...} +# 148| 0: [ReturnStmt] return ...; +# 148| 0: [RefExpr] ref ... +# 148| 0: [FieldAccess] access to field x +# 152| 12: [Class] TestRefReturns +# 154| 6: [Method] M +# 154| -1: [TypeMention] Void +# 155| 4: [BlockStmt] {...} +# 156| 0: [LocalVariableDeclStmt] ... ...; +# 156| 0: [LocalVariableDeclAndInitExpr] Int32 a = ... +# 156| -1: [TypeMention] int +# 156| 0: [LocalVariableAccess] access to local variable a +# 156| 1: [IntLiteral] 0 +# 158| 1: [LocalVariableDeclStmt] ... ...; +# 158| 0: [LocalVariableDeclAndInitExpr] S s = ... +# 158| -1: [TypeMention] S +# 158| 0: [LocalVariableAccess] access to local variable s +# 158| 1: [ObjectCreation] object creation of type S +# 158| -1: [TypeMention] S +# 158| 0: [LocalVariableAccess] access to local variable a +# 159| 2: [ExprStmt] ...; +# 159| 0: [AssignExpr] ... = ... +# 159| 0: [PropertyCall] access to property Prop +# 159| -1: [LocalVariableAccess] access to local variable s +# 159| 1: [IntLiteral] 1 +# 160| 3: [LocalVariableDeclStmt] ... ...; +# 160| 0: [LocalVariableDeclAndInitExpr] Int32 x = ... +# 160| -1: [TypeMention] int +# 160| 0: [LocalVariableAccess] access to local variable x +# 160| 1: [PropertyCall] access to property Prop +# 160| -1: [LocalVariableAccess] access to local variable s diff --git a/csharp/ql/test/library-tests/properties/Properties17.expected b/csharp/ql/test/library-tests/properties/Properties17.expected index ee817a63df9..74efae145f7 100644 --- a/csharp/ql/test/library-tests/properties/Properties17.expected +++ b/csharp/ql/test/library-tests/properties/Properties17.expected @@ -1,5 +1,6 @@ | Prop.field | | caption | | next | +| x | | y | | z | diff --git a/csharp/ql/test/library-tests/properties/Properties19.expected b/csharp/ql/test/library-tests/properties/Properties19.expected new file mode 100644 index 00000000000..1ae4493a6b5 --- /dev/null +++ b/csharp/ql/test/library-tests/properties/Properties19.expected @@ -0,0 +1,7 @@ +| properties.cs:12:23:12:29 | Caption | properties.cs:29:13:29:28 | access to property Caption | properties.cs:17:13:17:15 | set_Caption | +| properties.cs:12:23:12:29 | Caption | properties.cs:30:24:30:39 | access to property Caption | properties.cs:15:13:15:15 | get_Caption | +| properties.cs:57:20:57:20 | X | properties.cs:61:13:61:13 | access to property X | properties.cs:57:37:57:39 | set_X | +| properties.cs:58:20:58:20 | Y | properties.cs:62:13:62:13 | access to property Y | properties.cs:58:37:58:39 | set_Y | +| properties.cs:70:28:70:28 | X | properties.cs:82:46:82:51 | access to property X | properties.cs:70:32:70:34 | get_X | +| properties.cs:71:28:71:28 | Y | properties.cs:83:39:83:44 | access to property Y | properties.cs:74:13:74:15 | set_Y | +| properties.cs:146:24:146:27 | Prop | properties.cs:160:21:160:26 | access to property Prop | properties.cs:148:13:148:15 | get_Prop | diff --git a/csharp/ql/test/library-tests/properties/Properties19.ql b/csharp/ql/test/library-tests/properties/Properties19.ql new file mode 100644 index 00000000000..ea34f1d5635 --- /dev/null +++ b/csharp/ql/test/library-tests/properties/Properties19.ql @@ -0,0 +1,8 @@ +import csharp + +from PropertyCall pc, Property p, Accessor target +where + pc.getProperty() = p and + pc.getTarget() = target and + p.fromSource() +select p, pc, target diff --git a/csharp/ql/test/library-tests/properties/properties.cs b/csharp/ql/test/library-tests/properties/properties.cs index 2f88214ec75..391245e3497 100644 --- a/csharp/ql/test/library-tests/properties/properties.cs +++ b/csharp/ql/test/library-tests/properties/properties.cs @@ -133,4 +133,31 @@ namespace Properties set { field = value; } } } + + public ref struct S + { + private ref int x; + + public S(ref int v) + { + x = ref v; + } + + public ref int Prop + { + get { return ref x; } + } + } + + public class TestRefReturns + { + public void M() + { + int a = 0; + + S s = new S(ref a); + s.Prop = 1; + var x = s.Prop; + } + } } From a2ac0ab7d559fe724895329ab7e49a046e4877e2 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 May 2026 09:38:37 +0200 Subject: [PATCH 077/226] C#: Add test case for indexer calls and update test expected for other files. --- .../indexers/Indexers13.expected | 3 ++ .../test/library-tests/indexers/Indexers13.ql | 8 +++ .../library-tests/indexers/PrintAst.expected | 54 +++++++++++++++++++ .../test/library-tests/indexers/indexers.cs | 27 ++++++++++ 4 files changed, 92 insertions(+) create mode 100644 csharp/ql/test/library-tests/indexers/Indexers13.expected create mode 100644 csharp/ql/test/library-tests/indexers/Indexers13.ql diff --git a/csharp/ql/test/library-tests/indexers/Indexers13.expected b/csharp/ql/test/library-tests/indexers/Indexers13.expected new file mode 100644 index 00000000000..0e7281cf645 --- /dev/null +++ b/csharp/ql/test/library-tests/indexers/Indexers13.expected @@ -0,0 +1,3 @@ +| indexers.cs:24:21:24:24 | Item | indexers.cs:62:22:62:29 | access to indexer | indexers.cs:26:13:26:15 | get_Item | +| indexers.cs:24:21:24:24 | Item | indexers.cs:65:25:65:32 | access to indexer | indexers.cs:34:13:34:15 | set_Item | +| indexers.cs:143:24:143:27 | Item | indexers.cs:157:21:157:24 | access to indexer | indexers.cs:145:13:145:15 | get_Item | diff --git a/csharp/ql/test/library-tests/indexers/Indexers13.ql b/csharp/ql/test/library-tests/indexers/Indexers13.ql new file mode 100644 index 00000000000..63680269007 --- /dev/null +++ b/csharp/ql/test/library-tests/indexers/Indexers13.ql @@ -0,0 +1,8 @@ +import csharp + +from IndexerCall ic, Indexer i, Accessor target +where + ic.getIndexer() = i and + ic.getTarget() = target and + i.fromSource() +select i, ic, target diff --git a/csharp/ql/test/library-tests/indexers/PrintAst.expected b/csharp/ql/test/library-tests/indexers/PrintAst.expected index 93160309c79..57b83223c36 100644 --- a/csharp/ql/test/library-tests/indexers/PrintAst.expected +++ b/csharp/ql/test/library-tests/indexers/PrintAst.expected @@ -360,3 +360,57 @@ indexers.cs: # 130| 4: [BlockStmt] {...} # 130| 0: [ReturnStmt] return ...; # 130| 0: [IntLiteral] 0 +# 134| 5: [RefStruct] S +# 136| 6: [Field] x +# 136| -1: [TypeMention] int +# 138| 7: [InstanceConstructor] S +#-----| 2: (Parameters) +# 138| 0: [Parameter] v +# 138| -1: [TypeMention] int +# 139| 4: [BlockStmt] {...} +# 140| 0: [ExprStmt] ...; +# 140| 0: [AssignExpr] ... = ... +# 140| 0: [FieldAccess] access to field x +# 140| 1: [RefExpr] ref ... +# 140| 0: [ParameterAccess] access to parameter v +# 143| 8: [Indexer] Item +# 143| -1: [TypeMention] int +#-----| 1: (Parameters) +# 143| 0: [Parameter] i +# 143| -1: [TypeMention] int +# 145| 3: [Getter] get_Item +#-----| 2: (Parameters) +# 143| 0: [Parameter] i +# 145| 4: [BlockStmt] {...} +# 145| 0: [ReturnStmt] return ...; +# 145| 0: [RefExpr] ref ... +# 145| 0: [FieldAccess] access to field x +# 149| 6: [Class] TestRefReturns +# 151| 6: [Method] M +# 151| -1: [TypeMention] Void +# 152| 4: [BlockStmt] {...} +# 153| 0: [LocalVariableDeclStmt] ... ...; +# 153| 0: [LocalVariableDeclAndInitExpr] Int32 a = ... +# 153| -1: [TypeMention] int +# 153| 0: [LocalVariableAccess] access to local variable a +# 153| 1: [IntLiteral] 0 +# 155| 1: [LocalVariableDeclStmt] ... ...; +# 155| 0: [LocalVariableDeclAndInitExpr] S s = ... +# 155| -1: [TypeMention] S +# 155| 0: [LocalVariableAccess] access to local variable s +# 155| 1: [ObjectCreation] object creation of type S +# 155| -1: [TypeMention] S +# 155| 0: [LocalVariableAccess] access to local variable a +# 156| 2: [ExprStmt] ...; +# 156| 0: [AssignExpr] ... = ... +# 156| 0: [IndexerCall] access to indexer +# 156| -1: [LocalVariableAccess] access to local variable s +# 156| 0: [IntLiteral] 0 +# 156| 1: [IntLiteral] 1 +# 157| 3: [LocalVariableDeclStmt] ... ...; +# 157| 0: [LocalVariableDeclAndInitExpr] Int32 x = ... +# 157| -1: [TypeMention] int +# 157| 0: [LocalVariableAccess] access to local variable x +# 157| 1: [IndexerCall] access to indexer +# 157| -1: [LocalVariableAccess] access to local variable s +# 157| 0: [IntLiteral] 0 diff --git a/csharp/ql/test/library-tests/indexers/indexers.cs b/csharp/ql/test/library-tests/indexers/indexers.cs index 6da14ae769d..55011d82755 100644 --- a/csharp/ql/test/library-tests/indexers/indexers.cs +++ b/csharp/ql/test/library-tests/indexers/indexers.cs @@ -130,4 +130,31 @@ namespace Indexers get { return 0; } } } + + public ref struct S + { + private ref int x; + + public S(ref int v) + { + x = ref v; + } + + public ref int this[int i] + { + get { return ref x; } + } + } + + public class TestRefReturns + { + public void M() + { + int a = 0; + + S s = new S(ref a); + s[0] = 1; + var x = s[0]; + } + } } From 9d0d4e4912f9b5e31fa4280b2692f1eb8e5487de Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 May 2026 08:44:22 +0200 Subject: [PATCH 078/226] C#: Add ref return info for accessors. --- csharp/extractor/Semmle.Extraction.CSharp/Entities/Accessor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Accessor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Accessor.cs index ed409e23b39..7e30d4d5f7c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Accessor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Accessor.cs @@ -69,6 +69,7 @@ namespace Semmle.Extraction.CSharp.Entities } Overrides(trapFile); + ExtractRefReturn(trapFile, Symbol, this); if (Symbol.FromSource() && !HasBody) { From c3bb5e8effe92d883310e2985d71e5ab35a45ce2 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 May 2026 08:46:48 +0200 Subject: [PATCH 079/226] C#: Use ref return getters for properties/indexers in write contexts. --- .../ql/lib/semmle/code/csharp/exprs/Call.qll | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll index c9b8e61f493..a358e73970c 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll @@ -766,7 +766,16 @@ class PropertyCall extends AccessorCall, PropertyAccessExpr { } override Accessor getWriteTarget() { - this instanceof AssignableWrite and result = this.getProperty().getSetter() + this instanceof AssignableWrite and + exists(Property p | p = this.getProperty() | + result = p.getSetter() + or + result = + any(Getter g | + g = p.getGetter() and + g.getAnnotatedReturnType().isRef() + ) + ) } override Expr getArgument(int i) { @@ -801,7 +810,16 @@ class IndexerCall extends AccessorCall, IndexerAccessExpr { } override Accessor getWriteTarget() { - this instanceof AssignableWrite and result = this.getIndexer().getSetter() + this instanceof AssignableWrite and + exists(Indexer i | i = this.getIndexer() | + result = i.getSetter() + or + result = + any(Getter g | + g = i.getGetter() and + g.getAnnotatedReturnType().isRef() + ) + ) } override Expr getArgument(int i) { From 1c01bb32d9ffcdae69f8be7281a4050eaf7092cc Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 May 2026 09:48:04 +0200 Subject: [PATCH 080/226] C#: Update test expected output. --- csharp/ql/test/library-tests/indexers/Indexers13.expected | 1 + csharp/ql/test/library-tests/properties/Properties19.expected | 1 + 2 files changed, 2 insertions(+) diff --git a/csharp/ql/test/library-tests/indexers/Indexers13.expected b/csharp/ql/test/library-tests/indexers/Indexers13.expected index 0e7281cf645..a5e831421f8 100644 --- a/csharp/ql/test/library-tests/indexers/Indexers13.expected +++ b/csharp/ql/test/library-tests/indexers/Indexers13.expected @@ -1,3 +1,4 @@ | indexers.cs:24:21:24:24 | Item | indexers.cs:62:22:62:29 | access to indexer | indexers.cs:26:13:26:15 | get_Item | | indexers.cs:24:21:24:24 | Item | indexers.cs:65:25:65:32 | access to indexer | indexers.cs:34:13:34:15 | set_Item | +| indexers.cs:143:24:143:27 | Item | indexers.cs:156:13:156:16 | access to indexer | indexers.cs:145:13:145:15 | get_Item | | indexers.cs:143:24:143:27 | Item | indexers.cs:157:21:157:24 | access to indexer | indexers.cs:145:13:145:15 | get_Item | diff --git a/csharp/ql/test/library-tests/properties/Properties19.expected b/csharp/ql/test/library-tests/properties/Properties19.expected index 1ae4493a6b5..7c027119067 100644 --- a/csharp/ql/test/library-tests/properties/Properties19.expected +++ b/csharp/ql/test/library-tests/properties/Properties19.expected @@ -4,4 +4,5 @@ | properties.cs:58:20:58:20 | Y | properties.cs:62:13:62:13 | access to property Y | properties.cs:58:37:58:39 | set_Y | | properties.cs:70:28:70:28 | X | properties.cs:82:46:82:51 | access to property X | properties.cs:70:32:70:34 | get_X | | properties.cs:71:28:71:28 | Y | properties.cs:83:39:83:44 | access to property Y | properties.cs:74:13:74:15 | set_Y | +| properties.cs:146:24:146:27 | Prop | properties.cs:159:13:159:18 | access to property Prop | properties.cs:148:13:148:15 | get_Prop | | properties.cs:146:24:146:27 | Prop | properties.cs:160:21:160:26 | access to property Prop | properties.cs:148:13:148:15 | get_Prop | From c0273ae94fc0bffa765f7e253c49c0b8323099a0 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 May 2026 13:21:26 +0200 Subject: [PATCH 081/226] C#: Update other affected tests (including database quality). --- csharp/ql/test/library-tests/csharp8/NullableRefTypes.expected | 2 +- .../Telemetry/DatabaseQuality/IsNotOkayCall.expected | 1 - .../query-tests/Telemetry/DatabaseQuality/NoTarget.expected | 1 - csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/csharp/ql/test/library-tests/csharp8/NullableRefTypes.expected b/csharp/ql/test/library-tests/csharp8/NullableRefTypes.expected index 6ab83277fcf..d6965f85da5 100644 --- a/csharp/ql/test/library-tests/csharp8/NullableRefTypes.expected +++ b/csharp/ql/test/library-tests/csharp8/NullableRefTypes.expected @@ -227,7 +227,7 @@ returnTypes | NullableRefTypes.cs:107:26:107:36 | ReturnsRef5 | readonly MyClass! | | NullableRefTypes.cs:108:26:108:36 | ReturnsRef6 | readonly MyClass! | | NullableRefTypes.cs:110:10:110:20 | Parameters1 | Void! | -| NullableRefTypes.cs:113:32:113:44 | get_RefProperty | MyClass! | +| NullableRefTypes.cs:113:32:113:44 | get_RefProperty | ref MyClass! | | NullableRefTypes.cs:116:7:116:23 | | Void | | NullableRefTypes.cs:116:7:116:23 | ToStringWithTypes | Void! | | NullableRefTypes.cs:136:7:136:24 | | Void | diff --git a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected index 7555a37394b..dcdb8b09058 100644 --- a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected +++ b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/IsNotOkayCall.expected @@ -1,3 +1,2 @@ | Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer | | Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer | -| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer | diff --git a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected index 7ae469cf84e..a76dd08cdb6 100644 --- a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected +++ b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected @@ -9,6 +9,5 @@ | Quality.cs:23:9:23:30 | delegate call | Call without target $@. | Quality.cs:23:9:23:30 | delegate call | delegate call | | Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer | | Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer | -| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer | | Quality.cs:38:16:38:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:38:16:38:26 | access to property MyProperty2 | access to property MyProperty2 | | Quality.cs:50:20:50:26 | object creation of type T | Call without target $@. | Quality.cs:50:20:50:26 | object creation of type T | object creation of type T | diff --git a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs index 31f4deda5df..e10ce10f6c4 100644 --- a/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs +++ b/csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs @@ -29,7 +29,7 @@ public class Test var slice = sp[..3]; // TODO: this is not an indexer call, but rather a `sp.Slice(0, 3)` call. Span guidBytes = stackalloc byte[16]; - guidBytes[08] = 1; // TODO: this indexer call has no target, because the target is a `ref` returning getter. + guidBytes[08] = 1; new MyList([new(), new Test()]); } From 6825ccc74f9fe5b06eaf8402062cd5adc195e4dc Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 19 May 2026 13:36:58 +0200 Subject: [PATCH 082/226] C#: Add change-note. --- .../change-notes/2026-05-19-properties-indexers-refreturn.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2026-05-19-properties-indexers-refreturn.md diff --git a/csharp/ql/lib/change-notes/2026-05-19-properties-indexers-refreturn.md b/csharp/ql/lib/change-notes/2026-05-19-properties-indexers-refreturn.md new file mode 100644 index 00000000000..d92d5fdf819 --- /dev/null +++ b/csharp/ql/lib/change-notes/2026-05-19-properties-indexers-refreturn.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Improved call target resolution for ref-return properties and indexers. From b67694b2abdcd66461d3827efa590f96cfc05d5f Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 17 Sep 2024 12:11:16 +0200 Subject: [PATCH 083/226] Python: Remove imprecise container steps - remove `tupleStoreStep` and `dictStoreStep` from `containerStep` These are imprecise compared to the content being precise. - add implicit reads to recover taint at sinks - add implicit read steps for decoders to supplement the `AdditionalTaintStep` that now only covers when the full container is tainted. --- .../DataFlowConsistency.ql | 2 + .../dataflow/new/internal/DataFlowPrivate.qll | 36 +++++ .../new/internal/TaintTrackingPrivate.qll | 15 +- .../dataflow/sensitive-data/test.py | 5 +- .../test_string.py | 2 +- .../test_collections.py | 6 +- .../defaultAdditionalTaintStep/test_string.py | 2 +- .../test_unpacking.py | 2 +- .../frameworks/stdlib/test_re.py | 2 +- .../frameworks/tornado/taint_test.py | 2 +- ...ExternalAPIsUsedWithUntrustedData.expected | 1 + .../UntrustedDataToExternalAPI.expected | 5 + .../StackTraceExposure.expected | 6 +- .../CleartextLogging.expected | 6 - .../PartialServerSideRequestForgery.expected | 13 +- .../NoSqlInjection.expected | 132 +++++++++++++++--- 16 files changed, 182 insertions(+), 55 deletions(-) diff --git a/python/ql/consistency-queries/DataFlowConsistency.ql b/python/ql/consistency-queries/DataFlowConsistency.ql index 829aa6debef..e0ed207dc21 100644 --- a/python/ql/consistency-queries/DataFlowConsistency.ql +++ b/python/ql/consistency-queries/DataFlowConsistency.ql @@ -36,6 +36,8 @@ private module Input implements InputSig { // parameter, but dataflow-consistency queries should _not_ complain about there not // being a post-update node for the synthetic `**kwargs` parameter. n instanceof SynthDictSplatParameterNode + or + Private::Conversions::readStep(n, _, _) } predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index fffd0150008..7cb48d4784d 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -1009,6 +1009,8 @@ predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) { synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo) or VariableCapture::readStep(nodeFrom, c, nodeTo) + or + Conversions::readStep(nodeFrom, c, nodeTo) } /** Data flows from a sequence to a subscript of the sequence. */ @@ -1064,6 +1066,40 @@ predicate attributeReadStep(Node nodeFrom, AttributeContent c, AttrRead nodeTo) nodeTo.accesses(nodeFrom, c.getAttribute()) } +module Conversions { + private import semmle.python.Concepts + + predicate decoderReadStep(Node nodeFrom, ContentSet c, Node nodeTo) { + exists(Decoding decoding | + nodeFrom = decoding.getAnInput() and + nodeTo = decoding.getOutput() + ) and + ( + c instanceof TupleElementContent + or + c instanceof DictionaryElementContent + ) + } + + predicate encoderReadStep(Node nodeFrom, ContentSet c, Node nodeTo) { + exists(Encoding encoding | + nodeFrom = encoding.getAnInput() and + nodeTo = encoding.getOutput() + ) and + ( + c instanceof TupleElementContent + or + c instanceof DictionaryElementContent + ) + } + + predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) { + decoderReadStep(nodeFrom, c, nodeTo) + or + encoderReadStep(nodeFrom, c, nodeTo) + } +} + /** * Holds if values stored inside content `c` are cleared at node `n`. For example, * any value stored inside `f` is cleared at the pre-update node associated with `x` diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 62f5a76309b..6959ceabe70 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -16,7 +16,16 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { none() } * of `c` at sinks and inputs to additional taint steps. */ bindingset[node] -predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() } +predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { + // We allow implicit reads of precise content + // imprecise content has already bubled up. + exists(node) and + ( + c instanceof DataFlow::TupleElementContent + or + c instanceof DataFlow::DictionaryElementContent + ) +} private module Cached { /** @@ -176,10 +185,6 @@ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { or DataFlowPrivate::setStoreStep(nodeFrom, _, nodeTo) or - DataFlowPrivate::tupleStoreStep(nodeFrom, _, nodeTo) - or - DataFlowPrivate::dictStoreStep(nodeFrom, _, nodeTo) - or // comprehension, so there is taint-flow from `x` in `[x for x in xs]` to the // resulting list of the list-comprehension. // diff --git a/python/ql/test/library-tests/dataflow/sensitive-data/test.py b/python/ql/test/library-tests/dataflow/sensitive-data/test.py index 77238a5e1dc..d4a10511030 100644 --- a/python/ql/test/library-tests/dataflow/sensitive-data/test.py +++ b/python/ql/test/library-tests/dataflow/sensitive-data/test.py @@ -131,6 +131,5 @@ from unknown_settings import password # $ SensitiveDataSource=password print(password) # $ SensitiveUse=password _config = {"sleep_timer": 5, "mysql_password": password} -# since we have taint-step from store of `password`, we will consider any item in the -# dictionary to be a password :( -print(_config["sleep_timer"]) # $ SPURIOUS: SensitiveUse=password +# since we have precise dictionary content, other items of the config are not tainted +print(_config["sleep_timer"]) diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py index 41a14e73a27..4ef1572f089 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py @@ -17,7 +17,7 @@ def str_methods(): ts.casefold(), # $ tainted ts.format_map({}), # $ tainted - "{unsafe}".format_map({"unsafe": ts}), # $ tainted + "{unsafe}".format_map({"unsafe": ts}), # $ MISSING: tainted ) diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py index 6c86d1c75d5..73a369c0ece 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py @@ -29,10 +29,10 @@ def test_construction(): ensure_tainted( list(tainted_list), # $ tainted - list(tainted_tuple), # $ tainted + list(tainted_tuple), # $ MISSING: tainted list(tainted_set), # $ tainted - list(tainted_dict.values()), # $ tainted - list(tainted_dict.items()), # $ tainted + list(tainted_dict.values()), # $ MISSING: tainted + list(tainted_dict.items()), # $ MISSING: tainted tuple(tainted_list), # $ tainted set(tainted_list), # $ tainted diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py index 42ac758bfff..58d1c5160c4 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py @@ -115,7 +115,7 @@ def percent_fmt(): ensure_tainted( tainted_fmt % (1, 2), # $ tainted "%s foo bar" % ts, # $ tainted - "%s %s %s" % (1, 2, ts), # $ tainted + "%s %s %s" % (1, 2, ts), # $ MISSING: tainted ) diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py index d8bfe71dbc4..2816e848470 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_unpacking.py @@ -53,7 +53,7 @@ def contrived_1(): (a, b, c), (d, e, f) = tainted_list, no_taint_list ensure_tainted(a, b, c) # $ tainted - ensure_not_tainted(d, e, f) # $ SPURIOUS: tainted + ensure_not_tainted(d, e, f) def contrived_2(): diff --git a/python/ql/test/library-tests/frameworks/stdlib/test_re.py b/python/ql/test/library-tests/frameworks/stdlib/test_re.py index 4cfe5d972b7..8ed6f620bfa 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/test_re.py +++ b/python/ql/test/library-tests/frameworks/stdlib/test_re.py @@ -80,9 +80,9 @@ ensure_tainted( ) ensure_not_tainted( - re.subn(pat, repl="safe", string=ts), re.subn(pat, repl="safe", string=ts)[1], # // the number of substitutions made ) ensure_tainted( + re.subn(pat, repl="safe", string=ts), # $ tainted // implicit read at sink re.subn(pat, repl="safe", string=ts)[0], # $ tainted // the string ) diff --git a/python/ql/test/library-tests/frameworks/tornado/taint_test.py b/python/ql/test/library-tests/frameworks/tornado/taint_test.py index 697a9e30af6..7e80186a56f 100644 --- a/python/ql/test/library-tests/frameworks/tornado/taint_test.py +++ b/python/ql/test/library-tests/frameworks/tornado/taint_test.py @@ -63,7 +63,7 @@ class TaintTest(tornado.web.RequestHandler): request.headers["header-name"], # $ tainted request.headers.get_list("header-name"), # $ tainted request.headers.get_all(), # $ tainted - [(k, v) for (k, v) in request.headers.get_all()], # $ tainted + [(k, v) for (k, v) in request.headers.get_all()], # $ MISSING: tainted # Dict[str, http.cookies.Morsel] request.cookies, # $ tainted diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected index a346aef9d22..7776cabb14c 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected @@ -1,3 +1,4 @@ +| hmac.new [**] | 1 | 1 | | hmac.new [keyword msg] | 1 | 1 | | hmac.new [position 1] | 1 | 1 | | unknown.lib.func [keyword kw] | 2 | 1 | diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected index 08a5b798f71..9a49e3cbfe4 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected @@ -15,6 +15,8 @@ edges | test.py:23:16:23:27 | ControlFlowNode for Attribute | test.py:23:16:23:39 | ControlFlowNode for Attribute() | provenance | dict.get | | test.py:23:16:23:39 | ControlFlowNode for Attribute() | test.py:23:5:23:12 | ControlFlowNode for data_raw | provenance | | | test.py:24:5:24:8 | ControlFlowNode for data | test.py:25:44:25:47 | ControlFlowNode for data | provenance | | +| test.py:24:5:24:8 | ControlFlowNode for data | test.py:25:44:25:47 | ControlFlowNode for data | provenance | | +| test.py:25:44:25:47 | ControlFlowNode for data | test.py:25:15:25:74 | SynthDictSplatArgumentNode | provenance | | | test.py:34:5:34:8 | ControlFlowNode for data | test.py:35:10:35:13 | ControlFlowNode for data | provenance | | | test.py:34:5:34:8 | ControlFlowNode for data | test.py:36:13:36:16 | ControlFlowNode for data | provenance | | | test.py:34:12:34:18 | ControlFlowNode for request | test.py:34:12:34:23 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | @@ -45,6 +47,8 @@ nodes | test.py:23:16:23:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:23:16:23:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:24:5:24:8 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | +| test.py:25:15:25:74 | SynthDictSplatArgumentNode | semmle.label | SynthDictSplatArgumentNode | +| test.py:25:44:25:47 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | | test.py:25:44:25:47 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | | test.py:34:5:34:8 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | | test.py:34:12:34:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -68,6 +72,7 @@ nodes subpaths #select | test.py:15:36:15:39 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [position 1] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | +| test.py:25:15:25:74 | SynthDictSplatArgumentNode | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:25:15:25:74 | SynthDictSplatArgumentNode | Call to hmac.new [**] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | | test.py:25:44:25:47 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:25:44:25:47 | ControlFlowNode for data | Call to hmac.new [keyword msg] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | | test.py:35:10:35:13 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:35:10:35:13 | ControlFlowNode for data | Call to unknown.lib.func [position 0] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | | test.py:36:13:36:16 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:36:13:36:16 | ControlFlowNode for data | Call to unknown.lib.func [keyword kw] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | diff --git a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected index e0321cab12e..961eaac5143 100644 --- a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected +++ b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected @@ -7,7 +7,9 @@ edges | test.py:50:29:50:31 | ControlFlowNode for err | test.py:50:16:50:32 | ControlFlowNode for format_error() | provenance | | | test.py:50:29:50:31 | ControlFlowNode for err | test.py:52:18:52:20 | ControlFlowNode for msg | provenance | | | test.py:52:18:52:20 | ControlFlowNode for msg | test.py:53:12:53:27 | ControlFlowNode for BinaryExpr | provenance | | -| test.py:65:25:65:25 | ControlFlowNode for e | test.py:66:24:66:40 | ControlFlowNode for Dict | provenance | | +| test.py:65:25:65:25 | ControlFlowNode for e | test.py:66:34:66:39 | ControlFlowNode for str() | provenance | | +| test.py:66:24:66:40 | ControlFlowNode for Dict [Dictionary element at key error] | test.py:66:24:66:40 | ControlFlowNode for Dict | provenance | | +| test.py:66:34:66:39 | ControlFlowNode for str() | test.py:66:24:66:40 | ControlFlowNode for Dict [Dictionary element at key error] | provenance | | nodes | test.py:16:16:16:37 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:23:25:23:25 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | @@ -23,6 +25,8 @@ nodes | test.py:53:12:53:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | test.py:65:25:65:25 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | | test.py:66:24:66:40 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| test.py:66:24:66:40 | ControlFlowNode for Dict [Dictionary element at key error] | semmle.label | ControlFlowNode for Dict [Dictionary element at key error] | +| test.py:66:34:66:39 | ControlFlowNode for str() | semmle.label | ControlFlowNode for str() | subpaths | test.py:50:29:50:31 | ControlFlowNode for err | test.py:52:18:52:20 | ControlFlowNode for msg | test.py:53:12:53:27 | ControlFlowNode for BinaryExpr | test.py:50:16:50:32 | ControlFlowNode for format_error() | #select diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected index 7cb9e015190..5da1b60eee1 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected @@ -22,8 +22,6 @@ edges | test.py:67:38:67:48 | ControlFlowNode for bank_number | test.py:70:15:70:25 | ControlFlowNode for bank_number | provenance | | | test.py:67:76:67:78 | ControlFlowNode for ccn | test.py:73:15:73:17 | ControlFlowNode for ccn | provenance | | | test.py:67:81:67:88 | ControlFlowNode for user_ccn | test.py:74:15:74:22 | ControlFlowNode for user_ccn | provenance | | -| test.py:101:5:101:10 | ControlFlowNode for config | test.py:105:11:105:31 | ControlFlowNode for Subscript | provenance | | -| test.py:103:21:103:37 | ControlFlowNode for Attribute | test.py:101:5:101:10 | ControlFlowNode for config | provenance | | nodes | test.py:19:5:19:12 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | | test.py:19:16:19:29 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | @@ -68,9 +66,6 @@ nodes | test.py:70:15:70:25 | ControlFlowNode for bank_number | semmle.label | ControlFlowNode for bank_number | | test.py:73:15:73:17 | ControlFlowNode for ccn | semmle.label | ControlFlowNode for ccn | | test.py:74:15:74:22 | ControlFlowNode for user_ccn | semmle.label | ControlFlowNode for user_ccn | -| test.py:101:5:101:10 | ControlFlowNode for config | semmle.label | ControlFlowNode for config | -| test.py:103:21:103:37 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | -| test.py:105:11:105:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | subpaths #select | test.py:20:48:20:55 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | @@ -97,4 +92,3 @@ subpaths | test.py:70:15:70:25 | ControlFlowNode for bank_number | test.py:67:38:67:48 | ControlFlowNode for bank_number | test.py:70:15:70:25 | ControlFlowNode for bank_number | This expression logs $@ as clear text. | test.py:67:38:67:48 | ControlFlowNode for bank_number | sensitive data (private) | | test.py:73:15:73:17 | ControlFlowNode for ccn | test.py:67:76:67:78 | ControlFlowNode for ccn | test.py:73:15:73:17 | ControlFlowNode for ccn | This expression logs $@ as clear text. | test.py:67:76:67:78 | ControlFlowNode for ccn | sensitive data (private) | | test.py:74:15:74:22 | ControlFlowNode for user_ccn | test.py:67:81:67:88 | ControlFlowNode for user_ccn | test.py:74:15:74:22 | ControlFlowNode for user_ccn | This expression logs $@ as clear text. | test.py:67:81:67:88 | ControlFlowNode for user_ccn | sensitive data (private) | -| test.py:105:11:105:31 | ControlFlowNode for Subscript | test.py:103:21:103:37 | ControlFlowNode for Attribute | test.py:105:11:105:31 | ControlFlowNode for Subscript | This expression logs $@ as clear text. | test.py:103:21:103:37 | ControlFlowNode for Attribute | sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected index 0b875607157..5deeefd8920 100644 --- a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected +++ b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected @@ -1,5 +1,4 @@ #select -| full_partial_test.py:80:5:80:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:80:18:80:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | user-provided value | | full_partial_test.py:105:5:105:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:105:18:105:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | user-provided value | | full_partial_test.py:112:5:112:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:112:18:112:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | user-provided value | | full_partial_test.py:119:5:119:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:119:18:119:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | user-provided value | @@ -46,7 +45,6 @@ edges | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:41:18:41:24 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:42:17:42:23 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:66:18:66:24 | ControlFlowNode for request | provenance | | -| full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:67:17:67:23 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:83:18:83:24 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:84:17:84:23 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:101:18:101:24 | ControlFlowNode for request | provenance | | @@ -82,14 +80,9 @@ edges | full_partial_test.py:61:5:61:7 | ControlFlowNode for url | full_partial_test.py:63:18:63:20 | ControlFlowNode for url | provenance | | | full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | full_partial_test.py:70:5:70:7 | ControlFlowNode for url | provenance | | | full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | full_partial_test.py:74:5:74:7 | ControlFlowNode for url | provenance | | -| full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | full_partial_test.py:78:5:78:7 | ControlFlowNode for url | provenance | | | full_partial_test.py:66:18:66:24 | ControlFlowNode for request | full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | provenance | AdditionalTaintStep | -| full_partial_test.py:66:18:66:24 | ControlFlowNode for request | full_partial_test.py:67:5:67:13 | ControlFlowNode for query_val | provenance | AdditionalTaintStep | -| full_partial_test.py:67:5:67:13 | ControlFlowNode for query_val | full_partial_test.py:78:5:78:7 | ControlFlowNode for url | provenance | | -| full_partial_test.py:67:17:67:23 | ControlFlowNode for request | full_partial_test.py:67:5:67:13 | ControlFlowNode for query_val | provenance | AdditionalTaintStep | | full_partial_test.py:70:5:70:7 | ControlFlowNode for url | full_partial_test.py:72:18:72:20 | ControlFlowNode for url | provenance | | | full_partial_test.py:74:5:74:7 | ControlFlowNode for url | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | provenance | | -| full_partial_test.py:78:5:78:7 | ControlFlowNode for url | full_partial_test.py:80:18:80:20 | ControlFlowNode for url | provenance | | | full_partial_test.py:83:5:83:14 | ControlFlowNode for user_input | full_partial_test.py:87:5:87:7 | ControlFlowNode for url | provenance | | | full_partial_test.py:83:5:83:14 | ControlFlowNode for user_input | full_partial_test.py:91:5:91:7 | ControlFlowNode for url | provenance | | | full_partial_test.py:83:5:83:14 | ControlFlowNode for user_input | full_partial_test.py:95:5:95:7 | ControlFlowNode for url | provenance | | @@ -267,14 +260,10 @@ nodes | full_partial_test.py:63:18:63:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | | full_partial_test.py:66:18:66:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | -| full_partial_test.py:67:5:67:13 | ControlFlowNode for query_val | semmle.label | ControlFlowNode for query_val | -| full_partial_test.py:67:17:67:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:70:5:70:7 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:72:18:72:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:74:5:74:7 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | -| full_partial_test.py:78:5:78:7 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | -| full_partial_test.py:80:18:80:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:83:5:83:14 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | | full_partial_test.py:83:18:83:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:84:5:84:13 | ControlFlowNode for query_val | semmle.label | ControlFlowNode for query_val | @@ -420,3 +409,5 @@ nodes | test_requests.py:20:18:20:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_requests.py:22:34:22:43 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | subpaths +testFailures +| full_partial_test.py:80:23:80:80 | Comment # $ Alert[py/partial-ssrf] $ MISSING: Alert[py/full-ssrf] | Missing result: Alert[py/partial-ssrf] | diff --git a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected index 810ece4f107..fb8920cf03c 100644 --- a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected @@ -7,25 +7,39 @@ edges | PoC/server.py:1:26:1:32 | ControlFlowNode for request | PoC/server.py:98:14:98:20 | ControlFlowNode for request | provenance | | | PoC/server.py:26:5:26:17 | ControlFlowNode for author_string | PoC/server.py:27:25:27:37 | ControlFlowNode for author_string | provenance | | | PoC/server.py:26:21:26:27 | ControlFlowNode for request | PoC/server.py:26:5:26:17 | ControlFlowNode for author_string | provenance | AdditionalTaintStep | -| PoC/server.py:27:5:27:10 | ControlFlowNode for author | PoC/server.py:30:27:30:44 | ControlFlowNode for Dict | provenance | | -| PoC/server.py:27:5:27:10 | ControlFlowNode for author | PoC/server.py:31:34:31:51 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:27:5:27:10 | ControlFlowNode for author | PoC/server.py:30:38:30:43 | ControlFlowNode for author | provenance | | +| PoC/server.py:27:5:27:10 | ControlFlowNode for author | PoC/server.py:31:45:31:50 | ControlFlowNode for author | provenance | | | PoC/server.py:27:14:27:38 | ControlFlowNode for Attribute() | PoC/server.py:27:5:27:10 | ControlFlowNode for author | provenance | | | PoC/server.py:27:25:27:37 | ControlFlowNode for author_string | PoC/server.py:27:14:27:38 | ControlFlowNode for Attribute() | provenance | Config | +| PoC/server.py:30:27:30:44 | ControlFlowNode for Dict [Dictionary element at key author] | PoC/server.py:30:27:30:44 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:30:38:30:43 | ControlFlowNode for author | PoC/server.py:30:27:30:44 | ControlFlowNode for Dict [Dictionary element at key author] | provenance | | +| PoC/server.py:31:34:31:51 | ControlFlowNode for Dict [Dictionary element at key author] | PoC/server.py:31:34:31:51 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:31:45:31:50 | ControlFlowNode for author | PoC/server.py:31:34:31:51 | ControlFlowNode for Dict [Dictionary element at key author] | provenance | | | PoC/server.py:43:5:43:10 | ControlFlowNode for author | PoC/server.py:47:38:47:67 | ControlFlowNode for BinaryExpr | provenance | | | PoC/server.py:43:14:43:20 | ControlFlowNode for request | PoC/server.py:43:5:43:10 | ControlFlowNode for author | provenance | AdditionalTaintStep | | PoC/server.py:47:38:47:67 | ControlFlowNode for BinaryExpr | PoC/server.py:47:27:47:68 | ControlFlowNode for Dict | provenance | Config | | PoC/server.py:52:5:52:10 | ControlFlowNode for author | PoC/server.py:54:17:54:70 | ControlFlowNode for BinaryExpr | provenance | | | PoC/server.py:52:14:52:20 | ControlFlowNode for request | PoC/server.py:52:5:52:10 | ControlFlowNode for author | provenance | AdditionalTaintStep | -| PoC/server.py:53:5:53:10 | ControlFlowNode for search | PoC/server.py:61:27:61:58 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:53:5:53:10 | ControlFlowNode for search | PoC/server.py:61:51:61:56 | ControlFlowNode for search | provenance | | | PoC/server.py:53:14:57:5 | ControlFlowNode for Dict | PoC/server.py:53:5:53:10 | ControlFlowNode for search | provenance | | | PoC/server.py:54:17:54:70 | ControlFlowNode for BinaryExpr | PoC/server.py:53:14:57:5 | ControlFlowNode for Dict | provenance | Config | +| PoC/server.py:61:27:61:58 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | PoC/server.py:61:27:61:58 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:61:37:61:57 | ControlFlowNode for Dict [Dictionary element at key $function] | PoC/server.py:61:27:61:58 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | provenance | | +| PoC/server.py:61:51:61:56 | ControlFlowNode for search | PoC/server.py:61:37:61:57 | ControlFlowNode for Dict [Dictionary element at key $function] | provenance | | | PoC/server.py:77:5:77:10 | ControlFlowNode for author | PoC/server.py:80:23:80:101 | ControlFlowNode for BinaryExpr | provenance | | | PoC/server.py:77:14:77:20 | ControlFlowNode for request | PoC/server.py:77:5:77:10 | ControlFlowNode for author | provenance | AdditionalTaintStep | -| PoC/server.py:78:5:78:15 | ControlFlowNode for accumulator | PoC/server.py:84:5:84:9 | ControlFlowNode for group | provenance | | +| PoC/server.py:78:5:78:15 | ControlFlowNode for accumulator | PoC/server.py:86:37:86:47 | ControlFlowNode for accumulator | provenance | | | PoC/server.py:78:19:83:5 | ControlFlowNode for Dict | PoC/server.py:78:5:78:15 | ControlFlowNode for accumulator | provenance | | | PoC/server.py:80:23:80:101 | ControlFlowNode for BinaryExpr | PoC/server.py:78:19:83:5 | ControlFlowNode for Dict | provenance | Config | -| PoC/server.py:84:5:84:9 | ControlFlowNode for group | PoC/server.py:91:29:91:47 | ControlFlowNode for Dict | provenance | | -| PoC/server.py:84:5:84:9 | ControlFlowNode for group | PoC/server.py:92:38:92:56 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:84:5:84:9 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:91:41:91:45 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | +| PoC/server.py:84:5:84:9 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:92:50:92:54 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | +| PoC/server.py:84:13:87:5 | ControlFlowNode for Dict [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:84:5:84:9 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | +| PoC/server.py:86:19:86:49 | ControlFlowNode for Dict [Dictionary element at key $accumulator] | PoC/server.py:84:13:87:5 | ControlFlowNode for Dict [Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | +| PoC/server.py:86:37:86:47 | ControlFlowNode for accumulator | PoC/server.py:86:19:86:49 | ControlFlowNode for Dict [Dictionary element at key $accumulator] | provenance | | +| PoC/server.py:91:29:91:47 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:91:29:91:47 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:91:41:91:45 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:91:29:91:47 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | +| PoC/server.py:92:38:92:56 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:92:38:92:56 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:92:50:92:54 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:92:38:92:56 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | | PoC/server.py:98:5:98:10 | ControlFlowNode for author | PoC/server.py:99:5:99:10 | ControlFlowNode for mapper | provenance | | | PoC/server.py:98:14:98:20 | ControlFlowNode for request | PoC/server.py:98:5:98:10 | ControlFlowNode for author | provenance | AdditionalTaintStep | | PoC/server.py:99:5:99:10 | ControlFlowNode for mapper | PoC/server.py:102:9:102:14 | ControlFlowNode for mapper | provenance | | @@ -39,16 +53,20 @@ edges | flask_mongoengine_bad.py:20:30:20:42 | ControlFlowNode for unsafe_search | flask_mongoengine_bad.py:20:19:20:43 | ControlFlowNode for Attribute() | provenance | Config | | flask_mongoengine_bad.py:26:5:26:17 | ControlFlowNode for unsafe_search | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | provenance | | | flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | flask_mongoengine_bad.py:26:5:26:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | -| flask_mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | provenance | | +| flask_mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | flask_mongoengine_bad.py:30:48:30:58 | ControlFlowNode for json_search | provenance | | | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | flask_mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | provenance | | | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | provenance | Config | +| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict [Dictionary element at key name] | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | provenance | | +| flask_mongoengine_bad.py:30:48:30:58 | ControlFlowNode for json_search | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for request | provenance | | | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for request | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | provenance | | | flask_pymongo_bad.py:11:5:11:17 | ControlFlowNode for unsafe_search | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | provenance | | | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | flask_pymongo_bad.py:11:5:11:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | -| flask_pymongo_bad.py:12:5:12:15 | ControlFlowNode for json_search | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | provenance | | +| flask_pymongo_bad.py:12:5:12:15 | ControlFlowNode for json_search | flask_pymongo_bad.py:14:40:14:50 | ControlFlowNode for json_search | provenance | | | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | flask_pymongo_bad.py:12:5:12:15 | ControlFlowNode for json_search | provenance | | | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | provenance | Config | +| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict [Dictionary element at key name] | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | provenance | | +| flask_pymongo_bad.py:14:40:14:50 | ControlFlowNode for json_search | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for request | provenance | | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for request | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | provenance | | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for request | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | provenance | | @@ -58,24 +76,32 @@ edges | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for request | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | provenance | | | mongoengine_bad.py:18:5:18:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:19:30:19:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | mongoengine_bad.py:18:5:18:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | -| mongoengine_bad.py:19:5:19:15 | ControlFlowNode for json_search | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:19:5:19:15 | ControlFlowNode for json_search | mongoengine_bad.py:22:35:22:45 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:19:19:19:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:19:5:19:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:19:30:19:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:19:19:19:43 | ControlFlowNode for Attribute() | provenance | Config | +| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:22:35:22:45 | ControlFlowNode for json_search | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | | mongoengine_bad.py:26:5:26:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | mongoengine_bad.py:26:5:26:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | -| mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | mongoengine_bad.py:30:35:30:45 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | provenance | Config | +| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:30:35:30:45 | ControlFlowNode for json_search | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | | mongoengine_bad.py:34:5:34:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:35:30:35:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | mongoengine_bad.py:34:5:34:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | -| mongoengine_bad.py:35:5:35:15 | ControlFlowNode for json_search | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:35:5:35:15 | ControlFlowNode for json_search | mongoengine_bad.py:38:35:38:45 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:35:5:35:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:35:30:35:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | provenance | Config | +| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:38:35:38:45 | ControlFlowNode for json_search | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | | mongoengine_bad.py:42:5:42:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:43:30:43:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | mongoengine_bad.py:42:5:42:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | -| mongoengine_bad.py:43:5:43:15 | ControlFlowNode for json_search | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:43:5:43:15 | ControlFlowNode for json_search | mongoengine_bad.py:46:35:46:45 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:43:5:43:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:43:30:43:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | provenance | Config | +| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:46:35:46:45 | ControlFlowNode for json_search | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | | mongoengine_bad.py:50:5:50:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:51:30:51:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | mongoengine_bad.py:50:5:50:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | | mongoengine_bad.py:51:5:51:15 | ControlFlowNode for json_search | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | provenance | | @@ -83,9 +109,11 @@ edges | mongoengine_bad.py:51:30:51:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:51:19:51:43 | ControlFlowNode for Attribute() | provenance | Config | | mongoengine_bad.py:57:5:57:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | mongoengine_bad.py:57:5:57:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | -| mongoengine_bad.py:58:5:58:15 | ControlFlowNode for json_search | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:58:5:58:15 | ControlFlowNode for json_search | mongoengine_bad.py:61:38:61:48 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:58:5:58:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | provenance | Config | +| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | provenance | | +| mongoengine_bad.py:61:38:61:48 | ControlFlowNode for json_search | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:1:26:1:32 | ControlFlowNode for request | provenance | | | pymongo_test.py:1:26:1:32 | ControlFlowNode for request | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | provenance | | | pymongo_test.py:1:26:1:32 | ControlFlowNode for request | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | provenance | | @@ -93,32 +121,49 @@ edges | pymongo_test.py:1:26:1:32 | ControlFlowNode for request | pymongo_test.py:52:26:52:32 | ControlFlowNode for request | provenance | | | pymongo_test.py:12:5:12:17 | ControlFlowNode for unsafe_search | pymongo_test.py:13:30:13:42 | ControlFlowNode for unsafe_search | provenance | | | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | pymongo_test.py:12:5:12:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | -| pymongo_test.py:13:5:13:15 | ControlFlowNode for json_search | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:13:5:13:15 | ControlFlowNode for json_search | pymongo_test.py:15:51:15:61 | ControlFlowNode for json_search | provenance | | | pymongo_test.py:13:19:13:43 | ControlFlowNode for Attribute() | pymongo_test.py:13:5:13:15 | ControlFlowNode for json_search | provenance | | | pymongo_test.py:13:30:13:42 | ControlFlowNode for unsafe_search | pymongo_test.py:13:19:13:43 | ControlFlowNode for Attribute() | provenance | Config | +| pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict [Dictionary element at key data] | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:15:51:15:61 | ControlFlowNode for json_search | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict [Dictionary element at key data] | provenance | | | pymongo_test.py:29:5:29:12 | ControlFlowNode for event_id | pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | provenance | | | pymongo_test.py:29:16:29:51 | ControlFlowNode for Attribute() | pymongo_test.py:29:5:29:12 | ControlFlowNode for event_id | provenance | | | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | pymongo_test.py:29:27:29:50 | ControlFlowNode for Subscript | provenance | AdditionalTaintStep | | pymongo_test.py:29:27:29:50 | ControlFlowNode for Subscript | pymongo_test.py:29:16:29:51 | ControlFlowNode for Attribute() | provenance | Config | -| pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict [Dictionary element at key $where] | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | provenance | | | pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | provenance | Decoding-NoSQL | +| pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict [Dictionary element at key $where] | provenance | | | pymongo_test.py:39:5:39:12 | ControlFlowNode for event_id | pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | provenance | | | pymongo_test.py:39:16:39:51 | ControlFlowNode for Attribute() | pymongo_test.py:39:5:39:12 | ControlFlowNode for event_id | provenance | | | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | provenance | AdditionalTaintStep | | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | pymongo_test.py:39:16:39:51 | ControlFlowNode for Attribute() | provenance | Config | -| pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict [Dictionary element at key $where] | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | provenance | | | pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | provenance | Decoding-NoSQL | +| pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict [Dictionary element at key $where] | provenance | | | pymongo_test.py:52:5:52:11 | ControlFlowNode for decoded | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | provenance | | | pymongo_test.py:52:15:52:50 | ControlFlowNode for Attribute() | pymongo_test.py:52:5:52:11 | ControlFlowNode for decoded | provenance | | | pymongo_test.py:52:26:52:32 | ControlFlowNode for request | pymongo_test.py:52:26:52:49 | ControlFlowNode for Subscript | provenance | AdditionalTaintStep | | pymongo_test.py:52:26:52:49 | ControlFlowNode for Subscript | pymongo_test.py:52:15:52:50 | ControlFlowNode for Attribute() | provenance | Config | -| pymongo_test.py:54:5:54:10 | ControlFlowNode for search | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:54:5:54:10 | ControlFlowNode for search | pymongo_test.py:59:49:59:54 | ControlFlowNode for search | provenance | | +| pymongo_test.py:54:5:54:10 | ControlFlowNode for search [Dictionary element at key body] | pymongo_test.py:59:49:59:54 | ControlFlowNode for search [Dictionary element at key body] | provenance | | | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict | pymongo_test.py:54:5:54:10 | ControlFlowNode for search | provenance | | -| pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict [Dictionary element at key body] | pymongo_test.py:54:5:54:10 | ControlFlowNode for search [Dictionary element at key body] | provenance | | | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict | provenance | Decoding-NoSQL | -| pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict | provenance | | -| pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict [Dictionary element at key body] | provenance | | +| pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:61:49:61:55 | ControlFlowNode for decoded | provenance | | +| pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:62:35:62:41 | ControlFlowNode for decoded | provenance | | | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:63:25:63:31 | ControlFlowNode for decoded | provenance | | +| pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function, Dictionary element at key body] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function, Dictionary element at key body] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function, Dictionary element at key body] | provenance | | +| pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | provenance | | +| pymongo_test.py:59:49:59:54 | ControlFlowNode for search | pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function] | provenance | | +| pymongo_test.py:59:49:59:54 | ControlFlowNode for search [Dictionary element at key body] | pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function, Dictionary element at key body] | provenance | | +| pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:61:35:61:56 | ControlFlowNode for Dict [Dictionary element at key $function] | pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | provenance | | +| pymongo_test.py:61:49:61:55 | ControlFlowNode for decoded | pymongo_test.py:61:35:61:56 | ControlFlowNode for Dict [Dictionary element at key $function] | provenance | | +| pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict [Dictionary element at key $expr] | pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:62:35:62:41 | ControlFlowNode for decoded | pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict [Dictionary element at key $expr] | provenance | | nodes | PoC/server.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | PoC/server.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -128,7 +173,11 @@ nodes | PoC/server.py:27:14:27:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | PoC/server.py:27:25:27:37 | ControlFlowNode for author_string | semmle.label | ControlFlowNode for author_string | | PoC/server.py:30:27:30:44 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| PoC/server.py:30:27:30:44 | ControlFlowNode for Dict [Dictionary element at key author] | semmle.label | ControlFlowNode for Dict [Dictionary element at key author] | +| PoC/server.py:30:38:30:43 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | | PoC/server.py:31:34:31:51 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| PoC/server.py:31:34:31:51 | ControlFlowNode for Dict [Dictionary element at key author] | semmle.label | ControlFlowNode for Dict [Dictionary element at key author] | +| PoC/server.py:31:45:31:50 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | | PoC/server.py:43:5:43:10 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | | PoC/server.py:43:14:43:20 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | PoC/server.py:47:27:47:68 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | @@ -139,14 +188,24 @@ nodes | PoC/server.py:53:14:57:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | | PoC/server.py:54:17:54:70 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | PoC/server.py:61:27:61:58 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| PoC/server.py:61:27:61:58 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | +| PoC/server.py:61:37:61:57 | ControlFlowNode for Dict [Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $function] | +| PoC/server.py:61:51:61:56 | ControlFlowNode for search | semmle.label | ControlFlowNode for search | | PoC/server.py:77:5:77:10 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | | PoC/server.py:77:14:77:20 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | PoC/server.py:78:5:78:15 | ControlFlowNode for accumulator | semmle.label | ControlFlowNode for accumulator | | PoC/server.py:78:19:83:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | | PoC/server.py:80:23:80:101 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| PoC/server.py:84:5:84:9 | ControlFlowNode for group | semmle.label | ControlFlowNode for group | +| PoC/server.py:84:5:84:9 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | +| PoC/server.py:84:13:87:5 | ControlFlowNode for Dict [Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for Dict [Dictionary element at key author, Dictionary element at key $accumulator] | +| PoC/server.py:86:19:86:49 | ControlFlowNode for Dict [Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $accumulator] | +| PoC/server.py:86:37:86:47 | ControlFlowNode for accumulator | semmle.label | ControlFlowNode for accumulator | | PoC/server.py:91:29:91:47 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| PoC/server.py:91:29:91:47 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | +| PoC/server.py:91:41:91:45 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | | PoC/server.py:92:38:92:56 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| PoC/server.py:92:38:92:56 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | +| PoC/server.py:92:50:92:54 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | | PoC/server.py:98:5:98:10 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | | PoC/server.py:98:14:98:20 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | PoC/server.py:99:5:99:10 | ControlFlowNode for mapper | semmle.label | ControlFlowNode for mapper | @@ -165,6 +224,8 @@ nodes | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | +| flask_mongoengine_bad.py:30:48:30:58 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_pymongo_bad.py:11:5:11:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | @@ -173,6 +234,8 @@ nodes | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | +| flask_pymongo_bad.py:14:40:14:50 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | mongoengine_bad.py:18:5:18:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | @@ -181,24 +244,32 @@ nodes | mongoengine_bad.py:19:19:19:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:19:30:19:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | +| mongoengine_bad.py:22:35:22:45 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:26:5:26:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | +| mongoengine_bad.py:30:35:30:45 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:34:5:34:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | mongoengine_bad.py:35:5:35:15 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:35:30:35:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | +| mongoengine_bad.py:38:35:38:45 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:42:5:42:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | mongoengine_bad.py:43:5:43:15 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:43:30:43:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | +| mongoengine_bad.py:46:35:46:45 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:50:5:50:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | mongoengine_bad.py:51:5:51:15 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | @@ -211,6 +282,8 @@ nodes | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | +| mongoengine_bad.py:61:38:61:48 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | pymongo_test.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | pymongo_test.py:12:5:12:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | @@ -219,28 +292,45 @@ nodes | pymongo_test.py:13:19:13:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | pymongo_test.py:13:30:13:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict [Dictionary element at key data] | semmle.label | ControlFlowNode for Dict [Dictionary element at key data] | +| pymongo_test.py:15:51:15:61 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | pymongo_test.py:29:5:29:12 | ControlFlowNode for event_id | semmle.label | ControlFlowNode for event_id | | pymongo_test.py:29:16:29:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | pymongo_test.py:29:27:29:50 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict [Dictionary element at key $where] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $where] | | pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring | | pymongo_test.py:39:5:39:12 | ControlFlowNode for event_id | semmle.label | ControlFlowNode for event_id | | pymongo_test.py:39:16:39:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict [Dictionary element at key $where] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $where] | | pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring | | pymongo_test.py:52:5:52:11 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | | pymongo_test.py:52:15:52:50 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | pymongo_test.py:52:26:52:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | pymongo_test.py:52:26:52:49 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | pymongo_test.py:54:5:54:10 | ControlFlowNode for search | semmle.label | ControlFlowNode for search | +| pymongo_test.py:54:5:54:10 | ControlFlowNode for search [Dictionary element at key body] | semmle.label | ControlFlowNode for search [Dictionary element at key body] | | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict [Dictionary element at key body] | semmle.label | ControlFlowNode for Dict [Dictionary element at key body] | | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function, Dictionary element at key body] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function, Dictionary element at key body] | +| pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | +| pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function, Dictionary element at key body] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $function, Dictionary element at key body] | +| pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $function] | +| pymongo_test.py:59:49:59:54 | ControlFlowNode for search | semmle.label | ControlFlowNode for search | +| pymongo_test.py:59:49:59:54 | ControlFlowNode for search [Dictionary element at key body] | semmle.label | ControlFlowNode for search [Dictionary element at key body] | | pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | +| pymongo_test.py:61:35:61:56 | ControlFlowNode for Dict [Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $function] | +| pymongo_test.py:61:49:61:55 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | | pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict [Dictionary element at key $expr] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr] | +| pymongo_test.py:62:35:62:41 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | | pymongo_test.py:63:25:63:31 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | subpaths #select From facb3b681dd4aed6b7ff6928ab7c7a8f2c97e267 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 17 Sep 2024 23:04:19 +0200 Subject: [PATCH 084/226] Python: recover taint for % format strings --- .../python/dataflow/new/internal/DataFlowPrivate.qll | 11 +++++++++++ .../defaultAdditionalTaintStep/test_string.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 7cb48d4784d..2ec44234c08 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -1093,10 +1093,21 @@ module Conversions { ) } + predicate formatReadStep(Node nodeFrom, ContentSet c, Node nodeTo) { + // % formatting + exists(BinaryExprNode fmt | fmt = nodeTo.asCfgNode() | + fmt.getOp() instanceof Mod and + fmt.getRight() = nodeFrom.asCfgNode() + ) and + c instanceof TupleElementContent + } + predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) { decoderReadStep(nodeFrom, c, nodeTo) or encoderReadStep(nodeFrom, c, nodeTo) + or + formatReadStep(nodeFrom, c, nodeTo) } } diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py index 58d1c5160c4..42ac758bfff 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py @@ -115,7 +115,7 @@ def percent_fmt(): ensure_tainted( tainted_fmt % (1, 2), # $ tainted "%s foo bar" % ts, # $ tainted - "%s %s %s" % (1, 2, ts), # $ MISSING: tainted + "%s %s %s" % (1, 2, ts), # $ tainted ) From 93e7ab52b766ba4eba57713022a0243ac6c7f0d8 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Fri, 1 Nov 2024 14:52:09 +0100 Subject: [PATCH 085/226] Python: adjust test expectations We now find an alert on this line as we hope to It is not an alert for _full_ SSRF, though, since that configuration cannot handle multiple substitutions. --- .../PartialServerSideRequestForgery.expected | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected index 5deeefd8920..a8d90779312 100644 --- a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected +++ b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected @@ -1,4 +1,5 @@ #select +| full_partial_test.py:80:5:80:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:80:18:80:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | user-provided value | | full_partial_test.py:105:5:105:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:105:18:105:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | user-provided value | | full_partial_test.py:112:5:112:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:112:18:112:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | user-provided value | | full_partial_test.py:119:5:119:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:119:18:119:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | user-provided value | @@ -45,6 +46,7 @@ edges | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:41:18:41:24 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:42:17:42:23 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:66:18:66:24 | ControlFlowNode for request | provenance | | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:67:17:67:23 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:83:18:83:24 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:84:17:84:23 | ControlFlowNode for request | provenance | | | full_partial_test.py:1:19:1:25 | ControlFlowNode for request | full_partial_test.py:101:18:101:24 | ControlFlowNode for request | provenance | | @@ -80,9 +82,19 @@ edges | full_partial_test.py:61:5:61:7 | ControlFlowNode for url | full_partial_test.py:63:18:63:20 | ControlFlowNode for url | provenance | | | full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | full_partial_test.py:70:5:70:7 | ControlFlowNode for url | provenance | | | full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | full_partial_test.py:74:5:74:7 | ControlFlowNode for url | provenance | | +| full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | full_partial_test.py:78:38:78:47 | ControlFlowNode for user_input | provenance | | | full_partial_test.py:66:18:66:24 | ControlFlowNode for request | full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | provenance | AdditionalTaintStep | +| full_partial_test.py:66:18:66:24 | ControlFlowNode for request | full_partial_test.py:67:5:67:13 | ControlFlowNode for query_val | provenance | AdditionalTaintStep | +| full_partial_test.py:67:5:67:13 | ControlFlowNode for query_val | full_partial_test.py:78:50:78:58 | ControlFlowNode for query_val | provenance | | +| full_partial_test.py:67:17:67:23 | ControlFlowNode for request | full_partial_test.py:67:5:67:13 | ControlFlowNode for query_val | provenance | AdditionalTaintStep | | full_partial_test.py:70:5:70:7 | ControlFlowNode for url | full_partial_test.py:72:18:72:20 | ControlFlowNode for url | provenance | | | full_partial_test.py:74:5:74:7 | ControlFlowNode for url | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | provenance | | +| full_partial_test.py:78:5:78:7 | ControlFlowNode for url | full_partial_test.py:80:18:80:20 | ControlFlowNode for url | provenance | | +| full_partial_test.py:78:11:78:59 | ControlFlowNode for BinaryExpr | full_partial_test.py:78:5:78:7 | ControlFlowNode for url | provenance | | +| full_partial_test.py:78:38:78:47 | ControlFlowNode for user_input | full_partial_test.py:78:38:78:58 | ControlFlowNode for Tuple [Tuple element at index 0] | provenance | | +| full_partial_test.py:78:38:78:58 | ControlFlowNode for Tuple [Tuple element at index 0] | full_partial_test.py:78:11:78:59 | ControlFlowNode for BinaryExpr | provenance | | +| full_partial_test.py:78:38:78:58 | ControlFlowNode for Tuple [Tuple element at index 1] | full_partial_test.py:78:11:78:59 | ControlFlowNode for BinaryExpr | provenance | | +| full_partial_test.py:78:50:78:58 | ControlFlowNode for query_val | full_partial_test.py:78:38:78:58 | ControlFlowNode for Tuple [Tuple element at index 1] | provenance | | | full_partial_test.py:83:5:83:14 | ControlFlowNode for user_input | full_partial_test.py:87:5:87:7 | ControlFlowNode for url | provenance | | | full_partial_test.py:83:5:83:14 | ControlFlowNode for user_input | full_partial_test.py:91:5:91:7 | ControlFlowNode for url | provenance | | | full_partial_test.py:83:5:83:14 | ControlFlowNode for user_input | full_partial_test.py:95:5:95:7 | ControlFlowNode for url | provenance | | @@ -260,10 +272,19 @@ nodes | full_partial_test.py:63:18:63:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:66:5:66:14 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | | full_partial_test.py:66:18:66:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| full_partial_test.py:67:5:67:13 | ControlFlowNode for query_val | semmle.label | ControlFlowNode for query_val | +| full_partial_test.py:67:17:67:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:70:5:70:7 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:72:18:72:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:74:5:74:7 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:78:5:78:7 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| full_partial_test.py:78:11:78:59 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| full_partial_test.py:78:38:78:47 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | +| full_partial_test.py:78:38:78:58 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | +| full_partial_test.py:78:38:78:58 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] | +| full_partial_test.py:78:50:78:58 | ControlFlowNode for query_val | semmle.label | ControlFlowNode for query_val | +| full_partial_test.py:80:18:80:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | | full_partial_test.py:83:5:83:14 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | | full_partial_test.py:83:18:83:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:84:5:84:13 | ControlFlowNode for query_val | semmle.label | ControlFlowNode for query_val | @@ -409,5 +430,3 @@ nodes | test_requests.py:20:18:20:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_requests.py:22:34:22:43 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | subpaths -testFailures -| full_partial_test.py:80:23:80:80 | Comment # $ Alert[py/partial-ssrf] $ MISSING: Alert[py/full-ssrf] | Missing result: Alert[py/partial-ssrf] | From 9a180036a5593c15a3501d5be33ea8c7e7c1020e Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 11 Nov 2024 16:20:21 +0100 Subject: [PATCH 086/226] Python: conversion step for `format_map` and adjust collection test --- .../python/dataflow/new/internal/DataFlowPrivate.qll | 6 ++++++ .../defaultAdditionalTaintStep-py3/test_string.py | 2 +- .../defaultAdditionalTaintStep/test_collections.py | 8 +++++--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 2ec44234c08..aa4130fb6a8 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -1100,6 +1100,12 @@ module Conversions { fmt.getRight() = nodeFrom.asCfgNode() ) and c instanceof TupleElementContent + or + // format_map + // see https://docs.python.org/3/library/stdtypes.html#str.format_map + nodeTo.(MethodCallNode).calls(_, "format_map") and + nodeTo.(MethodCallNode).getArg(0) = nodeFrom and + c instanceof DictionaryElementContent } predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) { diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py index 4ef1572f089..41a14e73a27 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py @@ -17,7 +17,7 @@ def str_methods(): ts.casefold(), # $ tainted ts.format_map({}), # $ tainted - "{unsafe}".format_map({"unsafe": ts}), # $ MISSING: tainted + "{unsafe}".format_map({"unsafe": ts}), # $ tainted ) diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py index 73a369c0ece..a67438316f4 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py @@ -27,12 +27,14 @@ def test_construction(): tainted_dict, # $ tainted ) + # There are no implicit reads for list content as it is imprecise + # Therefore, list content stemming from precise content does not end up on the list itself. ensure_tainted( list(tainted_list), # $ tainted - list(tainted_tuple), # $ MISSING: tainted + list(tainted_tuple)[0], # $ tainted list(tainted_set), # $ tainted - list(tainted_dict.values()), # $ MISSING: tainted - list(tainted_dict.items()), # $ MISSING: tainted + list(tainted_dict.values())[0], # $ tainted + list(tainted_dict.items())[0], # $ tainted tuple(tainted_list), # $ tainted set(tainted_list), # $ tainted From 3275c814bd32893b43aad09bb9e915c18df210a8 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 11 Nov 2024 16:47:08 +0100 Subject: [PATCH 087/226] Python: reset test expectations --- ...ExternalAPIsUsedWithUntrustedData.expected | 1 - .../UntrustedDataToExternalAPI.expected | 5 -- .../StackTraceExposure.expected | 4 +- .../NoSqlInjection.expected | 76 +++++-------------- 4 files changed, 20 insertions(+), 66 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected index 7776cabb14c..a346aef9d22 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.expected @@ -1,4 +1,3 @@ -| hmac.new [**] | 1 | 1 | | hmac.new [keyword msg] | 1 | 1 | | hmac.new [position 1] | 1 | 1 | | unknown.lib.func [keyword kw] | 2 | 1 | diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected index 9a49e3cbfe4..08a5b798f71 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected @@ -15,8 +15,6 @@ edges | test.py:23:16:23:27 | ControlFlowNode for Attribute | test.py:23:16:23:39 | ControlFlowNode for Attribute() | provenance | dict.get | | test.py:23:16:23:39 | ControlFlowNode for Attribute() | test.py:23:5:23:12 | ControlFlowNode for data_raw | provenance | | | test.py:24:5:24:8 | ControlFlowNode for data | test.py:25:44:25:47 | ControlFlowNode for data | provenance | | -| test.py:24:5:24:8 | ControlFlowNode for data | test.py:25:44:25:47 | ControlFlowNode for data | provenance | | -| test.py:25:44:25:47 | ControlFlowNode for data | test.py:25:15:25:74 | SynthDictSplatArgumentNode | provenance | | | test.py:34:5:34:8 | ControlFlowNode for data | test.py:35:10:35:13 | ControlFlowNode for data | provenance | | | test.py:34:5:34:8 | ControlFlowNode for data | test.py:36:13:36:16 | ControlFlowNode for data | provenance | | | test.py:34:12:34:18 | ControlFlowNode for request | test.py:34:12:34:23 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | @@ -47,8 +45,6 @@ nodes | test.py:23:16:23:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:23:16:23:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:24:5:24:8 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | -| test.py:25:15:25:74 | SynthDictSplatArgumentNode | semmle.label | SynthDictSplatArgumentNode | -| test.py:25:44:25:47 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | | test.py:25:44:25:47 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | | test.py:34:5:34:8 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | | test.py:34:12:34:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -72,7 +68,6 @@ nodes subpaths #select | test.py:15:36:15:39 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [position 1] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | -| test.py:25:15:25:74 | SynthDictSplatArgumentNode | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:25:15:25:74 | SynthDictSplatArgumentNode | Call to hmac.new [**] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | | test.py:25:44:25:47 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:25:44:25:47 | ControlFlowNode for data | Call to hmac.new [keyword msg] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | | test.py:35:10:35:13 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:35:10:35:13 | ControlFlowNode for data | Call to unknown.lib.func [position 0] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | | test.py:36:13:36:16 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:36:13:36:16 | ControlFlowNode for data | Call to unknown.lib.func [keyword kw] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember | diff --git a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected index 961eaac5143..b24fd261ea8 100644 --- a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected +++ b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected @@ -8,8 +8,7 @@ edges | test.py:50:29:50:31 | ControlFlowNode for err | test.py:52:18:52:20 | ControlFlowNode for msg | provenance | | | test.py:52:18:52:20 | ControlFlowNode for msg | test.py:53:12:53:27 | ControlFlowNode for BinaryExpr | provenance | | | test.py:65:25:65:25 | ControlFlowNode for e | test.py:66:34:66:39 | ControlFlowNode for str() | provenance | | -| test.py:66:24:66:40 | ControlFlowNode for Dict [Dictionary element at key error] | test.py:66:24:66:40 | ControlFlowNode for Dict | provenance | | -| test.py:66:34:66:39 | ControlFlowNode for str() | test.py:66:24:66:40 | ControlFlowNode for Dict [Dictionary element at key error] | provenance | | +| test.py:66:34:66:39 | ControlFlowNode for str() | test.py:66:24:66:40 | ControlFlowNode for Dict | provenance | | nodes | test.py:16:16:16:37 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:23:25:23:25 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | @@ -25,7 +24,6 @@ nodes | test.py:53:12:53:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | test.py:65:25:65:25 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | | test.py:66:24:66:40 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| test.py:66:24:66:40 | ControlFlowNode for Dict [Dictionary element at key error] | semmle.label | ControlFlowNode for Dict [Dictionary element at key error] | | test.py:66:34:66:39 | ControlFlowNode for str() | semmle.label | ControlFlowNode for str() | subpaths | test.py:50:29:50:31 | ControlFlowNode for err | test.py:52:18:52:20 | ControlFlowNode for msg | test.py:53:12:53:27 | ControlFlowNode for BinaryExpr | test.py:50:16:50:32 | ControlFlowNode for format_error() | diff --git a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected index fb8920cf03c..2ff9a0d10b7 100644 --- a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected @@ -11,10 +11,8 @@ edges | PoC/server.py:27:5:27:10 | ControlFlowNode for author | PoC/server.py:31:45:31:50 | ControlFlowNode for author | provenance | | | PoC/server.py:27:14:27:38 | ControlFlowNode for Attribute() | PoC/server.py:27:5:27:10 | ControlFlowNode for author | provenance | | | PoC/server.py:27:25:27:37 | ControlFlowNode for author_string | PoC/server.py:27:14:27:38 | ControlFlowNode for Attribute() | provenance | Config | -| PoC/server.py:30:27:30:44 | ControlFlowNode for Dict [Dictionary element at key author] | PoC/server.py:30:27:30:44 | ControlFlowNode for Dict | provenance | | -| PoC/server.py:30:38:30:43 | ControlFlowNode for author | PoC/server.py:30:27:30:44 | ControlFlowNode for Dict [Dictionary element at key author] | provenance | | -| PoC/server.py:31:34:31:51 | ControlFlowNode for Dict [Dictionary element at key author] | PoC/server.py:31:34:31:51 | ControlFlowNode for Dict | provenance | | -| PoC/server.py:31:45:31:50 | ControlFlowNode for author | PoC/server.py:31:34:31:51 | ControlFlowNode for Dict [Dictionary element at key author] | provenance | | +| PoC/server.py:30:38:30:43 | ControlFlowNode for author | PoC/server.py:30:27:30:44 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:31:45:31:50 | ControlFlowNode for author | PoC/server.py:31:34:31:51 | ControlFlowNode for Dict | provenance | | | PoC/server.py:43:5:43:10 | ControlFlowNode for author | PoC/server.py:47:38:47:67 | ControlFlowNode for BinaryExpr | provenance | | | PoC/server.py:43:14:43:20 | ControlFlowNode for request | PoC/server.py:43:5:43:10 | ControlFlowNode for author | provenance | AdditionalTaintStep | | PoC/server.py:47:38:47:67 | ControlFlowNode for BinaryExpr | PoC/server.py:47:27:47:68 | ControlFlowNode for Dict | provenance | Config | @@ -23,8 +21,7 @@ edges | PoC/server.py:53:5:53:10 | ControlFlowNode for search | PoC/server.py:61:51:61:56 | ControlFlowNode for search | provenance | | | PoC/server.py:53:14:57:5 | ControlFlowNode for Dict | PoC/server.py:53:5:53:10 | ControlFlowNode for search | provenance | | | PoC/server.py:54:17:54:70 | ControlFlowNode for BinaryExpr | PoC/server.py:53:14:57:5 | ControlFlowNode for Dict | provenance | Config | -| PoC/server.py:61:27:61:58 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | PoC/server.py:61:27:61:58 | ControlFlowNode for Dict | provenance | | -| PoC/server.py:61:37:61:57 | ControlFlowNode for Dict [Dictionary element at key $function] | PoC/server.py:61:27:61:58 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | provenance | | +| PoC/server.py:61:37:61:57 | ControlFlowNode for Dict [Dictionary element at key $function] | PoC/server.py:61:27:61:58 | ControlFlowNode for Dict | provenance | | | PoC/server.py:61:51:61:56 | ControlFlowNode for search | PoC/server.py:61:37:61:57 | ControlFlowNode for Dict [Dictionary element at key $function] | provenance | | | PoC/server.py:77:5:77:10 | ControlFlowNode for author | PoC/server.py:80:23:80:101 | ControlFlowNode for BinaryExpr | provenance | | | PoC/server.py:77:14:77:20 | ControlFlowNode for request | PoC/server.py:77:5:77:10 | ControlFlowNode for author | provenance | AdditionalTaintStep | @@ -36,10 +33,8 @@ edges | PoC/server.py:84:13:87:5 | ControlFlowNode for Dict [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:84:5:84:9 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | | PoC/server.py:86:19:86:49 | ControlFlowNode for Dict [Dictionary element at key $accumulator] | PoC/server.py:84:13:87:5 | ControlFlowNode for Dict [Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | | PoC/server.py:86:37:86:47 | ControlFlowNode for accumulator | PoC/server.py:86:19:86:49 | ControlFlowNode for Dict [Dictionary element at key $accumulator] | provenance | | -| PoC/server.py:91:29:91:47 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:91:29:91:47 | ControlFlowNode for Dict | provenance | | -| PoC/server.py:91:41:91:45 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:91:29:91:47 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | -| PoC/server.py:92:38:92:56 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:92:38:92:56 | ControlFlowNode for Dict | provenance | | -| PoC/server.py:92:50:92:54 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:92:38:92:56 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | provenance | | +| PoC/server.py:91:41:91:45 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:91:29:91:47 | ControlFlowNode for Dict | provenance | | +| PoC/server.py:92:50:92:54 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | PoC/server.py:92:38:92:56 | ControlFlowNode for Dict | provenance | | | PoC/server.py:98:5:98:10 | ControlFlowNode for author | PoC/server.py:99:5:99:10 | ControlFlowNode for mapper | provenance | | | PoC/server.py:98:14:98:20 | ControlFlowNode for request | PoC/server.py:98:5:98:10 | ControlFlowNode for author | provenance | AdditionalTaintStep | | PoC/server.py:99:5:99:10 | ControlFlowNode for mapper | PoC/server.py:102:9:102:14 | ControlFlowNode for mapper | provenance | | @@ -56,8 +51,7 @@ edges | flask_mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | flask_mongoengine_bad.py:30:48:30:58 | ControlFlowNode for json_search | provenance | | | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | flask_mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | provenance | | | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | provenance | Config | -| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict [Dictionary element at key name] | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | provenance | | -| flask_mongoengine_bad.py:30:48:30:58 | ControlFlowNode for json_search | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | +| flask_mongoengine_bad.py:30:48:30:58 | ControlFlowNode for json_search | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | provenance | | | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for request | provenance | | | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for request | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | provenance | | | flask_pymongo_bad.py:11:5:11:17 | ControlFlowNode for unsafe_search | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | provenance | | @@ -65,8 +59,7 @@ edges | flask_pymongo_bad.py:12:5:12:15 | ControlFlowNode for json_search | flask_pymongo_bad.py:14:40:14:50 | ControlFlowNode for json_search | provenance | | | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | flask_pymongo_bad.py:12:5:12:15 | ControlFlowNode for json_search | provenance | | | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | provenance | Config | -| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict [Dictionary element at key name] | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | provenance | | -| flask_pymongo_bad.py:14:40:14:50 | ControlFlowNode for json_search | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | +| flask_pymongo_bad.py:14:40:14:50 | ControlFlowNode for json_search | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | provenance | | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for request | provenance | | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for request | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | provenance | | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for request | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | provenance | | @@ -79,29 +72,25 @@ edges | mongoengine_bad.py:19:5:19:15 | ControlFlowNode for json_search | mongoengine_bad.py:22:35:22:45 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:19:19:19:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:19:5:19:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:19:30:19:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:19:19:19:43 | ControlFlowNode for Attribute() | provenance | Config | -| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | provenance | | -| mongoengine_bad.py:22:35:22:45 | ControlFlowNode for json_search | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | +| mongoengine_bad.py:22:35:22:45 | ControlFlowNode for json_search | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | provenance | | | mongoengine_bad.py:26:5:26:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | mongoengine_bad.py:26:5:26:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | | mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | mongoengine_bad.py:30:35:30:45 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:27:5:27:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | provenance | Config | -| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | provenance | | -| mongoengine_bad.py:30:35:30:45 | ControlFlowNode for json_search | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | +| mongoengine_bad.py:30:35:30:45 | ControlFlowNode for json_search | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | provenance | | | mongoengine_bad.py:34:5:34:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:35:30:35:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | mongoengine_bad.py:34:5:34:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | | mongoengine_bad.py:35:5:35:15 | ControlFlowNode for json_search | mongoengine_bad.py:38:35:38:45 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:35:5:35:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:35:30:35:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | provenance | Config | -| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | provenance | | -| mongoengine_bad.py:38:35:38:45 | ControlFlowNode for json_search | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | +| mongoengine_bad.py:38:35:38:45 | ControlFlowNode for json_search | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | provenance | | | mongoengine_bad.py:42:5:42:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:43:30:43:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | mongoengine_bad.py:42:5:42:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | | mongoengine_bad.py:43:5:43:15 | ControlFlowNode for json_search | mongoengine_bad.py:46:35:46:45 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:43:5:43:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:43:30:43:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | provenance | Config | -| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | provenance | | -| mongoengine_bad.py:46:35:46:45 | ControlFlowNode for json_search | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | +| mongoengine_bad.py:46:35:46:45 | ControlFlowNode for json_search | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | provenance | | | mongoengine_bad.py:50:5:50:17 | ControlFlowNode for unsafe_search | mongoengine_bad.py:51:30:51:42 | ControlFlowNode for unsafe_search | provenance | | | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | mongoengine_bad.py:50:5:50:17 | ControlFlowNode for unsafe_search | provenance | AdditionalTaintStep | | mongoengine_bad.py:51:5:51:15 | ControlFlowNode for json_search | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | provenance | | @@ -112,8 +101,7 @@ edges | mongoengine_bad.py:58:5:58:15 | ControlFlowNode for json_search | mongoengine_bad.py:61:38:61:48 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:58:5:58:15 | ControlFlowNode for json_search | provenance | | | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | provenance | Config | -| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict [Dictionary element at key name] | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | provenance | | -| mongoengine_bad.py:61:38:61:48 | ControlFlowNode for json_search | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict [Dictionary element at key name] | provenance | | +| mongoengine_bad.py:61:38:61:48 | ControlFlowNode for json_search | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | provenance | | | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:1:26:1:32 | ControlFlowNode for request | provenance | | | pymongo_test.py:1:26:1:32 | ControlFlowNode for request | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | provenance | | | pymongo_test.py:1:26:1:32 | ControlFlowNode for request | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | provenance | | @@ -124,22 +112,19 @@ edges | pymongo_test.py:13:5:13:15 | ControlFlowNode for json_search | pymongo_test.py:15:51:15:61 | ControlFlowNode for json_search | provenance | | | pymongo_test.py:13:19:13:43 | ControlFlowNode for Attribute() | pymongo_test.py:13:5:13:15 | ControlFlowNode for json_search | provenance | | | pymongo_test.py:13:30:13:42 | ControlFlowNode for unsafe_search | pymongo_test.py:13:19:13:43 | ControlFlowNode for Attribute() | provenance | Config | -| pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict [Dictionary element at key data] | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | provenance | | -| pymongo_test.py:15:51:15:61 | ControlFlowNode for json_search | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict [Dictionary element at key data] | provenance | | +| pymongo_test.py:15:51:15:61 | ControlFlowNode for json_search | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | provenance | | | pymongo_test.py:29:5:29:12 | ControlFlowNode for event_id | pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | provenance | | | pymongo_test.py:29:16:29:51 | ControlFlowNode for Attribute() | pymongo_test.py:29:5:29:12 | ControlFlowNode for event_id | provenance | | | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | pymongo_test.py:29:27:29:50 | ControlFlowNode for Subscript | provenance | AdditionalTaintStep | | pymongo_test.py:29:27:29:50 | ControlFlowNode for Subscript | pymongo_test.py:29:16:29:51 | ControlFlowNode for Attribute() | provenance | Config | -| pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict [Dictionary element at key $where] | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | provenance | | | pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | provenance | Decoding-NoSQL | -| pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict [Dictionary element at key $where] | provenance | | | pymongo_test.py:39:5:39:12 | ControlFlowNode for event_id | pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | provenance | | | pymongo_test.py:39:16:39:51 | ControlFlowNode for Attribute() | pymongo_test.py:39:5:39:12 | ControlFlowNode for event_id | provenance | | | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | provenance | AdditionalTaintStep | | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | pymongo_test.py:39:16:39:51 | ControlFlowNode for Attribute() | provenance | Config | -| pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict [Dictionary element at key $where] | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | provenance | | | pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | provenance | Decoding-NoSQL | -| pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict [Dictionary element at key $where] | provenance | | | pymongo_test.py:52:5:52:11 | ControlFlowNode for decoded | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | provenance | | | pymongo_test.py:52:15:52:50 | ControlFlowNode for Attribute() | pymongo_test.py:52:5:52:11 | ControlFlowNode for decoded | provenance | | | pymongo_test.py:52:26:52:32 | ControlFlowNode for request | pymongo_test.py:52:26:52:49 | ControlFlowNode for Subscript | provenance | AdditionalTaintStep | @@ -153,17 +138,13 @@ edges | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:61:49:61:55 | ControlFlowNode for decoded | provenance | | | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:62:35:62:41 | ControlFlowNode for decoded | provenance | | | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:63:25:63:31 | ControlFlowNode for decoded | provenance | | -| pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function, Dictionary element at key body] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict | provenance | | -| pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict | provenance | | -| pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function, Dictionary element at key body] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function, Dictionary element at key body] | provenance | | -| pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | provenance | | +| pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function, Dictionary element at key body] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict | provenance | | +| pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function] | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict | provenance | | | pymongo_test.py:59:49:59:54 | ControlFlowNode for search | pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function] | provenance | | | pymongo_test.py:59:49:59:54 | ControlFlowNode for search [Dictionary element at key body] | pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function, Dictionary element at key body] | provenance | | -| pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict | provenance | | -| pymongo_test.py:61:35:61:56 | ControlFlowNode for Dict [Dictionary element at key $function] | pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | provenance | | +| pymongo_test.py:61:35:61:56 | ControlFlowNode for Dict [Dictionary element at key $function] | pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict | provenance | | | pymongo_test.py:61:49:61:55 | ControlFlowNode for decoded | pymongo_test.py:61:35:61:56 | ControlFlowNode for Dict [Dictionary element at key $function] | provenance | | -| pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict [Dictionary element at key $expr] | pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict | provenance | | -| pymongo_test.py:62:35:62:41 | ControlFlowNode for decoded | pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict [Dictionary element at key $expr] | provenance | | +| pymongo_test.py:62:35:62:41 | ControlFlowNode for decoded | pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict | provenance | | nodes | PoC/server.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | PoC/server.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -173,10 +154,8 @@ nodes | PoC/server.py:27:14:27:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | PoC/server.py:27:25:27:37 | ControlFlowNode for author_string | semmle.label | ControlFlowNode for author_string | | PoC/server.py:30:27:30:44 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| PoC/server.py:30:27:30:44 | ControlFlowNode for Dict [Dictionary element at key author] | semmle.label | ControlFlowNode for Dict [Dictionary element at key author] | | PoC/server.py:30:38:30:43 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | | PoC/server.py:31:34:31:51 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| PoC/server.py:31:34:31:51 | ControlFlowNode for Dict [Dictionary element at key author] | semmle.label | ControlFlowNode for Dict [Dictionary element at key author] | | PoC/server.py:31:45:31:50 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | | PoC/server.py:43:5:43:10 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | | PoC/server.py:43:14:43:20 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -188,7 +167,6 @@ nodes | PoC/server.py:53:14:57:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | | PoC/server.py:54:17:54:70 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | PoC/server.py:61:27:61:58 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| PoC/server.py:61:27:61:58 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | | PoC/server.py:61:37:61:57 | ControlFlowNode for Dict [Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $function] | | PoC/server.py:61:51:61:56 | ControlFlowNode for search | semmle.label | ControlFlowNode for search | | PoC/server.py:77:5:77:10 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | @@ -201,10 +179,8 @@ nodes | PoC/server.py:86:19:86:49 | ControlFlowNode for Dict [Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $accumulator] | | PoC/server.py:86:37:86:47 | ControlFlowNode for accumulator | semmle.label | ControlFlowNode for accumulator | | PoC/server.py:91:29:91:47 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| PoC/server.py:91:29:91:47 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | | PoC/server.py:91:41:91:45 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | | PoC/server.py:92:38:92:56 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| PoC/server.py:92:38:92:56 | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $group, Dictionary element at key author, Dictionary element at key $accumulator] | | PoC/server.py:92:50:92:54 | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | semmle.label | ControlFlowNode for group [Dictionary element at key author, Dictionary element at key $accumulator] | | PoC/server.py:98:5:98:10 | ControlFlowNode for author | semmle.label | ControlFlowNode for author | | PoC/server.py:98:14:98:20 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -224,7 +200,6 @@ nodes | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | | flask_mongoengine_bad.py:30:48:30:58 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -234,7 +209,6 @@ nodes | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | | flask_pymongo_bad.py:14:40:14:50 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -244,7 +218,6 @@ nodes | mongoengine_bad.py:19:19:19:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:19:30:19:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | | mongoengine_bad.py:22:35:22:45 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:26:5:26:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -252,7 +225,6 @@ nodes | mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | | mongoengine_bad.py:30:35:30:45 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:34:5:34:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -260,7 +232,6 @@ nodes | mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:35:30:35:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | | mongoengine_bad.py:38:35:38:45 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:42:5:42:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -268,7 +239,6 @@ nodes | mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:43:30:43:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | | mongoengine_bad.py:46:35:46:45 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | mongoengine_bad.py:50:5:50:17 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -282,7 +252,6 @@ nodes | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict [Dictionary element at key name] | semmle.label | ControlFlowNode for Dict [Dictionary element at key name] | | mongoengine_bad.py:61:38:61:48 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | pymongo_test.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -292,21 +261,18 @@ nodes | pymongo_test.py:13:19:13:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | pymongo_test.py:13:30:13:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict [Dictionary element at key data] | semmle.label | ControlFlowNode for Dict [Dictionary element at key data] | | pymongo_test.py:15:51:15:61 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search | | pymongo_test.py:29:5:29:12 | ControlFlowNode for event_id | semmle.label | ControlFlowNode for event_id | | pymongo_test.py:29:16:29:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | pymongo_test.py:29:27:29:50 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict [Dictionary element at key $where] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $where] | | pymongo_test.py:33:45:33:72 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring | | pymongo_test.py:39:5:39:12 | ControlFlowNode for event_id | semmle.label | ControlFlowNode for event_id | | pymongo_test.py:39:16:39:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict [Dictionary element at key $where] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $where] | | pymongo_test.py:43:45:43:72 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring | | pymongo_test.py:52:5:52:11 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | | pymongo_test.py:52:15:52:50 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -318,18 +284,14 @@ nodes | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict [Dictionary element at key body] | semmle.label | ControlFlowNode for Dict [Dictionary element at key body] | | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | | pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function, Dictionary element at key body] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function, Dictionary element at key body] | -| pymongo_test.py:59:25:59:56 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | | pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function, Dictionary element at key body] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $function, Dictionary element at key body] | | pymongo_test.py:59:35:59:55 | ControlFlowNode for Dict [Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $function] | | pymongo_test.py:59:49:59:54 | ControlFlowNode for search | semmle.label | ControlFlowNode for search | | pymongo_test.py:59:49:59:54 | ControlFlowNode for search [Dictionary element at key body] | semmle.label | ControlFlowNode for search [Dictionary element at key body] | | pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| pymongo_test.py:61:25:61:57 | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr, Dictionary element at key $function] | | pymongo_test.py:61:35:61:56 | ControlFlowNode for Dict [Dictionary element at key $function] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $function] | | pymongo_test.py:61:49:61:55 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | | pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | -| pymongo_test.py:62:25:62:42 | ControlFlowNode for Dict [Dictionary element at key $expr] | semmle.label | ControlFlowNode for Dict [Dictionary element at key $expr] | | pymongo_test.py:62:35:62:41 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | | pymongo_test.py:63:25:63:31 | ControlFlowNode for decoded | semmle.label | ControlFlowNode for decoded | subpaths From f669a4f3bf16c34dffdb6b4d17e3ba85e8b5469e Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 11 Nov 2024 18:43:21 +0100 Subject: [PATCH 088/226] Python: Make sure all imprecise taint bubbles up --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 11 +++++++++-- .../defaultAdditionalTaintStep/test_collections.py | 10 ++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 5d3b994880a..7e5d0d8ab06 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4244,8 +4244,15 @@ module StdlibPrivate { ) // TODO: Once we have DictKeyContent, we need to transform that into ListElementContent ) and - output = "ReturnValue.ListElement" and - preservesValue = true + ( + //Element content is mutated into list element content + output = "ReturnValue.ListElement" and + preservesValue = true + or + // Since list content is imprecise, we also taint the list. + output = "ReturnValue" and + preservesValue = false + ) or input = "Argument[0]" and output = "ReturnValue" and diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py index a67438316f4..b9fa1ebffd4 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py @@ -27,14 +27,11 @@ def test_construction(): tainted_dict, # $ tainted ) - # There are no implicit reads for list content as it is imprecise - # Therefore, list content stemming from precise content does not end up on the list itself. ensure_tainted( list(tainted_list), # $ tainted - list(tainted_tuple)[0], # $ tainted + list(tainted_tuple), # $ tainted list(tainted_set), # $ tainted - list(tainted_dict.values())[0], # $ tainted - list(tainted_dict.items())[0], # $ tainted + list(tainted_dict.values()), # $ tainted tuple(tainted_list), # $ tainted set(tainted_list), # $ tainted @@ -46,7 +43,8 @@ def test_construction(): ) ensure_not_tainted( - dict(k = tainted_string)["k1"] + dict(k = tainted_string)["k1"], + list(tainted_dict.items()), ) From 0ecca91deaa76ac16677ee429f66e62389aebedb Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 13 Nov 2024 10:30:22 +0100 Subject: [PATCH 089/226] Python: typo --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 7e5d0d8ab06..1e0bd846181 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4245,7 +4245,7 @@ module StdlibPrivate { // TODO: Once we have DictKeyContent, we need to transform that into ListElementContent ) and ( - //Element content is mutated into list element content + // Element content is mutated into list element content output = "ReturnValue.ListElement" and preservesValue = true or From fa9426c74905b9bdd9cd390df3c3e76515160ca3 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 13 Nov 2024 10:31:06 +0100 Subject: [PATCH 090/226] Python: extra tests for comprehension --- python/ql/test/library-tests/frameworks/tornado/taint_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/ql/test/library-tests/frameworks/tornado/taint_test.py b/python/ql/test/library-tests/frameworks/tornado/taint_test.py index 7e80186a56f..c4f95ec511d 100644 --- a/python/ql/test/library-tests/frameworks/tornado/taint_test.py +++ b/python/ql/test/library-tests/frameworks/tornado/taint_test.py @@ -64,6 +64,8 @@ class TaintTest(tornado.web.RequestHandler): request.headers.get_list("header-name"), # $ tainted request.headers.get_all(), # $ tainted [(k, v) for (k, v) in request.headers.get_all()], # $ MISSING: tainted + [(k, v) for (k, v) in request.headers.get_all()][0], # $ tainted + list([(k, v) for (k, v) in request.headers.get_all()]), # $ MISSING: tainted # Dict[str, http.cookies.Morsel] request.cookies, # $ tainted From fa758d6bf5e44bbd22298de3ad609483b3f7988a Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 3 Dec 2024 18:33:47 +0100 Subject: [PATCH 091/226] python: fix test --- .../test/library-tests/frameworks/tornado/taint_test.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/python/ql/test/library-tests/frameworks/tornado/taint_test.py b/python/ql/test/library-tests/frameworks/tornado/taint_test.py index c4f95ec511d..d6dac013fbc 100644 --- a/python/ql/test/library-tests/frameworks/tornado/taint_test.py +++ b/python/ql/test/library-tests/frameworks/tornado/taint_test.py @@ -63,9 +63,8 @@ class TaintTest(tornado.web.RequestHandler): request.headers["header-name"], # $ tainted request.headers.get_list("header-name"), # $ tainted request.headers.get_all(), # $ tainted - [(k, v) for (k, v) in request.headers.get_all()], # $ MISSING: tainted [(k, v) for (k, v) in request.headers.get_all()][0], # $ tainted - list([(k, v) for (k, v) in request.headers.get_all()]), # $ MISSING: tainted + list([(k, v) for (k, v) in request.headers.get_all()])[0], # $ tainted # Dict[str, http.cookies.Morsel] request.cookies, # $ tainted @@ -75,6 +74,11 @@ class TaintTest(tornado.web.RequestHandler): request.cookies["cookie-name"].coded_value, # $ tainted ) + ensure_not_tainted( + [(k, v) for (k, v) in request.headers.get_all()], # The comprehension is not tainted, only the elements + list([(k, v) for (k, v) in request.headers.get_all()]), # Here, all the elements of the list are tainted, but the list is not. + ) + def make_app(): return tornado.web.Application( From b6c2915f24a04f34a7a6e45a0cca89aa4ae497a3 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 19 May 2026 11:49:00 +0200 Subject: [PATCH 092/226] Ruby: Split callable and its body into two AST nodes. --- ruby/ql/consistency-queries/CfgConsistency.ql | 4 +- ruby/ql/lib/codeql/ruby/ast/Expr.qll | 2 + ruby/ql/lib/codeql/ruby/ast/Method.qll | 48 +++++++------- ruby/ql/lib/codeql/ruby/ast/internal/AST.qll | 64 +++++++++++-------- ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll | 33 ++++------ .../lib/codeql/ruby/ast/internal/Method.qll | 7 +- .../codeql/ruby/ast/internal/Synthesis.qll | 51 ++++++++++++--- .../dataflow/internal/DataFlowPrivate.qll | 2 +- .../ruby/dataflow/internal/DataFlowPublic.qll | 2 +- ruby/ql/lib/codeql/ruby/experimental/Rbi.qll | 8 +-- ruby/ql/lib/codeql/ruby/frameworks/Slim.qll | 2 +- .../lib/codeql/ruby/frameworks/XmlParsing.qll | 1 + .../actiondispatch/internal/Routing.qll | 10 +-- .../security/ImproperMemoizationQuery.qll | 2 +- .../ruby/security/InsecureDependencyQuery.qll | 2 +- 15 files changed, 139 insertions(+), 99 deletions(-) diff --git a/ruby/ql/consistency-queries/CfgConsistency.ql b/ruby/ql/consistency-queries/CfgConsistency.ql index c8d797b71f4..297b81678ee 100644 --- a/ruby/ql/consistency-queries/CfgConsistency.ql +++ b/ruby/ql/consistency-queries/CfgConsistency.ql @@ -27,7 +27,7 @@ query predicate scopeNoFirst(CfgScope scope) { not scope = any(Callable c | not exists(c.getAParameter()) and - not c.(BodyStmt).hasEnsure() and - not exists(c.(BodyStmt).getARescue()) + not c.getBody().hasEnsure() and + not exists(c.getBody().getARescue()) ) } diff --git a/ruby/ql/lib/codeql/ruby/ast/Expr.qll b/ruby/ql/lib/codeql/ruby/ast/Expr.qll index e932202e53f..a49cafa8299 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Expr.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Expr.qll @@ -167,6 +167,8 @@ class StmtSequence extends Expr, TStmtSequence { */ class BodyStmt extends StmtSequence, TBodyStmt { final override Stmt getStmt(int n) { + synthChild(this, n, result) + or toGenerated(result) = rank[n + 1](Ruby::AstNode node, int i | node = getBodyStmtChild(this, i) and diff --git a/ruby/ql/lib/codeql/ruby/ast/Method.qll b/ruby/ql/lib/codeql/ruby/ast/Method.qll index 1594b6e6311..38892da721e 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Method.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Method.qll @@ -8,7 +8,7 @@ private import internal.TreeSitter private import internal.Method /** A callable. */ -class Callable extends StmtSequence, Expr, Scope, TCallable { +class Callable extends Expr, Scope, TCallable { /** Gets the number of parameters of this callable. */ final int getNumberOfParameters() { result = count(this.getAParameter()) } @@ -18,27 +18,26 @@ class Callable extends StmtSequence, Expr, Scope, TCallable { /** Gets the `n`th parameter of this callable. */ Parameter getParameter(int n) { none() } + /** Gets the body of this callable. */ + BodyStmt getBody() { none() } + override AstNode getAChild(string pred) { result = super.getAChild(pred) or + pred = "getBody" and result = this.getBody() + or pred = "getParameter" and result = this.getParameter(_) } } /** A method. */ -class MethodBase extends Callable, BodyStmt, Scope, TMethodBase { +class MethodBase extends Callable, Scope, TMethodBase { /** Gets the name of this method. */ string getName() { none() } /** Holds if the name of this method is `name`. */ final predicate hasName(string name) { this.getName() = name } - override AstNode getAChild(string pred) { - result = Callable.super.getAChild(pred) - or - result = BodyStmt.super.getAChild(pred) - } - /** * Holds if this method is public. * Methods are public by default. @@ -218,6 +217,10 @@ class Method extends MethodBase, TMethod { toGenerated(result) = g.getParameters().getChild(n) } + final override BodyStmt getBody() { + toGenerated(result) = g.getBody() or synthChild(this, _, result) + } + final override string toString() { result = this.getName() } overlay[global] @@ -280,6 +283,10 @@ class SingletonMethod extends MethodBase, TSingletonMethod { toGenerated(result) = g.getParameters().getChild(n) } + final override BodyStmt getBody() { + toGenerated(result) = g.getBody() or synthChild(this, _, result) + } + final override string toString() { result = this.getName() } final override AstNode getAChild(string pred) { @@ -321,7 +328,7 @@ class SingletonMethod extends MethodBase, TSingletonMethod { * -> (x) { x + 1 } * ``` */ -class Lambda extends Callable, BodyStmt, TLambda { +class Lambda extends Callable, TLambda { private Ruby::Lambda g; Lambda() { this = TLambda(g) } @@ -332,13 +339,12 @@ class Lambda extends Callable, BodyStmt, TLambda { toGenerated(result) = g.getParameters().getChild(n) } - final override string toString() { result = "-> { ... }" } - - final override AstNode getAChild(string pred) { - result = Callable.super.getAChild(pred) - or - result = BodyStmt.super.getAChild(pred) + final override BodyStmt getBody() { + toGenerated(result) = g.getBody().(Ruby::DoBlock).getBody() or + toGenerated(result) = g.getBody().(Ruby::Block).getBody() } + + final override string toString() { result = "-> { ... }" } } /** A block. */ @@ -355,7 +361,7 @@ class Block extends Callable, Scope, TBlock { */ LocalVariableWriteAccess getLocalVariable(int n) { none() } - override AstNode getAChild(string pred) { + final override AstNode getAChild(string pred) { result = Callable.super.getAChild(pred) or pred = "getLocalVariable" and result = this.getLocalVariable(_) @@ -363,7 +369,7 @@ class Block extends Callable, Scope, TBlock { } /** A block enclosed within `do` and `end`. */ -class DoBlock extends Block, BodyStmt, TDoBlock { +class DoBlock extends Block, TDoBlock { private Ruby::DoBlock g; DoBlock() { this = TDoBlock(g) } @@ -376,13 +382,9 @@ class DoBlock extends Block, BodyStmt, TDoBlock { toGenerated(result) = g.getParameters().getChild(n) } - final override string toString() { result = "do ... end" } + final override BodyStmt getBody() { toGenerated(result) = g.getBody() } - final override AstNode getAChild(string pred) { - result = Block.super.getAChild(pred) - or - result = BodyStmt.super.getAChild(pred) - } + final override string toString() { result = "do ... end" } final override string getAPrimaryQlClass() { result = "DoBlock" } } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll b/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll index ee46fbe8b66..bf187e22699 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll @@ -100,9 +100,16 @@ private module Cached { } or TBlockArgument(Ruby::BlockArgument g) or TBlockParameter(Ruby::BlockParameter g) or + TBodyStatement(Ruby::BodyStatement g) { + any(Ruby::Method m).getBody() = g or + any(Ruby::SingletonMethod m).getBody() = g or + any(Ruby::DoBlock b).getBody() = g + } or + TBodyStmtSynth(Ast::AstNode parent, int i) { mkSynthChild(BodyStmtKind(), parent, i) } or TBooleanLiteralSynth(Ast::AstNode parent, int i, boolean value) { mkSynthChild(BooleanLiteralKind(value), parent, i) } or + TBraceBlockBody(Ruby::BlockBody g) or TBraceBlockSynth(Ast::AstNode parent, int i) { mkSynthChild(BraceBlockKind(), parent, i) } or TBraceBlockReal(Ruby::Block g) { not g.getParent() instanceof Ruby::Lambda } or TBreakStmt(Ruby::Break g) or @@ -362,23 +369,24 @@ private module Cached { TAssignMulExpr or TAssignRShiftExpr or TAssignSubExpr or TBareStringLiteral or TBareSymbolLiteral or TBeginBlock or TBeginExpr or TBitwiseAndExprReal or TBitwiseOrExprReal or TBitwiseXorExprReal or TBlockArgument or TBlockParameter or - TBraceBlockReal or TBreakStmt or TCaseEqExpr or TCaseExpr or TCaseMatchReal or - TCharacterLiteral or TClassDeclaration or TClassVariableAccessReal or TComplementExpr or - TComplexLiteral or TDefinedExprReal or TDelimitedSymbolLiteral or - TDestructuredLeftAssignment or TDestructuredParameter or TDivExprReal or TDo or TDoBlock or - TElementReference or TElseReal or TElsif or TEmptyStmt or TEncoding or TEndBlock or - TEnsure or TEqExpr or TExponentExprReal or TFalseLiteral or TFile or TFindPattern or - TFloatLiteral or TForExpr or TForwardParameter or TForwardArgument or TGEExpr or TGTExpr or - TGlobalVariableAccessReal or THashKeySymbolLiteral or THashLiteral or THashPattern or - THashSplatExprReal or THashSplatNilParameter or THashSplatParameter or THereDoc or - TIdentifierMethodCall or TIfReal or TIfModifierExpr or TInClauseReal or - TInstanceVariableAccessReal or TIntegerLiteralReal or TKeywordParameter or TLEExpr or - TLShiftExprReal or TLTExpr or TLambda or TLeftAssignmentList or TLine or - TLocalVariableAccessReal or TLogicalAndExprReal or TLogicalOrExprReal or TMethod or - TMatchPattern or TModuleDeclaration or TModuloExprReal or TMulExprReal or TNEExpr or - TNextStmt or TNilLiteralReal or TNoRegExpMatchExpr or TNotExprReal or TOptionalParameter or - TPairReal or TParenthesizedExpr or TParenthesizedPattern or TRShiftExprReal or - TRangeLiteralReal or TRationalLiteral or TRedoStmt or TRegExpLiteral or TRegExpMatchExpr or + TBodyStatement or TBraceBlockBody or TBraceBlockReal or TBreakStmt or TCaseEqExpr or + TCaseExpr or TCaseMatchReal or TCharacterLiteral or TClassDeclaration or + TClassVariableAccessReal or TComplementExpr or TComplexLiteral or TDefinedExprReal or + TDelimitedSymbolLiteral or TDestructuredLeftAssignment or TDestructuredParameter or + TDivExprReal or TDo or TDoBlock or TElementReference or TElseReal or TElsif or TEmptyStmt or + TEncoding or TEndBlock or TEnsure or TEqExpr or TExponentExprReal or TFalseLiteral or + TFile or TFindPattern or TFloatLiteral or TForExpr or TForwardParameter or + TForwardArgument or TGEExpr or TGTExpr or TGlobalVariableAccessReal or + THashKeySymbolLiteral or THashLiteral or THashPattern or THashSplatExprReal or + THashSplatNilParameter or THashSplatParameter or THereDoc or TIdentifierMethodCall or + TIfReal or TIfModifierExpr or TInClauseReal or TInstanceVariableAccessReal or + TIntegerLiteralReal or TKeywordParameter or TLEExpr or TLShiftExprReal or TLTExpr or + TLambda or TLeftAssignmentList or TLine or TLocalVariableAccessReal or + TLogicalAndExprReal or TLogicalOrExprReal or TMethod or TMatchPattern or + TModuleDeclaration or TModuloExprReal or TMulExprReal or TNEExpr or TNextStmt or + TNilLiteralReal or TNoRegExpMatchExpr or TNotExprReal or TOptionalParameter or TPairReal or + TParenthesizedExpr or TParenthesizedPattern or TRShiftExprReal or TRangeLiteralReal or + TRationalLiteral or TRedoStmt or TRegExpLiteral or TRegExpMatchExpr or TRegularArrayLiteral or TRegularMethodCall or TRegularStringLiteral or TRegularSuperCall or TRescueClause or TRescueModifierExpr or TRetryStmt or TReturnStmt or TScopeResolutionConstantAccess or TSelfReal or TSimpleParameterReal or @@ -393,13 +401,13 @@ private module Cached { class TAstNodeSynth = TAddExprSynth or TAssignExprSynth or TBitwiseAndExprSynth or TBitwiseOrExprSynth or - TBitwiseXorExprSynth or TBraceBlockSynth or TBooleanLiteralSynth or TCaseMatchSynth or - TClassVariableAccessSynth or TConstantReadAccessSynth or TConstantWriteAccessSynth or - TDivExprSynth or TElseSynth or TExponentExprSynth or TGlobalVariableAccessSynth or - TIfSynth or TInClauseSynth or TInstanceVariableAccessSynth or TIntegerLiteralSynth or - TLShiftExprSynth or TLocalVariableAccessSynth or TLogicalAndExprSynth or - TLogicalOrExprSynth or TMethodCallSynth or TModuloExprSynth or TMulExprSynth or - TNilLiteralSynth or TRShiftExprSynth or TRangeLiteralSynth or TSelfSynth or + TBitwiseXorExprSynth or TBraceBlockSynth or TBodyStmtSynth or TBooleanLiteralSynth or + TCaseMatchSynth or TClassVariableAccessSynth or TConstantReadAccessSynth or + TConstantWriteAccessSynth or TDivExprSynth or TElseSynth or TExponentExprSynth or + TGlobalVariableAccessSynth or TIfSynth or TInClauseSynth or TInstanceVariableAccessSynth or + TIntegerLiteralSynth or TLShiftExprSynth or TLocalVariableAccessSynth or + TLogicalAndExprSynth or TLogicalOrExprSynth or TMethodCallSynth or TModuloExprSynth or + TMulExprSynth or TNilLiteralSynth or TRShiftExprSynth or TRangeLiteralSynth or TSelfSynth or TSimpleParameterSynth or TSplatExprSynth or THashSplatExprSynth or TStmtSequenceSynth or TSubExprSynth or TPairSynth or TSimpleSymbolLiteralSynth; @@ -439,6 +447,8 @@ private module Cached { n = TBitwiseXorExprReal(result) or n = TBlockArgument(result) or n = TBlockParameter(result) or + n = TBodyStatement(result) or + n = TBraceBlockBody(result) or n = TBraceBlockReal(result) or n = TBreakStmt(result) or n = TCaseEqExpr(result) or @@ -584,6 +594,8 @@ private module Cached { or result = TBitwiseXorExprSynth(parent, i) or + result = TBodyStmtSynth(parent, i) + or result = TBooleanLiteralSynth(parent, i, _) or result = TBraceBlockSynth(parent, i) @@ -757,9 +769,9 @@ class TElse = TElseReal or TElseSynth; class TStmtSequence = TBeginBlock or TEndBlock or TThen or TElse or TDo or TEnsure or TStringInterpolationComponent or - TBlock or TBodyStmt or TParenthesizedExpr or TStmtSequenceSynth; + TBodyStmt or TParenthesizedExpr or TStmtSequenceSynth; -class TBodyStmt = TBeginExpr or TModuleBase or TMethod or TLambda or TDoBlock or TSingletonMethod; +class TBodyStmt = TBeginExpr or TModuleBase or TBraceBlockBody or TBodyStatement or TBodyStmtSynth; class TNilLiteral = TNilLiteralReal or TNilLiteralSynth; diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll index fdeec446a93..656b53eec46 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll @@ -14,6 +14,18 @@ class StmtSequenceSynth extends StmtSequence, TStmtSequenceSynth { final override string toString() { result = "..." } } +class BodyStatement extends BodyStmt, TBodyStatement { + final override string toString() { result = "..." } +} + +class BraceBlockBody extends BodyStmt, TBraceBlockBody { + final override string toString() { result = "..." } +} + +class BodyStmtSynth extends BodyStmt, TBodyStmtSynth { + final override string toString() { result = "..." } +} + class Then extends StmtSequence, TThen { private Ruby::Then g; @@ -64,26 +76,9 @@ class Ensure extends StmtSequence, TEnsure { // Not defined by dispatch, as it should not be exposed Ruby::AstNode getBodyStmtChild(TBodyStmt b, int i) { - exists(Ruby::Method g, Ruby::AstNode body | b = TMethod(g) and body = g.getBody() | - result = body.(Ruby::BodyStatement).getChild(i) - or - i = 0 and result = body and not body instanceof Ruby::BodyStatement - ) + result = any(Ruby::BlockBody g | b = TBraceBlockBody(g)).getChild(i) or - exists(Ruby::SingletonMethod g, Ruby::AstNode body | - b = TSingletonMethod(g) and body = g.getBody() - | - result = body.(Ruby::BodyStatement).getChild(i) - or - i = 0 and result = body and not body instanceof Ruby::BodyStatement - ) - or - exists(Ruby::Lambda g | b = TLambda(g) | - result = g.getBody().(Ruby::DoBlock).getBody().getChild(i) or - result = g.getBody().(Ruby::Block).getBody().getChild(i) - ) - or - result = any(Ruby::DoBlock g | b = TDoBlock(g)).getBody().getChild(i) + result = any(Ruby::BodyStatement g | b = TBodyStatement(g)).getChild(i) or result = any(Ruby::Program g | b = TToplevel(g)).getChild(i) and not result instanceof Ruby::BeginBlock diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Method.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Method.qll index c4dd1abbee0..fc30ec0c44f 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Method.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Method.qll @@ -18,7 +18,7 @@ class BraceBlockReal extends BraceBlock, TBraceBlockReal { toGenerated(result) = g.getParameters().getChild(n) } - final override Stmt getStmt(int i) { toGenerated(result) = g.getBody().getChild(i) } + final override BodyStmt getBody() { toGenerated(result) = g.getBody() } } /** @@ -28,8 +28,5 @@ class BraceBlockReal extends BraceBlock, TBraceBlockReal { class BraceBlockSynth extends BraceBlock, TBraceBlockSynth { final override Parameter getParameter(int n) { synthChild(this, n, result) } - final override Stmt getStmt(int i) { - i >= 0 and - synthChild(this, i + this.getNumberOfParameters(), result) - } + final override BodyStmt getBody() { synthChild(this, _, result) } } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index f2be91a63e5..072f453826c 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -19,6 +19,7 @@ newtype TSynthKind = BitwiseAndExprKind() or BitwiseOrExprKind() or BitwiseXorExprKind() or + BodyStmtKind() or BooleanLiteralKind(boolean value) { value = true or value = false } or BraceBlockKind() or CaseMatchKind() or @@ -73,6 +74,8 @@ class SynthKind extends TSynthKind { or this = BitwiseXorExprKind() and result = "BitwiseXorExprKind" or + this = BodyStmtKind() and result = "BodyStmtKind" + or this = BooleanLiteralKind(_) and result = "BooleanLiteralKind" or this = BraceBlockKind() and result = "BraceBlockKind" @@ -1475,17 +1478,24 @@ private module ForLoopDesugar { i = 0 and child = SynthChild(SimpleParameterKind()) or - exists(SimpleParameter param | param = TSimpleParameterSynth(block, 0) | + // block body + parent = block and + i = 1 and + child = SynthChild(BodyStmtKind()) + or + exists(SimpleParameter param, BodyStmt body | + param = TSimpleParameterSynth(block, 0) and body = TBodyStmtSynth(block, 1) + | parent = param and i = 0 and child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(param, 0))) or // assignment to pattern from for loop to synth parameter - parent = block and - i = 1 and + parent = body and + i = 0 and child = SynthChild(AssignExprKind()) or - parent = TAssignExprSynth(block, 1) and + parent = TAssignExprSynth(body, 0) and ( i = 0 and child = childRef(for.getPattern()) @@ -1493,11 +1503,11 @@ private module ForLoopDesugar { i = 1 and child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(param, 0))) ) + or + // rest of block body + parent = body and + child = childRef(for.getBody().(Do).getStmt(i - 1)) ) - or - // rest of block body - parent = block and - child = childRef(for.getBody().(Do).getStmt(i - 2)) ) ) ) @@ -1951,3 +1961,28 @@ private module ImplicitSuperArgsSynthesis { } } } + +private module CallableBodySynthesis { + private predicate bodySynthesis(AstNode parent, int i, Child child) { + exists(TMethodBase m, Ruby::AstNode body | + body = any(Ruby::Method g | m = TMethod(g)).getBody() + or + body = any(Ruby::SingletonMethod g | m = TSingletonMethod(g)).getBody() + | + parent = m and + not body instanceof Ruby::BodyStatement and + i = 0 and + child = SynthChild(BodyStmtKind()) + or + parent = TBodyStmtSynth(m, 0) and + i = 0 and + child = childRef(fromGenerated(body)) + ) + } + + private class CallableBodySynthesis extends Synthesis { + final override predicate child(AstNode parent, int i, Child child) { + bodySynthesis(parent, i, child) + } + } +} diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index e4bcf2537a7..fb5ce7b0145 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -1662,7 +1662,7 @@ private module ReturnNodes { * last thing that is evaluated in the body of the callable. */ class ExprReturnNode extends SourceReturnNode, ExprNode { - ExprReturnNode() { exists(Callable c | implicitReturn(c, this) = c.getAStmt()) } + ExprReturnNode() { exists(Callable c | implicitReturn(c, this) = c.getBody().getAStmt()) } override ReturnKind getKindSource() { exists(CfgScope scope | scope = this.(NodeImpl).getCfgScope() | diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll index 6f2bc8b4acc..d0823fba0a7 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll @@ -1392,7 +1392,7 @@ class StmtSequenceNode extends ExprNode { /** * A data flow node corresponding to a method, block, or lambda expression. */ -class CallableNode extends StmtSequenceNode { +class CallableNode extends ExprNode { private Callable callable; CallableNode() { this.asExpr().getExpr() = callable } diff --git a/ruby/ql/lib/codeql/ruby/experimental/Rbi.qll b/ruby/ql/lib/codeql/ruby/experimental/Rbi.qll index 008089a6251..68efe353bb0 100644 --- a/ruby/ql/lib/codeql/ruby/experimental/Rbi.qll +++ b/ruby/ql/lib/codeql/ruby/experimental/Rbi.qll @@ -83,11 +83,7 @@ module Rbi { /** * Gets the type aliased by this call. */ - RbiType getAliasedType() { - exists(ExprNodes::MethodCallCfgNode n | n.getExpr() = this | - result = n.getBlock().(ExprNodes::StmtSequenceCfgNode).getLastStmt().getExpr() - ) - } + RbiType getAliasedType() { result = this.getBlock().getBody().getLastStmt() } } /** @@ -304,7 +300,7 @@ module Rbi { private MethodSignatureCall sigCall; MethodSignatureDefiningCall() { - exists(MethodCall c | c = sigCall.getBlock().getAChild() | + exists(MethodCall c | c = sigCall.getBlock().getBody().getAChild() | // The typical pattern for the contents of a `sig` block is something // like `params().returns()` - we want to // pick up both of these calls. diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Slim.qll b/ruby/ql/lib/codeql/ruby/frameworks/Slim.qll index 3c3c3987383..7f85737bc04 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Slim.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Slim.qll @@ -18,7 +18,7 @@ module Slim { override DataFlow::Node getTemplate() { result.asExpr().getExpr() = - this.getBlock().(DataFlow::BlockNode).asCallableAstNode().getAStmt() + this.getBlock().(DataFlow::BlockNode).asCallableAstNode().getBody().getAStmt() } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/XmlParsing.qll b/ruby/ql/lib/codeql/ruby/frameworks/XmlParsing.qll index 91dc0ce5efa..b9b96fe1909 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/XmlParsing.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/XmlParsing.qll @@ -38,6 +38,7 @@ private class NokogiriXmlParserCall extends XmlParserCall::Range, DataFlow::Call .getExpr() .(MethodCall) .getBlock() + .getBody() .getAStmt() .getAChild*() .(MethodCall) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Routing.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Routing.qll index e6e453d449f..ac545481b9c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Routing.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Routing.qll @@ -98,7 +98,7 @@ module Routing { Block getBlock() { result = block } - override Stmt getAStmt() { result = block.getAStmt() } + override Stmt getAStmt() { result = block.getBody().getAStmt() } override RouteBlock getParent() { none() } @@ -128,7 +128,7 @@ module Routing { override string getAPrimaryQlClass() { result = "ConstraintsRouteBlock" } - override Stmt getAStmt() { result = block.getAStmt() } + override Stmt getAStmt() { result = block.getBody().getAStmt() } override string getPathComponent() { result = "" } @@ -156,7 +156,7 @@ module Routing { override string getAPrimaryQlClass() { result = "ScopeRouteBlock" } - override Stmt getAStmt() { result = block.getAStmt() } + override Stmt getAStmt() { result = block.getBody().getAStmt() } override string toString() { result = methodCall.toString() } @@ -216,7 +216,7 @@ module Routing { override string getAPrimaryQlClass() { result = "ResourcesRouteBlock" } - override Stmt getAStmt() { result = block.getAStmt() } + override Stmt getAStmt() { result = block.getBody().getAStmt() } /** * Gets the `resources` call that gives rise to this route block. @@ -282,7 +282,7 @@ module Routing { NamespaceRouteBlock() { this = TNamespaceRouteBlock(parent, methodCall, block) } - override Stmt getAStmt() { result = block.getAStmt() } + override Stmt getAStmt() { result = block.getBody().getAStmt() } override string getPathComponent() { result = this.getNamespace() } diff --git a/ruby/ql/lib/codeql/ruby/security/ImproperMemoizationQuery.qll b/ruby/ql/lib/codeql/ruby/security/ImproperMemoizationQuery.qll index dab75f00b9e..f46540cc33a 100644 --- a/ruby/ql/lib/codeql/ruby/security/ImproperMemoizationQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/ImproperMemoizationQuery.qll @@ -70,7 +70,7 @@ private predicate memoReturnedFromMethod(Method m, MemoStmt s) { or // If we don't have flow (e.g. due to the dataflow library not supporting instance variable flow yet), // fall back to a syntactic heuristic: does the last statement in the method mention the memoization variable? - m.getLastStmt().getAChild*().(InstanceVariableReadAccess).getVariable() = + m.getBody().getLastStmt().getAChild*().(InstanceVariableReadAccess).getVariable() = s.getVariableAccess().getVariable() } diff --git a/ruby/ql/lib/codeql/ruby/security/InsecureDependencyQuery.qll b/ruby/ql/lib/codeql/ruby/security/InsecureDependencyQuery.qll index b8298420f81..dc18981a50b 100644 --- a/ruby/ql/lib/codeql/ruby/security/InsecureDependencyQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/InsecureDependencyQuery.qll @@ -33,7 +33,7 @@ private class SourceCall extends RelevantGemCall { private class GitSourceCall extends RelevantGemCall { GitSourceCall() { this.getMethodName() = "git_source" } - override Expr getAUrlPart() { result = this.getBlock().getLastStmt() } + override Expr getAUrlPart() { result = this.getBlock().getBody().getLastStmt() } } /** From 7dcd2d6ab6c903bcc7b816a8b08eb80f332f6ac2 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 21 May 2026 12:01:45 +0200 Subject: [PATCH 093/226] Ruby: Adjust CFG to updated AST. --- ruby/ql/consistency-queries/CfgConsistency.ql | 4 +- .../internal/ControlFlowGraphImpl.qll | 132 ++++++++---------- .../ruby/controlflow/internal/Splitting.qll | 2 +- 3 files changed, 62 insertions(+), 76 deletions(-) diff --git a/ruby/ql/consistency-queries/CfgConsistency.ql b/ruby/ql/consistency-queries/CfgConsistency.ql index 297b81678ee..5af4f22fc26 100644 --- a/ruby/ql/consistency-queries/CfgConsistency.ql +++ b/ruby/ql/consistency-queries/CfgConsistency.ql @@ -11,9 +11,7 @@ import codeql.ruby.controlflow.internal.ControlFlowGraphImpl as CfgImpl query predicate nonPostOrderExpr(Expr e, string cls) { cls = e.getPrimaryQlClasses() and not exists(e.getDesugared()) and - not e instanceof BeginExpr and - not e instanceof Namespace and - not e instanceof Toplevel and + not e instanceof BodyStmt and exists(AstNode last, Completion c | CfgImpl::last(e, last, c) and last != e and diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll index f564633bb00..63198a17cf7 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll @@ -100,24 +100,26 @@ private class EndBlockScope extends CfgScopeImpl, EndBlock { } } -private class BodyStmtCallableScope extends CfgScopeImpl, AstInternal::TBodyStmt, Callable { - final override predicate entry(AstNode first) { this.(Trees::BodyStmtTree).firstInner(first) } - - final override predicate exit(AstNode last, Completion c) { - this.(Trees::BodyStmtTree).lastInner(last, c) - } -} - -private class BraceBlockScope extends CfgScopeImpl, BraceBlock { +private class CallableScope extends CfgScopeImpl, Callable { final override predicate entry(AstNode first) { - first(this.(Trees::BraceBlockTree).getBodyChild(0, _), first) + first(this.(Trees::CallableTree).getBodyChild(0), first) } final override predicate exit(AstNode last, Completion c) { - last(this.(Trees::BraceBlockTree).getLastBodyChild(), last, c) + this.getBody().(Trees::BodyStmtTree).last(last, c) or - last(this.(Trees::BraceBlockTree).getBodyChild(_, _), last, c) and - not c instanceof NormalCompletion + exists(int i | + not exists(this.getBody()) and + last(this.(Trees::CallableTree).getBodyChild(i), last, c) and + not exists(this.(Trees::CallableTree).getBodyChild(i + 1)) + ) + or + exists(AstNode child | + child = this.(Trees::CallableTree).getBodyChild(_) and + not child = this.getBody() and + last(child, last, c) and + not c instanceof NormalCompletion + ) } } @@ -159,10 +161,6 @@ module Trees { } private class BeginTree extends BodyStmtTree instanceof BeginExpr { - final override predicate first(AstNode first) { this.firstInner(first) } - - final override predicate last(AstNode last, Completion c) { this.lastInner(last, c) } - final override predicate propagatesAbnormal(AstNode child) { none() } } @@ -196,16 +194,14 @@ module Trees { private class BlockParameterTree extends NonDefaultValueParameterTree instanceof BlockParameter { } - abstract class BodyStmtTree extends StmtSequenceTree instanceof BodyStmt { + class BodyStmtTree extends StmtSequenceTree instanceof BodyStmt { /** Gets a rescue clause in this block. */ final RescueClause getARescue() { result = super.getRescue(_) } /** Gets the `ensure` clause in this block, if any. */ final StmtSequence getEnsure() { result = super.getEnsure() } - override predicate first(AstNode first) { first = this } - - predicate firstInner(AstNode first) { + override predicate first(AstNode first) { first(this.getBodyChild(0, _), first) or not exists(this.getBodyChild(_, _)) and @@ -217,7 +213,7 @@ module Trees { ) } - predicate lastInner(AstNode last, Completion c) { + override predicate last(AstNode last, Completion c) { exists(boolean ensurable | last = this.getAnEnsurePredecessor(c, ensurable) | not super.hasEnsure() or @@ -387,27 +383,28 @@ module Trees { private class BooleanLiteralTree extends LeafTree instanceof BooleanLiteral { } - class BraceBlockTree extends StmtSequenceTree instanceof BraceBlock { - final override predicate propagatesAbnormal(AstNode child) { none() } - - final override AstNode getBodyChild(int i, boolean rescuable) { - result = super.getParameter(i) and rescuable = false + class BraceBlockTree extends CallableTree instanceof BraceBlock { + final override AstNode getBodyChild(int i) { + result = super.getParameter(i) or - result = super.getLocalVariable(i - super.getNumberOfParameters()) and rescuable = false + result = super.getLocalVariable(i - super.getNumberOfParameters()) or - result = - StmtSequenceTree.super - .getBodyChild(i - super.getNumberOfParameters() - count(super.getALocalVariable()), - rescuable) + result = super.getBody() and + i = super.getNumberOfParameters() + count(super.getALocalVariable()) } + } + + class CallableTree extends PostOrderTree instanceof Callable { + final override predicate propagatesAbnormal(AstNode child) { none() } override predicate first(AstNode first) { first = this } + abstract AstNode getBodyChild(int i); + override predicate succ(AstNode pred, AstNode succ, Completion c) { - // Normal left-to-right evaluation in the body exists(int i | - last(this.getBodyChild(i, _), pred, c) and - first(this.getBodyChild(i + 1, _), succ) and + last(this.getBodyChild(i), pred, c) and + first(this.getBodyChild(i + 1), succ) and c instanceof NormalCompletion ) } @@ -1016,20 +1013,16 @@ module Trees { final override predicate succ(AstNode pred, AstNode succ, Completion c) { none() } } - private class DoBlockTree extends BodyStmtTree instanceof DoBlock { + private class DoBlockTree extends CallableTree instanceof DoBlock { /** Gets the `i`th child in the body of this block. */ - final override AstNode getBodyChild(int i, boolean rescuable) { - result = super.getParameter(i) and rescuable = false + final override AstNode getBodyChild(int i) { + result = super.getParameter(i) or - result = super.getLocalVariable(i - super.getNumberOfParameters()) and rescuable = false + result = super.getLocalVariable(i - super.getNumberOfParameters()) or - result = - BodyStmtTree.super - .getBodyChild(i - super.getNumberOfParameters() - count(super.getALocalVariable()), - rescuable) + result = super.getBody() and + i = super.getNumberOfParameters() + count(super.getALocalVariable()) } - - override predicate propagatesAbnormal(AstNode child) { none() } } private class EmptyStatementTree extends LeafTree instanceof EmptyStmt { } @@ -1073,14 +1066,12 @@ module Trees { final override AstNode getAccessNode() { result = super.getDefiningAccess() } } - private class LambdaTree extends BodyStmtTree instanceof Lambda { - final override predicate propagatesAbnormal(AstNode child) { none() } - + private class LambdaTree extends CallableTree instanceof Lambda { /** Gets the `i`th child in the body of this block. */ - final override AstNode getBodyChild(int i, boolean rescuable) { - result = super.getParameter(i) and rescuable = false + final override AstNode getBodyChild(int i) { + result = super.getParameter(i) or - result = BodyStmtTree.super.getBodyChild(i - super.getNumberOfParameters(), rescuable) + result = super.getBody() and i = super.getNumberOfParameters() } } @@ -1151,14 +1142,12 @@ module Trees { private class MethodNameTree extends LeafTree instanceof MethodName, AstInternal::TTokenMethodName { } - private class MethodTree extends BodyStmtTree instanceof Method { - final override predicate propagatesAbnormal(AstNode child) { none() } - + private class MethodTree extends CallableTree instanceof Method { /** Gets the `i`th child in the body of this block. */ - final override AstNode getBodyChild(int i, boolean rescuable) { - result = super.getParameter(i) and rescuable = false + final override AstNode getBodyChild(int i) { + result = super.getParameter(i) or - result = BodyStmtTree.super.getBodyChild(i - super.getNumberOfParameters(), rescuable) + result = super.getBody() and i = super.getNumberOfParameters() } } @@ -1183,12 +1172,12 @@ module Trees { BodyStmtTree.super.succ(pred, succ, c) or pred = this and - this.firstInner(succ) and + super.first(succ) and c instanceof SimpleCompletion } final override predicate last(AstNode last, Completion c) { - this.lastInner(last, c) + super.last(last, c) or not exists(this.getAChild(_)) and last = this and @@ -1328,7 +1317,7 @@ module Trees { private class SingletonClassTree extends BodyStmtTree instanceof SingletonClass { final override predicate first(AstNode first) { - this.firstInner(first) + super.first(first) or not exists(this.getAChild(_)) and first = this @@ -1338,7 +1327,12 @@ module Trees { BodyStmtTree.super.succ(pred, succ, c) or succ = this and - this.lastInner(pred, c) + super.last(pred, c) + } + + final override predicate last(AstNode last, Completion c) { + last = this and + c.isValidFor(this) } /** Gets the `i`th child in the body of this block. */ @@ -1351,20 +1345,18 @@ module Trees { } } - private class SingletonMethodTree extends BodyStmtTree instanceof SingletonMethod { - final override predicate propagatesAbnormal(AstNode child) { none() } - + private class SingletonMethodTree extends CallableTree instanceof SingletonMethod { /** Gets the `i`th child in the body of this block. */ - final override AstNode getBodyChild(int i, boolean rescuable) { - result = super.getParameter(i) and rescuable = false + final override AstNode getBodyChild(int i) { + result = super.getParameter(i) or - result = BodyStmtTree.super.getBodyChild(i - super.getNumberOfParameters(), rescuable) + result = super.getBody() and i = super.getNumberOfParameters() } override predicate first(AstNode first) { first(super.getObject(), first) } override predicate succ(AstNode pred, AstNode succ, Completion c) { - BodyStmtTree.super.succ(pred, succ, c) + CallableTree.super.succ(pred, succ, c) or last(super.getObject(), pred, c) and succ = this and @@ -1443,10 +1435,6 @@ module Trees { or result = BodyStmtTree.super.getBodyChild(i - count(super.getABeginBlock()), rescuable) } - - final override predicate first(AstNode first) { super.firstInner(first) } - - final override predicate last(AstNode last, Completion c) { super.lastInner(last, c) } } private class UndefStmtTree extends StandardPreOrderTree instanceof UndefStmt { diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll index 782315dc14c..737f450b4f2 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll @@ -246,7 +246,7 @@ module EnsureSplitting { private predicate exit0(AstNode pred, Trees::BodyStmtTree block, int nestLevel, Completion c) { this.appliesToPredecessor(pred) and nestLevel = block.getNestLevel() and - block.lastInner(pred, c) + block.last(pred, c) } /** From e8779295eea09c963f3726dc9fdd04c57ca3ec54 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 21 May 2026 22:27:45 +0100 Subject: [PATCH 094/226] Update test results --- .../PromptInjection.expected | 4 ---- .../CWE-1427-PromptInjection/openai_test.py | 2 +- .../CVE-2018-1281/BindToAllInterfaces.expected | 18 +++++++++++++----- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/PromptInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/PromptInjection.expected index 6acb03ce7f5..fbf4ae3fd98 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/PromptInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/PromptInjection.expected @@ -13,7 +13,6 @@ | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:18:15:18:19 | ControlFlowNode for query | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:18:15:18:19 | ControlFlowNode for query | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| openai_test.py:23:15:37:9 | ControlFlowNode for List | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:23:15:37:9 | ControlFlowNode for List | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:33:33:33:37 | ControlFlowNode for query | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:33:33:33:37 | ControlFlowNode for query | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:41:22:41:46 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:41:22:41:46 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | @@ -61,7 +60,6 @@ edges | openai_test.py:2:26:2:32 | ControlFlowNode for request | openai_test.py:13:13:13:19 | ControlFlowNode for request | provenance | | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:10 | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:10 | -| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:23:15:37:9 | ControlFlowNode for List | provenance | Sink:MaD:9 | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | provenance | | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:41:22:41:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:10 | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:63:28:63:51 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:8 | @@ -72,7 +70,6 @@ edges | openai_test.py:12:15:12:26 | ControlFlowNode for Attribute | openai_test.py:12:15:12:41 | ControlFlowNode for Attribute() | provenance | dict.get | | openai_test.py:12:15:12:41 | ControlFlowNode for Attribute() | openai_test.py:12:5:12:11 | ControlFlowNode for persona | provenance | | | openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:18:15:18:19 | ControlFlowNode for query | provenance | Sink:MaD:9 | -| openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:23:15:37:9 | ControlFlowNode for List | provenance | Sink:MaD:9 | | openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:33:33:33:37 | ControlFlowNode for query | provenance | | | openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:42:15:42:19 | ControlFlowNode for query | provenance | Sink:MaD:9 | | openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:53:33:53:37 | ControlFlowNode for query | provenance | | @@ -139,7 +136,6 @@ nodes | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | openai_test.py:18:15:18:19 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| openai_test.py:23:15:37:9 | ControlFlowNode for List | semmle.label | ControlFlowNode for List | | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | openai_test.py:33:33:33:37 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | openai_test.py:41:22:41:46 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/openai_test.py b/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/openai_test.py index 8ea014c62b4..2b25609670c 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/openai_test.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/openai_test.py @@ -34,7 +34,7 @@ async def get_input_openai(): } ] } - ] # $ Alert[py/prompt-injection] + ] ) response3 = await async_client.responses.create( diff --git a/python/ql/test/query-tests/Security/CVE-2018-1281/BindToAllInterfaces.expected b/python/ql/test/query-tests/Security/CVE-2018-1281/BindToAllInterfaces.expected index 0b96b2df650..c478fe78fd7 100644 --- a/python/ql/test/query-tests/Security/CVE-2018-1281/BindToAllInterfaces.expected +++ b/python/ql/test/query-tests/Security/CVE-2018-1281/BindToAllInterfaces.expected @@ -11,10 +11,13 @@ edges | BindToAllInterfaces_test.py:5:9:5:17 | ControlFlowNode for StringLiteral | BindToAllInterfaces_test.py:5:9:5:24 | ControlFlowNode for Tuple | provenance | Sink:MaD:63 | | BindToAllInterfaces_test.py:9:9:9:10 | ControlFlowNode for StringLiteral | BindToAllInterfaces_test.py:9:9:9:16 | ControlFlowNode for Tuple | provenance | Sink:MaD:63 | -| BindToAllInterfaces_test.py:16:1:16:10 | ControlFlowNode for ALL_LOCALS | BindToAllInterfaces_test.py:17:9:17:24 | ControlFlowNode for Tuple | provenance | Sink:MaD:63 | -| BindToAllInterfaces_test.py:16:1:16:10 | ControlFlowNode for ALL_LOCALS | BindToAllInterfaces_test.py:20:1:20:3 | ControlFlowNode for tup | provenance | | +| BindToAllInterfaces_test.py:16:1:16:10 | ControlFlowNode for ALL_LOCALS | BindToAllInterfaces_test.py:17:9:17:18 | ControlFlowNode for ALL_LOCALS | provenance | | +| BindToAllInterfaces_test.py:16:1:16:10 | ControlFlowNode for ALL_LOCALS | BindToAllInterfaces_test.py:20:8:20:17 | ControlFlowNode for ALL_LOCALS | provenance | | | BindToAllInterfaces_test.py:16:14:16:22 | ControlFlowNode for StringLiteral | BindToAllInterfaces_test.py:16:1:16:10 | ControlFlowNode for ALL_LOCALS | provenance | | -| BindToAllInterfaces_test.py:20:1:20:3 | ControlFlowNode for tup | BindToAllInterfaces_test.py:21:8:21:10 | ControlFlowNode for tup | provenance | Sink:MaD:63 | +| BindToAllInterfaces_test.py:17:9:17:18 | ControlFlowNode for ALL_LOCALS | BindToAllInterfaces_test.py:17:9:17:24 | ControlFlowNode for Tuple | provenance | Sink:MaD:63 | +| BindToAllInterfaces_test.py:20:1:20:3 | ControlFlowNode for tup [Tuple element at index 0] | BindToAllInterfaces_test.py:21:8:21:10 | ControlFlowNode for tup | provenance | Sink:MaD:63 | +| BindToAllInterfaces_test.py:20:8:20:17 | ControlFlowNode for ALL_LOCALS | BindToAllInterfaces_test.py:20:8:20:23 | ControlFlowNode for Tuple [Tuple element at index 0] | provenance | | +| BindToAllInterfaces_test.py:20:8:20:23 | ControlFlowNode for Tuple [Tuple element at index 0] | BindToAllInterfaces_test.py:20:1:20:3 | ControlFlowNode for tup [Tuple element at index 0] | provenance | | | BindToAllInterfaces_test.py:26:9:26:12 | ControlFlowNode for StringLiteral | BindToAllInterfaces_test.py:26:9:26:18 | ControlFlowNode for Tuple | provenance | Sink:MaD:63 | | BindToAllInterfaces_test.py:33:18:33:21 | ControlFlowNode for self [Return] [Attribute bind_addr] | BindToAllInterfaces_test.py:41:10:41:17 | ControlFlowNode for Server() [Attribute bind_addr] | provenance | | | BindToAllInterfaces_test.py:34:9:34:12 | [post] ControlFlowNode for self [Attribute bind_addr] | BindToAllInterfaces_test.py:33:18:33:21 | ControlFlowNode for self [Return] [Attribute bind_addr] | provenance | | @@ -25,9 +28,10 @@ edges | BindToAllInterfaces_test.py:41:1:41:6 | ControlFlowNode for server [Attribute bind_addr] | BindToAllInterfaces_test.py:42:1:42:6 | ControlFlowNode for server [Attribute bind_addr] | provenance | | | BindToAllInterfaces_test.py:41:10:41:17 | ControlFlowNode for Server() [Attribute bind_addr] | BindToAllInterfaces_test.py:41:1:41:6 | ControlFlowNode for server [Attribute bind_addr] | provenance | | | BindToAllInterfaces_test.py:42:1:42:6 | ControlFlowNode for server [Attribute bind_addr] | BindToAllInterfaces_test.py:37:15:37:18 | ControlFlowNode for self [Attribute bind_addr] | provenance | | -| BindToAllInterfaces_test.py:46:1:46:4 | ControlFlowNode for host | BindToAllInterfaces_test.py:48:9:48:18 | ControlFlowNode for Tuple | provenance | Sink:MaD:63 | +| BindToAllInterfaces_test.py:46:1:46:4 | ControlFlowNode for host | BindToAllInterfaces_test.py:48:9:48:12 | ControlFlowNode for host | provenance | | | BindToAllInterfaces_test.py:46:8:46:44 | ControlFlowNode for Attribute() | BindToAllInterfaces_test.py:46:1:46:4 | ControlFlowNode for host | provenance | | | BindToAllInterfaces_test.py:46:35:46:43 | ControlFlowNode for StringLiteral | BindToAllInterfaces_test.py:46:8:46:44 | ControlFlowNode for Attribute() | provenance | dict.get | +| BindToAllInterfaces_test.py:48:9:48:12 | ControlFlowNode for host | BindToAllInterfaces_test.py:48:9:48:18 | ControlFlowNode for Tuple | provenance | Sink:MaD:63 | | BindToAllInterfaces_test.py:53:10:53:18 | ControlFlowNode for StringLiteral | BindToAllInterfaces_test.py:53:10:53:25 | ControlFlowNode for Tuple | provenance | Sink:MaD:63 | | BindToAllInterfaces_test.py:58:10:58:18 | ControlFlowNode for StringLiteral | BindToAllInterfaces_test.py:58:10:58:25 | ControlFlowNode for Tuple | provenance | Sink:MaD:63 | nodes @@ -37,8 +41,11 @@ nodes | BindToAllInterfaces_test.py:9:9:9:16 | ControlFlowNode for Tuple | semmle.label | ControlFlowNode for Tuple | | BindToAllInterfaces_test.py:16:1:16:10 | ControlFlowNode for ALL_LOCALS | semmle.label | ControlFlowNode for ALL_LOCALS | | BindToAllInterfaces_test.py:16:14:16:22 | ControlFlowNode for StringLiteral | semmle.label | ControlFlowNode for StringLiteral | +| BindToAllInterfaces_test.py:17:9:17:18 | ControlFlowNode for ALL_LOCALS | semmle.label | ControlFlowNode for ALL_LOCALS | | BindToAllInterfaces_test.py:17:9:17:24 | ControlFlowNode for Tuple | semmle.label | ControlFlowNode for Tuple | -| BindToAllInterfaces_test.py:20:1:20:3 | ControlFlowNode for tup | semmle.label | ControlFlowNode for tup | +| BindToAllInterfaces_test.py:20:1:20:3 | ControlFlowNode for tup [Tuple element at index 0] | semmle.label | ControlFlowNode for tup [Tuple element at index 0] | +| BindToAllInterfaces_test.py:20:8:20:17 | ControlFlowNode for ALL_LOCALS | semmle.label | ControlFlowNode for ALL_LOCALS | +| BindToAllInterfaces_test.py:20:8:20:23 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] | | BindToAllInterfaces_test.py:21:8:21:10 | ControlFlowNode for tup | semmle.label | ControlFlowNode for tup | | BindToAllInterfaces_test.py:26:9:26:12 | ControlFlowNode for StringLiteral | semmle.label | ControlFlowNode for StringLiteral | | BindToAllInterfaces_test.py:26:9:26:18 | ControlFlowNode for Tuple | semmle.label | ControlFlowNode for Tuple | @@ -55,6 +62,7 @@ nodes | BindToAllInterfaces_test.py:46:1:46:4 | ControlFlowNode for host | semmle.label | ControlFlowNode for host | | BindToAllInterfaces_test.py:46:8:46:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | BindToAllInterfaces_test.py:46:35:46:43 | ControlFlowNode for StringLiteral | semmle.label | ControlFlowNode for StringLiteral | +| BindToAllInterfaces_test.py:48:9:48:12 | ControlFlowNode for host | semmle.label | ControlFlowNode for host | | BindToAllInterfaces_test.py:48:9:48:18 | ControlFlowNode for Tuple | semmle.label | ControlFlowNode for Tuple | | BindToAllInterfaces_test.py:53:10:53:18 | ControlFlowNode for StringLiteral | semmle.label | ControlFlowNode for StringLiteral | | BindToAllInterfaces_test.py:53:10:53:25 | ControlFlowNode for Tuple | semmle.label | ControlFlowNode for Tuple | From 3adb7043e8c94f4c7ca86c8b6c679ca058be1bda Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 22 May 2026 13:29:45 +0200 Subject: [PATCH 095/226] Ruby: Fix pre-existing bug. --- .../ruby/controlflow/internal/ControlFlowGraphImpl.qll | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll index 63198a17cf7..9658c51d673 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll @@ -205,12 +205,7 @@ module Trees { first(this.getBodyChild(0, _), first) or not exists(this.getBodyChild(_, _)) and - ( - first(super.getRescue(_), first) - or - not exists(super.getRescue(_)) and - first(super.getEnsure(), first) - ) + first(super.getEnsure(), first) } override predicate last(AstNode last, Completion c) { From e07f45fff4f7417411d449cc7ec8bf0b6eb7a587 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 22 May 2026 13:36:59 +0200 Subject: [PATCH 096/226] Ruby: Accept test changes. --- ruby/ql/test/library-tests/ast/Ast.expected | 761 ++++++++++-------- .../library-tests/ast/AstDesugar.expected | 277 ++++--- .../library-tests/modules/methods.expected | 95 +++ .../library-tests/modules/modules.expected | 114 +++ 4 files changed, 762 insertions(+), 485 deletions(-) diff --git a/ruby/ql/test/library-tests/ast/Ast.expected b/ruby/ql/test/library-tests/ast/Ast.expected index 0bece506bfb..c391b7f584d 100644 --- a/ruby/ql/test/library-tests/ast/Ast.expected +++ b/ruby/ql/test/library-tests/ast/Ast.expected @@ -15,18 +15,19 @@ gems/Gemfile: # 5| getArgument: [StringLiteral] "https://gems.example.com" # 5| getComponent: [StringTextComponent] https://gems.example.com # 5| getBlock: [DoBlock] do ... end -# 6| getStmt: [MethodCall] call to gem -# 6| getReceiver: [SelfVariableAccess] self -# 6| getArgument: [StringLiteral] "my_gem" -# 6| getComponent: [StringTextComponent] my_gem -# 6| getArgument: [StringLiteral] "1.0" -# 6| getComponent: [StringTextComponent] 1.0 -# 7| getStmt: [MethodCall] call to gem -# 7| getReceiver: [SelfVariableAccess] self -# 7| getArgument: [StringLiteral] "another_gem" -# 7| getComponent: [StringTextComponent] another_gem -# 7| getArgument: [StringLiteral] "3.1.4" -# 7| getComponent: [StringTextComponent] 3.1.4 +# 6| getBody: [StmtSequence] ... +# 6| getStmt: [MethodCall] call to gem +# 6| getReceiver: [SelfVariableAccess] self +# 6| getArgument: [StringLiteral] "my_gem" +# 6| getComponent: [StringTextComponent] my_gem +# 6| getArgument: [StringLiteral] "1.0" +# 6| getComponent: [StringTextComponent] 1.0 +# 7| getStmt: [MethodCall] call to gem +# 7| getReceiver: [SelfVariableAccess] self +# 7| getArgument: [StringLiteral] "another_gem" +# 7| getComponent: [StringTextComponent] another_gem +# 7| getArgument: [StringLiteral] "3.1.4" +# 7| getComponent: [StringTextComponent] 3.1.4 calls/calls.rb: # 1| [Toplevel] calls.rb # 2| getStmt: [MethodCall] call to foo @@ -45,17 +46,19 @@ calls/calls.rb: # 14| getBlock: [BraceBlock] { ... } # 14| getParameter: [SimpleParameter] x # 14| getDefiningAccess: [LocalVariableAccess] x -# 14| getStmt: [AddExpr] ... + ... -# 14| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 14| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 +# 14| getBody: [StmtSequence] ... +# 14| getStmt: [AddExpr] ... + ... +# 14| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 14| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 # 17| getStmt: [MethodCall] call to foo # 17| getReceiver: [SelfVariableAccess] self # 17| getBlock: [DoBlock] do ... end # 17| getParameter: [SimpleParameter] x # 17| getDefiningAccess: [LocalVariableAccess] x -# 18| getStmt: [AddExpr] ... + ... -# 18| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 18| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 +# 18| getBody: [StmtSequence] ... +# 18| getStmt: [AddExpr] ... + ... +# 18| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 18| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 # 22| getStmt: [MethodCall] call to bar # 22| getReceiver: [IntegerLiteral] 123 # 22| getArgument: [StringLiteral] "foo" @@ -63,15 +66,18 @@ calls/calls.rb: # 22| getBlock: [DoBlock] do ... end # 22| getParameter: [SimpleParameter] x # 22| getDefiningAccess: [LocalVariableAccess] x -# 23| getStmt: [AddExpr] ... + ... -# 23| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 23| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 +# 23| getBody: [StmtSequence] ... +# 23| getStmt: [AddExpr] ... + ... +# 23| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 23| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 # 27| getStmt: [Method] method_that_yields -# 28| getStmt: [YieldCall] yield ... +# 28| getBody: [StmtSequence] ... +# 28| getStmt: [YieldCall] yield ... # 32| getStmt: [Method] another_method_that_yields -# 33| getStmt: [YieldCall] yield ... -# 33| getArgument: [IntegerLiteral] 100 -# 33| getArgument: [IntegerLiteral] 200 +# 33| getBody: [StmtSequence] ... +# 33| getStmt: [YieldCall] yield ... +# 33| getArgument: [IntegerLiteral] 100 +# 33| getArgument: [IntegerLiteral] 200 # 43| getStmt: [MethodCall] call to foo # 43| getReceiver: [SelfVariableAccess] self # 44| getStmt: [MethodCall] call to foo @@ -148,17 +154,19 @@ calls/calls.rb: # 89| getStmt: [MethodCall] call to foo # 89| getReceiver: [SelfVariableAccess] self # 89| getBlock: [BraceBlock] { ... } -# 89| getStmt: [MethodCall] call to bar -# 89| getReceiver: [SelfVariableAccess] self -# 89| getStmt: [MethodCall] call to baz -# 89| getReceiver: [ConstantReadAccess] X +# 89| getBody: [StmtSequence] ... +# 89| getStmt: [MethodCall] call to bar +# 89| getReceiver: [SelfVariableAccess] self +# 89| getStmt: [MethodCall] call to baz +# 89| getReceiver: [ConstantReadAccess] X # 92| getStmt: [MethodCall] call to foo # 92| getReceiver: [SelfVariableAccess] self # 92| getBlock: [DoBlock] do ... end -# 93| getStmt: [MethodCall] call to bar -# 93| getReceiver: [SelfVariableAccess] self -# 94| getStmt: [MethodCall] call to baz -# 94| getReceiver: [ConstantReadAccess] X +# 93| getBody: [StmtSequence] ... +# 93| getStmt: [MethodCall] call to bar +# 93| getReceiver: [SelfVariableAccess] self +# 94| getStmt: [MethodCall] call to baz +# 94| getReceiver: [ConstantReadAccess] X # 98| getStmt: [MethodCall] call to bar # 98| getReceiver: [MethodCall] call to foo # 98| getReceiver: [SelfVariableAccess] self @@ -205,17 +213,19 @@ calls/calls.rb: # 129| getStmt: [MethodCall] call to bar # 129| getReceiver: [ConstantReadAccess] X # 133| getStmt: [Method] some_method -# 134| getStmt: [MethodCall] call to foo -# 134| getReceiver: [SelfVariableAccess] self -# 135| getStmt: [MethodCall] call to bar -# 135| getReceiver: [ConstantReadAccess] X +# 134| getBody: [StmtSequence] ... +# 134| getStmt: [MethodCall] call to foo +# 134| getReceiver: [SelfVariableAccess] self +# 135| getStmt: [MethodCall] call to bar +# 135| getReceiver: [ConstantReadAccess] X # 139| getStmt: [SingletonMethod] some_method # 139| getObject: [MethodCall] call to foo # 139| getReceiver: [SelfVariableAccess] self -# 140| getStmt: [MethodCall] call to bar -# 140| getReceiver: [SelfVariableAccess] self -# 141| getStmt: [MethodCall] call to baz -# 141| getReceiver: [ConstantReadAccess] X +# 140| getBody: [StmtSequence] ... +# 140| getStmt: [MethodCall] call to bar +# 140| getReceiver: [SelfVariableAccess] self +# 141| getStmt: [MethodCall] call to baz +# 141| getReceiver: [ConstantReadAccess] X # 145| getStmt: [Method] method_with_keyword_param # 145| getParameter: [KeywordParameter] keyword # 145| getDefiningAccess: [LocalVariableAccess] keyword @@ -500,56 +510,62 @@ calls/calls.rb: # 278| getReceiver: [ConstantReadAccess] X # 283| getStmt: [ClassDeclaration] MyClass # 284| getStmt: [Method] my_method -# 285| getStmt: [SuperCall] super call to my_method -# 286| getStmt: [SuperCall] super call to my_method -# 287| getStmt: [SuperCall] super call to my_method -# 287| getArgument: [StringLiteral] "blah" -# 287| getComponent: [StringTextComponent] blah -# 288| getStmt: [SuperCall] super call to my_method -# 288| getArgument: [IntegerLiteral] 1 -# 288| getArgument: [IntegerLiteral] 2 -# 288| getArgument: [IntegerLiteral] 3 -# 289| getStmt: [SuperCall] super call to my_method -# 289| getBlock: [BraceBlock] { ... } -# 289| getParameter: [SimpleParameter] x -# 289| getDefiningAccess: [LocalVariableAccess] x -# 289| getStmt: [AddExpr] ... + ... -# 289| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 289| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 -# 290| getStmt: [SuperCall] super call to my_method -# 290| getBlock: [DoBlock] do ... end -# 290| getParameter: [SimpleParameter] x -# 290| getDefiningAccess: [LocalVariableAccess] x -# 290| getStmt: [MulExpr] ... * ... -# 290| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 290| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 2 -# 291| getStmt: [SuperCall] super call to my_method -# 291| getArgument: [IntegerLiteral] 4 -# 291| getArgument: [IntegerLiteral] 5 -# 291| getBlock: [BraceBlock] { ... } -# 291| getParameter: [SimpleParameter] x -# 291| getDefiningAccess: [LocalVariableAccess] x -# 291| getStmt: [AddExpr] ... + ... -# 291| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 291| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 100 -# 292| getStmt: [SuperCall] super call to my_method -# 292| getArgument: [IntegerLiteral] 6 -# 292| getArgument: [IntegerLiteral] 7 -# 292| getBlock: [DoBlock] do ... end -# 292| getParameter: [SimpleParameter] x -# 292| getDefiningAccess: [LocalVariableAccess] x -# 292| getStmt: [AddExpr] ... + ... -# 292| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 292| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 200 +# 285| getBody: [StmtSequence] ... +# 285| getStmt: [SuperCall] super call to my_method +# 286| getStmt: [SuperCall] super call to my_method +# 287| getStmt: [SuperCall] super call to my_method +# 287| getArgument: [StringLiteral] "blah" +# 287| getComponent: [StringTextComponent] blah +# 288| getStmt: [SuperCall] super call to my_method +# 288| getArgument: [IntegerLiteral] 1 +# 288| getArgument: [IntegerLiteral] 2 +# 288| getArgument: [IntegerLiteral] 3 +# 289| getStmt: [SuperCall] super call to my_method +# 289| getBlock: [BraceBlock] { ... } +# 289| getParameter: [SimpleParameter] x +# 289| getDefiningAccess: [LocalVariableAccess] x +# 289| getBody: [StmtSequence] ... +# 289| getStmt: [AddExpr] ... + ... +# 289| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 289| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 +# 290| getStmt: [SuperCall] super call to my_method +# 290| getBlock: [DoBlock] do ... end +# 290| getParameter: [SimpleParameter] x +# 290| getDefiningAccess: [LocalVariableAccess] x +# 290| getBody: [StmtSequence] ... +# 290| getStmt: [MulExpr] ... * ... +# 290| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 290| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 2 +# 291| getStmt: [SuperCall] super call to my_method +# 291| getArgument: [IntegerLiteral] 4 +# 291| getArgument: [IntegerLiteral] 5 +# 291| getBlock: [BraceBlock] { ... } +# 291| getParameter: [SimpleParameter] x +# 291| getDefiningAccess: [LocalVariableAccess] x +# 291| getBody: [StmtSequence] ... +# 291| getStmt: [AddExpr] ... + ... +# 291| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 291| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 100 +# 292| getStmt: [SuperCall] super call to my_method +# 292| getArgument: [IntegerLiteral] 6 +# 292| getArgument: [IntegerLiteral] 7 +# 292| getBlock: [DoBlock] do ... end +# 292| getParameter: [SimpleParameter] x +# 292| getDefiningAccess: [LocalVariableAccess] x +# 292| getBody: [StmtSequence] ... +# 292| getStmt: [AddExpr] ... + ... +# 292| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 292| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 200 # 300| getStmt: [ClassDeclaration] AnotherClass # 301| getStmt: [Method] another_method -# 302| getStmt: [MethodCall] call to super -# 302| getReceiver: [MethodCall] call to foo -# 302| getReceiver: [SelfVariableAccess] self -# 303| getStmt: [MethodCall] call to super -# 303| getReceiver: [SelfVariableAccess] self -# 304| getStmt: [MethodCall] call to super -# 304| getReceiver: [SuperCall] super call to another_method +# 302| getBody: [StmtSequence] ... +# 302| getStmt: [MethodCall] call to super +# 302| getReceiver: [MethodCall] call to foo +# 302| getReceiver: [SelfVariableAccess] self +# 303| getStmt: [MethodCall] call to super +# 303| getReceiver: [SelfVariableAccess] self +# 304| getStmt: [MethodCall] call to super +# 304| getReceiver: [SuperCall] super call to another_method # 309| getStmt: [MethodCall] call to call # 309| getReceiver: [MethodCall] call to foo # 309| getReceiver: [SelfVariableAccess] self @@ -619,49 +635,57 @@ calls/calls.rb: # 319| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 # 319| getAnOperand/getRightOperand: [IntegerLiteral] 2 # 322| getStmt: [Method] foo -# 322| getStmt: [MethodCall] call to bar -# 322| getReceiver: [SelfVariableAccess] self +# 322| getBody: [StmtSequence] ... +# 322| getStmt: [MethodCall] call to bar +# 322| getReceiver: [SelfVariableAccess] self # 323| getStmt: [Method] foo -# 323| getStmt: [MethodCall] call to bar -# 323| getReceiver: [SelfVariableAccess] self +# 323| getBody: [StmtSequence] ... +# 323| getStmt: [MethodCall] call to bar +# 323| getReceiver: [SelfVariableAccess] self # 324| getStmt: [Method] foo +# 324| getBody: [StmtSequence] ... +# 324| getStmt: [MethodCall] call to bar +# 324| getReceiver: [SelfVariableAccess] self # 324| getParameter: [SimpleParameter] x # 324| getDefiningAccess: [LocalVariableAccess] x -# 324| getStmt: [MethodCall] call to bar -# 324| getReceiver: [SelfVariableAccess] self # 325| getStmt: [SingletonMethod] foo +# 325| getBody: [StmtSequence] ... +# 325| getStmt: [MethodCall] call to bar +# 325| getReceiver: [SelfVariableAccess] self # 325| getObject: [ConstantReadAccess] Object -# 325| getStmt: [MethodCall] call to bar -# 325| getReceiver: [SelfVariableAccess] self # 326| getStmt: [SingletonMethod] foo +# 326| getBody: [StmtSequence] ... +# 326| getStmt: [MethodCall] call to bar +# 326| getReceiver: [SelfVariableAccess] self # 326| getObject: [ConstantReadAccess] Object # 326| getParameter: [SimpleParameter] x # 326| getDefiningAccess: [LocalVariableAccess] x -# 326| getStmt: [MethodCall] call to bar -# 326| getReceiver: [SelfVariableAccess] self # 327| getStmt: [Method] foo -# 327| getStmt: [RescueModifierExpr] ... rescue ... -# 327| getBody: [MethodCall] call to bar -# 327| getReceiver: [SelfVariableAccess] self -# 327| getHandler: [ParenthesizedExpr] ( ... ) -# 327| getStmt: [MethodCall] call to print +# 327| getBody: [StmtSequence] ... +# 327| getStmt: [RescueModifierExpr] ... rescue ... +# 327| getBody: [MethodCall] call to bar # 327| getReceiver: [SelfVariableAccess] self -# 327| getArgument: [StringLiteral] "error" -# 327| getComponent: [StringTextComponent] error +# 327| getHandler: [ParenthesizedExpr] ( ... ) +# 327| getStmt: [MethodCall] call to print +# 327| getReceiver: [SelfVariableAccess] self +# 327| getArgument: [StringLiteral] "error" +# 327| getComponent: [StringTextComponent] error # 330| getStmt: [Method] foo # 330| getParameter: [ForwardParameter] ... -# 331| getStmt: [SuperCall] super call to foo -# 331| getArgument: [ForwardedArguments] ... +# 331| getBody: [StmtSequence] ... +# 331| getStmt: [SuperCall] super call to foo +# 331| getArgument: [ForwardedArguments] ... # 334| getStmt: [Method] foo # 334| getParameter: [SimpleParameter] a # 334| getDefiningAccess: [LocalVariableAccess] a # 334| getParameter: [SimpleParameter] b # 334| getDefiningAccess: [LocalVariableAccess] b # 334| getParameter: [ForwardParameter] ... -# 335| getStmt: [MethodCall] call to bar -# 335| getReceiver: [SelfVariableAccess] self -# 335| getArgument: [LocalVariableAccess] b -# 335| getArgument: [ForwardedArguments] ... +# 335| getBody: [StmtSequence] ... +# 335| getStmt: [MethodCall] call to bar +# 335| getReceiver: [SelfVariableAccess] self +# 335| getArgument: [LocalVariableAccess] b +# 335| getArgument: [ForwardedArguments] ... # 339| getStmt: [ForExpr] for ... in ... # 339| getPattern: [DestructuredLhsExpr] (..., ...) # 339| getElement: [LocalVariableAccess] x @@ -718,31 +742,35 @@ calls/calls.rb: # 350| getAnOperand/getRightOperand: [Lambda] -> { ... } # 350| getParameter: [SimpleParameter] x # 350| getDefiningAccess: [LocalVariableAccess] x -# 350| getStmt: [LocalVariableAccess] y +# 350| getBody: [StmtSequence] ... +# 350| getStmt: [LocalVariableAccess] y # 351| getStmt: [AssignExpr] ... = ... # 351| getAnOperand/getLeftOperand: [LocalVariableAccess] f # 351| getAnOperand/getRightOperand: [Lambda] -> { ... } # 351| getParameter: [SimpleParameter] x # 351| getDefiningAccess: [LocalVariableAccess] x -# 351| getStmt: [MethodCall] call to foo -# 351| getReceiver: [SelfVariableAccess] self -# 351| getArgument: [LocalVariableAccess] x +# 351| getBody: [StmtSequence] ... +# 351| getStmt: [MethodCall] call to foo +# 351| getReceiver: [SelfVariableAccess] self +# 351| getArgument: [LocalVariableAccess] x # 352| getStmt: [AssignExpr] ... = ... # 352| getAnOperand/getLeftOperand: [LocalVariableAccess] g # 352| getAnOperand/getRightOperand: [Lambda] -> { ... } # 352| getParameter: [SimpleParameter] x # 352| getDefiningAccess: [LocalVariableAccess] x -# 352| getStmt: [MethodCall] call to unknown_call -# 352| getReceiver: [SelfVariableAccess] self +# 352| getBody: [StmtSequence] ... +# 352| getStmt: [MethodCall] call to unknown_call +# 352| getReceiver: [SelfVariableAccess] self # 353| getStmt: [AssignExpr] ... = ... # 353| getAnOperand/getLeftOperand: [LocalVariableAccess] h # 353| getAnOperand/getRightOperand: [Lambda] -> { ... } # 353| getParameter: [SimpleParameter] x # 353| getDefiningAccess: [LocalVariableAccess] x -# 354| getStmt: [LocalVariableAccess] x -# 355| getStmt: [LocalVariableAccess] y -# 356| getStmt: [MethodCall] call to unknown_call -# 356| getReceiver: [SelfVariableAccess] self +# 354| getBody: [StmtSequence] ... +# 354| getStmt: [LocalVariableAccess] x +# 355| getStmt: [LocalVariableAccess] y +# 356| getStmt: [MethodCall] call to unknown_call +# 356| getReceiver: [SelfVariableAccess] self # 360| getStmt: [MethodCall] call to empty? # 360| getReceiver: [MethodCall] call to list # 360| getReceiver: [SelfVariableAccess] self @@ -760,7 +788,8 @@ calls/calls.rb: # 363| getBlock: [BraceBlock] { ... } # 363| getParameter: [SimpleParameter] x # 363| getDefiningAccess: [LocalVariableAccess] x -# 363| getStmt: [LocalVariableAccess] x +# 363| getBody: [StmtSequence] ... +# 363| getStmt: [LocalVariableAccess] x control/cases.rb: # 1| [Toplevel] cases.rb # 2| getStmt: [AssignExpr] ... = ... @@ -1094,9 +1123,10 @@ control/cases.rb: # 101| getPattern: [Lambda] -> { ... } # 101| getParameter: [SimpleParameter] x # 101| getDefiningAccess: [LocalVariableAccess] x -# 101| getStmt: [EqExpr] ... == ... -# 101| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 101| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 10 +# 101| getBody: [StmtSequence] ... +# 101| getStmt: [EqExpr] ... == ... +# 101| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 101| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 10 # 102| getBranch: [InClause] in ... then ... # 102| getPattern: [SymbolLiteral] :foo # 102| getComponent: [StringTextComponent] foo @@ -1301,15 +1331,17 @@ modules/classes.rb: # 16| getScopeExpr: [ConstantReadAccess] MyModule # 20| getStmt: [ClassDeclaration] Wibble # 21| getStmt: [Method] method_a -# 22| getStmt: [MethodCall] call to puts -# 22| getReceiver: [SelfVariableAccess] self -# 22| getArgument: [StringLiteral] "a" -# 22| getComponent: [StringTextComponent] a +# 22| getBody: [StmtSequence] ... +# 22| getStmt: [MethodCall] call to puts +# 22| getReceiver: [SelfVariableAccess] self +# 22| getArgument: [StringLiteral] "a" +# 22| getComponent: [StringTextComponent] a # 25| getStmt: [Method] method_b -# 26| getStmt: [MethodCall] call to puts -# 26| getReceiver: [SelfVariableAccess] self -# 26| getArgument: [StringLiteral] "b" -# 26| getComponent: [StringTextComponent] b +# 26| getBody: [StmtSequence] ... +# 26| getStmt: [MethodCall] call to puts +# 26| getReceiver: [SelfVariableAccess] self +# 26| getArgument: [StringLiteral] "b" +# 26| getComponent: [StringTextComponent] b # 29| getStmt: [MethodCall] call to some_method_call # 29| getReceiver: [SelfVariableAccess] self # 30| getStmt: [AssignExpr] ... = ... @@ -1324,14 +1356,16 @@ modules/classes.rb: # 41| getStmt: [SingletonClass] class << ... # 41| getValue: [LocalVariableAccess] x # 42| getStmt: [Method] length -# 43| getStmt: [MulExpr] ... * ... -# 43| getAnOperand/getLeftOperand/getReceiver: [IntegerLiteral] 100 -# 43| getAnOperand/getArgument/getRightOperand: [SuperCall] super call to length +# 43| getBody: [StmtSequence] ... +# 43| getStmt: [MulExpr] ... * ... +# 43| getAnOperand/getLeftOperand/getReceiver: [IntegerLiteral] 100 +# 43| getAnOperand/getArgument/getRightOperand: [SuperCall] super call to length # 46| getStmt: [Method] wibble -# 47| getStmt: [MethodCall] call to puts -# 47| getReceiver: [SelfVariableAccess] self -# 47| getArgument: [StringLiteral] "wibble" -# 47| getComponent: [StringTextComponent] wibble +# 47| getBody: [StmtSequence] ... +# 47| getStmt: [MethodCall] call to puts +# 47| getReceiver: [SelfVariableAccess] self +# 47| getArgument: [StringLiteral] "wibble" +# 47| getComponent: [StringTextComponent] wibble # 50| getStmt: [MethodCall] call to another_method_call # 50| getReceiver: [SelfVariableAccess] self # 51| getStmt: [AssignExpr] ... = ... @@ -1533,32 +1567,34 @@ constants/constants.rb: # 17| getAnOperand/getArgument/getRightOperand: [ConstantReadAccess] CONST_B # 17| getScopeExpr: [ConstantReadAccess] ModuleA # 19| getStmt: [Method] foo -# 20| getStmt: [AssignExpr] ... = ... -# 20| getAnOperand/getLeftOperand: [ConstantAssignment] Names -# 20| getAnOperand/getRightOperand: [ArrayLiteral] [...] -# 20| getElement: [StringLiteral] "Vera" -# 20| getComponent: [StringTextComponent] Vera -# 20| getElement: [StringLiteral] "Chuck" -# 20| getComponent: [StringTextComponent] Chuck -# 20| getElement: [StringLiteral] "Dave" -# 20| getComponent: [StringTextComponent] Dave -# 22| getStmt: [MethodCall] call to each -# 22| getReceiver: [ConstantReadAccess] Names -# 22| getBlock: [DoBlock] do ... end -# 22| getParameter: [SimpleParameter] name -# 22| getDefiningAccess: [LocalVariableAccess] name -# 23| getStmt: [MethodCall] call to puts -# 23| getReceiver: [SelfVariableAccess] self -# 23| getArgument: [StringLiteral] "#{...} #{...}" -# 23| getComponent: [StringInterpolationComponent] #{...} -# 23| getStmt: [ConstantReadAccess] GREETING -# 23| getComponent: [StringTextComponent] -# 23| getComponent: [StringInterpolationComponent] #{...} -# 23| getStmt: [LocalVariableAccess] name -# 28| getStmt: [MethodCall] call to Array -# 28| getReceiver: [SelfVariableAccess] self -# 28| getArgument: [StringLiteral] "foo" -# 28| getComponent: [StringTextComponent] foo +# 20| getBody: [StmtSequence] ... +# 20| getStmt: [AssignExpr] ... = ... +# 20| getAnOperand/getLeftOperand: [ConstantAssignment] Names +# 20| getAnOperand/getRightOperand: [ArrayLiteral] [...] +# 20| getElement: [StringLiteral] "Vera" +# 20| getComponent: [StringTextComponent] Vera +# 20| getElement: [StringLiteral] "Chuck" +# 20| getComponent: [StringTextComponent] Chuck +# 20| getElement: [StringLiteral] "Dave" +# 20| getComponent: [StringTextComponent] Dave +# 22| getStmt: [MethodCall] call to each +# 22| getReceiver: [ConstantReadAccess] Names +# 22| getBlock: [DoBlock] do ... end +# 22| getParameter: [SimpleParameter] name +# 22| getDefiningAccess: [LocalVariableAccess] name +# 23| getBody: [StmtSequence] ... +# 23| getStmt: [MethodCall] call to puts +# 23| getReceiver: [SelfVariableAccess] self +# 23| getArgument: [StringLiteral] "#{...} #{...}" +# 23| getComponent: [StringInterpolationComponent] #{...} +# 23| getStmt: [ConstantReadAccess] GREETING +# 23| getComponent: [StringTextComponent] +# 23| getComponent: [StringInterpolationComponent] #{...} +# 23| getStmt: [LocalVariableAccess] name +# 28| getStmt: [MethodCall] call to Array +# 28| getReceiver: [SelfVariableAccess] self +# 28| getArgument: [StringLiteral] "foo" +# 28| getComponent: [StringTextComponent] foo # 31| getStmt: [ClassDeclaration] ClassD # 31| getScopeExpr: [ConstantReadAccess] ModuleA # 31| getSuperclassExpr: [ConstantReadAccess] ClassA @@ -2309,14 +2345,15 @@ literals/literals.rb: # 171| getComponent: [StringTextComponent] # 171| # 174| getStmt: [Method] m -# 175| getStmt: [AssignExpr] ... = ... -# 175| getAnOperand/getLeftOperand: [LocalVariableAccess] query -# 175| getAnOperand/getRightOperand: [HereDoc] <<-BLA -# 175| getComponent: [StringTextComponent] -# 175| some text -# 176| getComponent: [StringEscapeSequenceComponent] \n -# 176| getComponent: [StringTextComponent] and some more -# 176| +# 175| getBody: [StmtSequence] ... +# 175| getStmt: [AssignExpr] ... = ... +# 175| getAnOperand/getLeftOperand: [LocalVariableAccess] query +# 175| getAnOperand/getRightOperand: [HereDoc] <<-BLA +# 175| getComponent: [StringTextComponent] +# 175| some text +# 176| getComponent: [StringEscapeSequenceComponent] \n +# 176| getComponent: [StringTextComponent] and some more +# 176| # 180| getStmt: [AssignExpr] ... = ... # 180| getAnOperand/getLeftOperand: [LocalVariableAccess] query # 180| getAnOperand/getRightOperand: [HereDoc] <<~SQUIGGLY @@ -2648,9 +2685,10 @@ modules/modules.rb: # 90| getStmt: [MethodCall] call to module_eval # 90| getReceiver: [ConstantReadAccess] Object # 90| getBlock: [BraceBlock] { ... } -# 90| getStmt: [MethodCall] call to prepend -# 90| getReceiver: [SelfVariableAccess] self -# 90| getArgument: [ConstantReadAccess] Other +# 90| getBody: [StmtSequence] ... +# 90| getStmt: [MethodCall] call to prepend +# 90| getReceiver: [SelfVariableAccess] self +# 90| getArgument: [ConstantReadAccess] Other # 91| getStmt: [ModuleDeclaration] Y # 91| getScopeExpr: [ConstantReadAccess] Foo1 # 95| getStmt: [ModuleDeclaration] IncludeTest2 @@ -2745,26 +2783,27 @@ operations/operations.rb: # 28| getStmt: [DefinedExpr] defined? ... # 28| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] foo # 29| getStmt: [Method] foo -# 29| getStmt: [ReturnStmt] return -# 29| getValue: [ArgumentList] ..., ... -# 29| getElement: [IntegerLiteral] 1 -# 29| getElement: [SplatExpr] * ... -# 29| getAnOperand/getOperand/getReceiver: [ArrayLiteral] [...] -# 29| getElement: [IntegerLiteral] 2 -# 29| getElement: [Pair] Pair -# 29| getKey: [SymbolLiteral] :a -# 29| getComponent: [StringTextComponent] a -# 29| getValue: [IntegerLiteral] 3 -# 29| getElement: [HashSplatExpr] ** ... -# 29| getAnOperand/getOperand/getReceiver: [HashLiteral] {...} -# 29| getElement: [Pair] Pair -# 29| getKey: [SymbolLiteral] :b -# 29| getComponent: [StringTextComponent] b -# 29| getValue: [IntegerLiteral] 4 -# 29| getElement: [Pair] Pair -# 29| getKey: [SymbolLiteral] :c -# 29| getComponent: [StringTextComponent] c -# 29| getValue: [IntegerLiteral] 5 +# 29| getBody: [StmtSequence] ... +# 29| getStmt: [ReturnStmt] return +# 29| getValue: [ArgumentList] ..., ... +# 29| getElement: [IntegerLiteral] 1 +# 29| getElement: [SplatExpr] * ... +# 29| getAnOperand/getOperand/getReceiver: [ArrayLiteral] [...] +# 29| getElement: [IntegerLiteral] 2 +# 29| getElement: [Pair] Pair +# 29| getKey: [SymbolLiteral] :a +# 29| getComponent: [StringTextComponent] a +# 29| getValue: [IntegerLiteral] 3 +# 29| getElement: [HashSplatExpr] ** ... +# 29| getAnOperand/getOperand/getReceiver: [HashLiteral] {...} +# 29| getElement: [Pair] Pair +# 29| getKey: [SymbolLiteral] :b +# 29| getComponent: [StringTextComponent] b +# 29| getValue: [IntegerLiteral] 4 +# 29| getElement: [Pair] Pair +# 29| getKey: [SymbolLiteral] :c +# 29| getComponent: [StringTextComponent] c +# 29| getValue: [IntegerLiteral] 5 # 32| getStmt: [AddExpr] ... + ... # 32| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] w # 32| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 234 @@ -2899,10 +2938,11 @@ operations/operations.rb: # 95| getDefiningAccess: [LocalVariableAccess] a # 95| getParameter: [SimpleParameter] b # 95| getDefiningAccess: [LocalVariableAccess] b -# 96| getStmt: [ReturnStmt] return -# 96| getValue: [LogicalAndExpr] ... && ... -# 96| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] a -# 97| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] b +# 96| getBody: [StmtSequence] ... +# 96| getStmt: [ReturnStmt] return +# 96| getValue: [LogicalAndExpr] ... && ... +# 96| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] a +# 97| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] b # 107| getStmt: [ClassDeclaration] X # 108| getStmt: [AssignExpr] ... = ... # 108| getAnOperand/getLeftOperand: [InstanceVariableAccess] @x @@ -2979,14 +3019,15 @@ params/params.rb: # 9| getDefiningAccess: [LocalVariableAccess] key # 9| getParameter: [SimpleParameter] value # 9| getDefiningAccess: [LocalVariableAccess] value -# 10| getStmt: [MethodCall] call to puts -# 10| getReceiver: [SelfVariableAccess] self -# 10| getArgument: [StringLiteral] "#{...} -> #{...}" -# 10| getComponent: [StringInterpolationComponent] #{...} -# 10| getStmt: [LocalVariableAccess] key -# 10| getComponent: [StringTextComponent] -> -# 10| getComponent: [StringInterpolationComponent] #{...} -# 10| getStmt: [LocalVariableAccess] value +# 10| getBody: [StmtSequence] ... +# 10| getStmt: [MethodCall] call to puts +# 10| getReceiver: [SelfVariableAccess] self +# 10| getArgument: [StringLiteral] "#{...} -> #{...}" +# 10| getComponent: [StringInterpolationComponent] #{...} +# 10| getStmt: [LocalVariableAccess] key +# 10| getComponent: [StringTextComponent] -> +# 10| getComponent: [StringInterpolationComponent] #{...} +# 10| getStmt: [LocalVariableAccess] value # 14| getStmt: [AssignExpr] ... = ... # 14| getAnOperand/getLeftOperand: [LocalVariableAccess] sum # 14| getAnOperand/getRightOperand: [Lambda] -> { ... } @@ -2994,9 +3035,10 @@ params/params.rb: # 14| getDefiningAccess: [LocalVariableAccess] foo # 14| getParameter: [SimpleParameter] bar # 14| getDefiningAccess: [LocalVariableAccess] bar -# 14| getStmt: [AddExpr] ... + ... -# 14| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo -# 14| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] bar +# 14| getBody: [StmtSequence] ... +# 14| getStmt: [AddExpr] ... + ... +# 14| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo +# 14| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] bar # 17| getStmt: [Method] destructured_method_param # 17| getParameter: [DestructuredParameter] (..., ...) # 17| getElement: [LocalVariableAccess] a @@ -3011,11 +3053,12 @@ params/params.rb: # 22| getParameter: [DestructuredParameter] (..., ...) # 22| getElement: [LocalVariableAccess] a # 22| getElement: [LocalVariableAccess] b -# 22| getStmt: [MethodCall] call to puts -# 22| getReceiver: [SelfVariableAccess] self -# 22| getArgument: [AddExpr] ... + ... -# 22| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] a -# 22| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] b +# 22| getBody: [StmtSequence] ... +# 22| getStmt: [MethodCall] call to puts +# 22| getReceiver: [SelfVariableAccess] self +# 22| getArgument: [AddExpr] ... + ... +# 22| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] a +# 22| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] b # 25| getStmt: [AssignExpr] ... = ... # 25| getAnOperand/getLeftOperand: [LocalVariableAccess] sum_four_values # 25| getAnOperand/getRightOperand: [Lambda] -> { ... } @@ -3025,13 +3068,14 @@ params/params.rb: # 25| getParameter: [DestructuredParameter] (..., ...) # 25| getElement: [LocalVariableAccess] third # 25| getElement: [LocalVariableAccess] fourth -# 26| getStmt: [AddExpr] ... + ... -# 26| getAnOperand/getLeftOperand/getReceiver: [AddExpr] ... + ... +# 26| getBody: [StmtSequence] ... +# 26| getStmt: [AddExpr] ... + ... # 26| getAnOperand/getLeftOperand/getReceiver: [AddExpr] ... + ... -# 26| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] first -# 26| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] second -# 26| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] third -# 26| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] fourth +# 26| getAnOperand/getLeftOperand/getReceiver: [AddExpr] ... + ... +# 26| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] first +# 26| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] second +# 26| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] third +# 26| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] fourth # 30| getStmt: [Method] method_with_splat # 30| getParameter: [SimpleParameter] wibble # 30| getDefiningAccess: [LocalVariableAccess] wibble @@ -3065,26 +3109,28 @@ params/params.rb: # 41| getParameter: [KeywordParameter] bar # 41| getDefiningAccess: [LocalVariableAccess] bar # 41| getDefaultValue: [IntegerLiteral] 7 -# 42| getStmt: [AddExpr] ... + ... -# 42| getAnOperand/getLeftOperand/getReceiver: [AddExpr] ... + ... -# 42| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 42| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] foo -# 42| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] bar +# 42| getBody: [StmtSequence] ... +# 42| getStmt: [AddExpr] ... + ... +# 42| getAnOperand/getLeftOperand/getReceiver: [AddExpr] ... + ... +# 42| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 42| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] foo +# 42| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] bar # 46| getStmt: [Method] use_block_with_keyword # 46| getParameter: [BlockParameter] &block # 46| getDefiningAccess: [LocalVariableAccess] block -# 47| getStmt: [MethodCall] call to puts -# 47| getReceiver: [SelfVariableAccess] self -# 47| getArgument: [MethodCall] call to call -# 47| getReceiver: [LocalVariableAccess] block -# 47| getArgument: [Pair] Pair -# 47| getKey: [SymbolLiteral] :bar -# 47| getComponent: [StringTextComponent] bar -# 47| getValue: [IntegerLiteral] 2 -# 47| getArgument: [Pair] Pair -# 47| getKey: [SymbolLiteral] :foo -# 47| getComponent: [StringTextComponent] foo -# 47| getValue: [IntegerLiteral] 3 +# 47| getBody: [StmtSequence] ... +# 47| getStmt: [MethodCall] call to puts +# 47| getReceiver: [SelfVariableAccess] self +# 47| getArgument: [MethodCall] call to call +# 47| getReceiver: [LocalVariableAccess] block +# 47| getArgument: [Pair] Pair +# 47| getKey: [SymbolLiteral] :bar +# 47| getComponent: [StringTextComponent] bar +# 47| getValue: [IntegerLiteral] 2 +# 47| getArgument: [Pair] Pair +# 47| getKey: [SymbolLiteral] :foo +# 47| getComponent: [StringTextComponent] foo +# 47| getValue: [IntegerLiteral] 3 # 49| getStmt: [MethodCall] call to use_block_with_keyword # 49| getReceiver: [SelfVariableAccess] self # 49| getBlock: [DoBlock] do ... end @@ -3093,9 +3139,10 @@ params/params.rb: # 49| getParameter: [KeywordParameter] yy # 49| getDefiningAccess: [LocalVariableAccess] yy # 49| getDefaultValue: [IntegerLiteral] 100 -# 50| getStmt: [AddExpr] ... + ... -# 50| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] xx -# 50| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] yy +# 50| getBody: [StmtSequence] ... +# 50| getStmt: [AddExpr] ... + ... +# 50| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] xx +# 50| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] yy # 53| getStmt: [AssignExpr] ... = ... # 53| getAnOperand/getLeftOperand: [LocalVariableAccess] lambda_with_keyword_params # 53| getAnOperand/getRightOperand: [Lambda] -> { ... } @@ -3106,11 +3153,12 @@ params/params.rb: # 53| getParameter: [KeywordParameter] z # 53| getDefiningAccess: [LocalVariableAccess] z # 53| getDefaultValue: [IntegerLiteral] 3 -# 54| getStmt: [AddExpr] ... + ... -# 54| getAnOperand/getLeftOperand/getReceiver: [AddExpr] ... + ... -# 54| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 54| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] y -# 54| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] z +# 54| getBody: [StmtSequence] ... +# 54| getStmt: [AddExpr] ... + ... +# 54| getAnOperand/getLeftOperand/getReceiver: [AddExpr] ... + ... +# 54| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 54| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] y +# 54| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] z # 58| getStmt: [Method] method_with_optional_params # 58| getParameter: [SimpleParameter] val1 # 58| getDefiningAccess: [LocalVariableAccess] val1 @@ -3123,10 +3171,11 @@ params/params.rb: # 62| getStmt: [Method] use_block_with_optional # 62| getParameter: [BlockParameter] &block # 62| getDefiningAccess: [LocalVariableAccess] block -# 63| getStmt: [MethodCall] call to call -# 63| getReceiver: [LocalVariableAccess] block -# 63| getArgument: [StringLiteral] "Zeus" -# 63| getComponent: [StringTextComponent] Zeus +# 63| getBody: [StmtSequence] ... +# 63| getStmt: [MethodCall] call to call +# 63| getReceiver: [LocalVariableAccess] block +# 63| getArgument: [StringLiteral] "Zeus" +# 63| getComponent: [StringTextComponent] Zeus # 65| getStmt: [MethodCall] call to use_block_with_optional # 65| getReceiver: [SelfVariableAccess] self # 65| getBlock: [DoBlock] do ... end @@ -3135,15 +3184,16 @@ params/params.rb: # 65| getParameter: [OptionalParameter] age # 65| getDefiningAccess: [LocalVariableAccess] age # 65| getDefaultValue: [IntegerLiteral] 99 -# 66| getStmt: [MethodCall] call to puts -# 66| getReceiver: [SelfVariableAccess] self -# 66| getArgument: [StringLiteral] "#{...} is #{...} years old" -# 66| getComponent: [StringInterpolationComponent] #{...} -# 66| getStmt: [LocalVariableAccess] name -# 66| getComponent: [StringTextComponent] is -# 66| getComponent: [StringInterpolationComponent] #{...} -# 66| getStmt: [LocalVariableAccess] age -# 66| getComponent: [StringTextComponent] years old +# 66| getBody: [StmtSequence] ... +# 66| getStmt: [MethodCall] call to puts +# 66| getReceiver: [SelfVariableAccess] self +# 66| getArgument: [StringLiteral] "#{...} is #{...} years old" +# 66| getComponent: [StringInterpolationComponent] #{...} +# 66| getStmt: [LocalVariableAccess] name +# 66| getComponent: [StringTextComponent] is +# 66| getComponent: [StringInterpolationComponent] #{...} +# 66| getStmt: [LocalVariableAccess] age +# 66| getComponent: [StringTextComponent] years old # 70| getStmt: [AssignExpr] ... = ... # 70| getAnOperand/getLeftOperand: [LocalVariableAccess] lambda_with_optional_params # 70| getAnOperand/getRightOperand: [Lambda] -> { ... } @@ -3155,11 +3205,12 @@ params/params.rb: # 70| getParameter: [OptionalParameter] c # 70| getDefiningAccess: [LocalVariableAccess] c # 70| getDefaultValue: [IntegerLiteral] 20 -# 70| getStmt: [AddExpr] ... + ... -# 70| getAnOperand/getLeftOperand/getReceiver: [AddExpr] ... + ... -# 70| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] a -# 70| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] b -# 70| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] c +# 70| getBody: [StmtSequence] ... +# 70| getStmt: [AddExpr] ... + ... +# 70| getAnOperand/getLeftOperand/getReceiver: [AddExpr] ... + ... +# 70| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] a +# 70| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] b +# 70| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] c # 73| getStmt: [Method] method_with_nil_splat # 73| getParameter: [SimpleParameter] wibble # 73| getDefiningAccess: [LocalVariableAccess] wibble @@ -3175,14 +3226,15 @@ params/params.rb: # 81| getDefiningAccess: [LocalVariableAccess] array # 81| getParameter: [BlockParameter] & # 81| getDefiningAccess: [LocalVariableAccess] __synth__0 -# 82| getStmt: [MethodCall] call to proc -# 82| getReceiver: [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 +# 82| getBody: [StmtSequence] ... +# 82| getStmt: [MethodCall] call to proc +# 82| getReceiver: [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 # 86| getStmt: [MethodCall] call to run_block # 86| getReceiver: [SelfVariableAccess] self # 86| getBlock: [BraceBlock] { ... } @@ -3190,27 +3242,30 @@ params/params.rb: # 86| getDefiningAccess: [LocalVariableAccess] x # 86| getLocalVariable: [LocalVariableAccess] y # 86| getLocalVariable: [LocalVariableAccess] z -# 86| getStmt: [MethodCall] call to puts -# 86| getReceiver: [SelfVariableAccess] self -# 86| getArgument: [LocalVariableAccess] x +# 86| getBody: [StmtSequence] ... +# 86| getStmt: [MethodCall] call to puts +# 86| getReceiver: [SelfVariableAccess] self +# 86| getArgument: [LocalVariableAccess] x # 89| getStmt: [Method] anonymous_splat_parameter # 89| getParameter: [SimpleParameter] array # 89| getDefiningAccess: [LocalVariableAccess] array # 89| getParameter: [SplatParameter] * # 89| getDefiningAccess: [LocalVariableAccess] __synth__0 -# 90| getStmt: [MethodCall] call to concat -# 90| getReceiver: [LocalVariableAccess] array -# 90| getArgument: [SplatExpr] * ... -# 90| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0 +# 90| getBody: [StmtSequence] ... +# 90| getStmt: [MethodCall] call to concat +# 90| getReceiver: [LocalVariableAccess] array +# 90| getArgument: [SplatExpr] * ... +# 90| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0 # 94| getStmt: [Method] anonymous_hash_splat_parameter # 94| getParameter: [SimpleParameter] hash # 94| getDefiningAccess: [LocalVariableAccess] hash # 94| getParameter: [HashSplatParameter] ** # 94| getDefiningAccess: [LocalVariableAccess] __synth__0 -# 95| getStmt: [MethodCall] call to merge -# 95| getReceiver: [LocalVariableAccess] hash -# 95| getArgument: [HashSplatExpr] ** ... -# 95| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0 +# 95| getBody: [StmtSequence] ... +# 95| getStmt: [MethodCall] call to merge +# 95| getReceiver: [LocalVariableAccess] hash +# 95| getArgument: [HashSplatExpr] ** ... +# 95| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0 # 98| getStmt: [ClassDeclaration] Sup # 99| getStmt: [Method] m # 99| getParameter: [SimpleParameter] x @@ -3221,16 +3276,17 @@ params/params.rb: # 99| getDefiningAccess: [LocalVariableAccess] k # 99| getParameter: [HashSplatParameter] **kwargs # 99| getDefiningAccess: [LocalVariableAccess] kwargs -# 100| getStmt: [MethodCall] call to print -# 100| getReceiver: [SelfVariableAccess] self -# 100| getArgument: [AddExpr] ... + ... -# 100| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x -# 100| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 -# 101| getStmt: [MethodCall] call to print -# 101| getReceiver: [SelfVariableAccess] self -# 101| getArgument: [AddExpr] ... + ... -# 101| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] k -# 101| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 +# 100| getBody: [StmtSequence] ... +# 100| getStmt: [MethodCall] call to print +# 100| getReceiver: [SelfVariableAccess] self +# 100| getArgument: [AddExpr] ... + ... +# 100| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] x +# 100| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 +# 101| getStmt: [MethodCall] call to print +# 101| getReceiver: [SelfVariableAccess] self +# 101| getArgument: [AddExpr] ... + ... +# 101| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] k +# 101| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 # 105| getStmt: [ClassDeclaration] Sub # 105| getSuperclassExpr: [ConstantReadAccess] Sup # 106| getStmt: [Method] m @@ -3242,15 +3298,16 @@ params/params.rb: # 106| getDefiningAccess: [LocalVariableAccess] k # 106| getParameter: [HashSplatParameter] **kwargs # 106| getDefiningAccess: [LocalVariableAccess] kwargs -# 107| getStmt: [SuperCall] super call to m -# 107| getArgument: [LocalVariableAccess] y -# 107| getArgument: [SplatExpr] * ... -# 107| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] rest -# 107| getArgument: [Pair] Pair -# 107| getKey: [SymbolLiteral] k -# 107| getValue: [LocalVariableAccess] k -# 107| getArgument: [HashSplatExpr] ** ... -# 107| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] kwargs +# 107| getBody: [StmtSequence] ... +# 107| getStmt: [SuperCall] super call to m +# 107| getArgument: [LocalVariableAccess] y +# 107| getArgument: [SplatExpr] * ... +# 107| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] rest +# 107| getArgument: [Pair] Pair +# 107| getKey: [SymbolLiteral] k +# 107| getValue: [LocalVariableAccess] k +# 107| getArgument: [HashSplatExpr] ** ... +# 107| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] kwargs # 111| getStmt: [MethodCall] call to m # 111| getReceiver: [MethodCall] call to new # 111| getReceiver: [ConstantReadAccess] Sub @@ -3288,57 +3345,59 @@ gems/test.gemspec: # 1| getBlock: [DoBlock] do ... end # 1| getParameter: [SimpleParameter] s # 1| getDefiningAccess: [LocalVariableAccess] s -# 2| getStmt: [AssignExpr] ... = ... -# 2| getAnOperand/getLeftOperand: [MethodCall] call to name -# 2| getReceiver: [LocalVariableAccess] s -# 2| getAnOperand/getRightOperand: [StringLiteral] "test" -# 2| getComponent: [StringTextComponent] test -# 3| getStmt: [AssignExpr] ... = ... -# 3| getAnOperand/getLeftOperand: [MethodCall] call to version -# 3| getReceiver: [LocalVariableAccess] s -# 3| getAnOperand/getRightOperand: [StringLiteral] "0.0.0" -# 3| getComponent: [StringTextComponent] 0.0.0 -# 4| getStmt: [AssignExpr] ... = ... -# 4| getAnOperand/getLeftOperand: [MethodCall] call to summary -# 4| getReceiver: [LocalVariableAccess] s -# 4| getAnOperand/getRightOperand: [StringLiteral] "foo!" -# 4| getComponent: [StringTextComponent] foo! -# 5| getStmt: [AssignExpr] ... = ... -# 5| getAnOperand/getLeftOperand: [MethodCall] call to description -# 5| getReceiver: [LocalVariableAccess] s -# 5| getAnOperand/getRightOperand: [StringLiteral] "A test" -# 5| getComponent: [StringTextComponent] A test -# 6| getStmt: [AssignExpr] ... = ... -# 6| getAnOperand/getLeftOperand: [MethodCall] call to authors -# 6| getReceiver: [LocalVariableAccess] s -# 6| getAnOperand/getRightOperand: [ArrayLiteral] [...] -# 6| getElement: [StringLiteral] "Mona Lisa" -# 6| getComponent: [StringTextComponent] Mona Lisa -# 7| getStmt: [AssignExpr] ... = ... -# 7| getAnOperand/getLeftOperand: [MethodCall] call to email -# 7| getReceiver: [LocalVariableAccess] s -# 7| getAnOperand/getRightOperand: [StringLiteral] "mona@example.com" -# 7| getComponent: [StringTextComponent] mona@example.com -# 8| getStmt: [AssignExpr] ... = ... -# 8| getAnOperand/getLeftOperand: [MethodCall] call to files -# 8| getReceiver: [LocalVariableAccess] s -# 8| getAnOperand/getRightOperand: [ArrayLiteral] [...] -# 8| getElement: [StringLiteral] "lib/test.rb" -# 8| getComponent: [StringTextComponent] lib/test.rb -# 9| getStmt: [AssignExpr] ... = ... -# 9| getAnOperand/getLeftOperand: [MethodCall] call to homepage -# 9| getReceiver: [LocalVariableAccess] s -# 9| getAnOperand/getRightOperand: [StringLiteral] "https://github.com/github/cod..." -# 9| getComponent: [StringTextComponent] https://github.com/github/codeql-ruby +# 2| getBody: [StmtSequence] ... +# 2| getStmt: [AssignExpr] ... = ... +# 2| getAnOperand/getLeftOperand: [MethodCall] call to name +# 2| getReceiver: [LocalVariableAccess] s +# 2| getAnOperand/getRightOperand: [StringLiteral] "test" +# 2| getComponent: [StringTextComponent] test +# 3| getStmt: [AssignExpr] ... = ... +# 3| getAnOperand/getLeftOperand: [MethodCall] call to version +# 3| getReceiver: [LocalVariableAccess] s +# 3| getAnOperand/getRightOperand: [StringLiteral] "0.0.0" +# 3| getComponent: [StringTextComponent] 0.0.0 +# 4| getStmt: [AssignExpr] ... = ... +# 4| getAnOperand/getLeftOperand: [MethodCall] call to summary +# 4| getReceiver: [LocalVariableAccess] s +# 4| getAnOperand/getRightOperand: [StringLiteral] "foo!" +# 4| getComponent: [StringTextComponent] foo! +# 5| getStmt: [AssignExpr] ... = ... +# 5| getAnOperand/getLeftOperand: [MethodCall] call to description +# 5| getReceiver: [LocalVariableAccess] s +# 5| getAnOperand/getRightOperand: [StringLiteral] "A test" +# 5| getComponent: [StringTextComponent] A test +# 6| getStmt: [AssignExpr] ... = ... +# 6| getAnOperand/getLeftOperand: [MethodCall] call to authors +# 6| getReceiver: [LocalVariableAccess] s +# 6| getAnOperand/getRightOperand: [ArrayLiteral] [...] +# 6| getElement: [StringLiteral] "Mona Lisa" +# 6| getComponent: [StringTextComponent] Mona Lisa +# 7| getStmt: [AssignExpr] ... = ... +# 7| getAnOperand/getLeftOperand: [MethodCall] call to email +# 7| getReceiver: [LocalVariableAccess] s +# 7| getAnOperand/getRightOperand: [StringLiteral] "mona@example.com" +# 7| getComponent: [StringTextComponent] mona@example.com +# 8| getStmt: [AssignExpr] ... = ... +# 8| getAnOperand/getLeftOperand: [MethodCall] call to files +# 8| getReceiver: [LocalVariableAccess] s +# 8| getAnOperand/getRightOperand: [ArrayLiteral] [...] +# 8| getElement: [StringLiteral] "lib/test.rb" +# 8| getComponent: [StringTextComponent] lib/test.rb +# 9| getStmt: [AssignExpr] ... = ... +# 9| getAnOperand/getLeftOperand: [MethodCall] call to homepage +# 9| getReceiver: [LocalVariableAccess] s +# 9| getAnOperand/getRightOperand: [StringLiteral] "https://github.com/github/cod..." +# 9| getComponent: [StringTextComponent] https://github.com/github/codeql-ruby gems/lib/test.rb: # 1| [Toplevel] test.rb # 1| getStmt: [ClassDeclaration] Foo # 2| getStmt: [SingletonMethod] greet # 2| getObject: [SelfVariableAccess] self -# 3| getStmt: [MethodCall] call to puts -# 3| getReceiver: [SelfVariableAccess] self -# 3| getArgument: [StringLiteral] "Hello" -# 3| getComponent: [StringTextComponent] Hello +# 3| getBody: [StmtSequence] ... +# 3| getStmt: [MethodCall] call to puts +# 3| getReceiver: [SelfVariableAccess] self +# 3| getArgument: [StringLiteral] "Hello" +# 3| getComponent: [StringTextComponent] Hello modules/toplevel.rb: # 1| [Toplevel] toplevel.rb # 1| getStmt: [MethodCall] call to puts diff --git a/ruby/ql/test/library-tests/ast/AstDesugar.expected b/ruby/ql/test/library-tests/ast/AstDesugar.expected index 29443860749..40594888db1 100644 --- a/ruby/ql/test/library-tests/ast/AstDesugar.expected +++ b/ruby/ql/test/library-tests/ast/AstDesugar.expected @@ -38,11 +38,12 @@ calls/calls.rb: # 223| getBlock: [BraceBlock] { ... } # 223| getParameter: [SimpleParameter] __synth__0__1 # 223| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 223| getStmt: [AssignExpr] ... = ... -# 223| getAnOperand/getLeftOperand: [LocalVariableAccess] x -# 223| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 224| getStmt: [MethodCall] call to baz -# 224| getReceiver: [SelfVariableAccess] self +# 223| getBody: [StmtSequence] ... +# 223| getStmt: [AssignExpr] ... = ... +# 223| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 223| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 224| getStmt: [MethodCall] call to baz +# 224| getReceiver: [SelfVariableAccess] self # 226| [ForExpr] for ... in ... # 226| getDesugared: [StmtSequence] ... # 226| getStmt: [IfExpr] if ... @@ -58,11 +59,12 @@ calls/calls.rb: # 226| getBlock: [BraceBlock] { ... } # 226| getParameter: [SimpleParameter] __synth__0__1 # 226| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 226| getStmt: [AssignExpr] ... = ... -# 226| getAnOperand/getLeftOperand: [LocalVariableAccess] x -# 226| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 227| getStmt: [MethodCall] call to baz -# 227| getReceiver: [ConstantReadAccess] X +# 226| getBody: [StmtSequence] ... +# 226| getStmt: [AssignExpr] ... = ... +# 226| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 226| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 227| getStmt: [MethodCall] call to baz +# 227| getReceiver: [ConstantReadAccess] X # 246| [HashLiteral] {...} # 246| getDesugared: [MethodCall] call to [] # 246| getReceiver: [ConstantReadAccess] Hash @@ -302,33 +304,34 @@ calls/calls.rb: # 339| getBlock: [BraceBlock] { ... } # 339| getParameter: [SimpleParameter] __synth__0__1 # 339| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 339| getStmt: [AssignExpr] ... = ... -# 339| getDesugared: [StmtSequence] ... -# 339| getStmt: [AssignExpr] ... = ... -# 339| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3__1 -# 339| getAnOperand/getRightOperand: [SplatExpr] * ... -# 339| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 -# 339| getStmt: [AssignExpr] ... = ... -# 339| getAnOperand/getLeftOperand: [LocalVariableAccess] x -# 339| getAnOperand/getRightOperand: [MethodCall] call to [] -# 339| getReceiver: [LocalVariableAccess] __synth__3__1 -# 339| getArgument: [IntegerLiteral] 0 -# 339| getStmt: [AssignExpr] ... = ... -# 339| getAnOperand/getLeftOperand: [LocalVariableAccess] y -# 339| getAnOperand/getRightOperand: [MethodCall] call to [] -# 339| getReceiver: [LocalVariableAccess] __synth__3__1 -# 339| getArgument: [IntegerLiteral] 1 -# 339| getStmt: [AssignExpr] ... = ... -# 339| getAnOperand/getLeftOperand: [LocalVariableAccess] z -# 339| getAnOperand/getRightOperand: [MethodCall] call to [] -# 339| getReceiver: [LocalVariableAccess] __synth__3__1 -# 339| getArgument: [IntegerLiteral] 2 -# 339| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) -# 340| getStmt: [MethodCall] call to foo -# 340| getReceiver: [SelfVariableAccess] self -# 340| getArgument: [LocalVariableAccess] x -# 340| getArgument: [LocalVariableAccess] y -# 340| getArgument: [LocalVariableAccess] z +# 339| getBody: [StmtSequence] ... +# 339| getStmt: [AssignExpr] ... = ... +# 339| getDesugared: [StmtSequence] ... +# 339| getStmt: [AssignExpr] ... = ... +# 339| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3__1 +# 339| getAnOperand/getRightOperand: [SplatExpr] * ... +# 339| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 +# 339| getStmt: [AssignExpr] ... = ... +# 339| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 339| getAnOperand/getRightOperand: [MethodCall] call to [] +# 339| getReceiver: [LocalVariableAccess] __synth__3__1 +# 339| getArgument: [IntegerLiteral] 0 +# 339| getStmt: [AssignExpr] ... = ... +# 339| getAnOperand/getLeftOperand: [LocalVariableAccess] y +# 339| getAnOperand/getRightOperand: [MethodCall] call to [] +# 339| getReceiver: [LocalVariableAccess] __synth__3__1 +# 339| getArgument: [IntegerLiteral] 1 +# 339| getStmt: [AssignExpr] ... = ... +# 339| getAnOperand/getLeftOperand: [LocalVariableAccess] z +# 339| getAnOperand/getRightOperand: [MethodCall] call to [] +# 339| getReceiver: [LocalVariableAccess] __synth__3__1 +# 339| getArgument: [IntegerLiteral] 2 +# 339| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) +# 340| getStmt: [MethodCall] call to foo +# 340| getReceiver: [SelfVariableAccess] self +# 340| getArgument: [LocalVariableAccess] x +# 340| getArgument: [LocalVariableAccess] y +# 340| getArgument: [LocalVariableAccess] z # 361| [MethodCall] call to empty? # 361| getDesugared: [StmtSequence] ... # 361| getStmt: [AssignExpr] ... = ... @@ -360,7 +363,8 @@ calls/calls.rb: # 363| getBlock: [BraceBlock] { ... } # 363| getParameter: [SimpleParameter] x # 363| getDefiningAccess: [LocalVariableAccess] x -# 363| getStmt: [LocalVariableAccess] x +# 363| getBody: [StmtSequence] ... +# 363| getStmt: [LocalVariableAccess] x control/cases.rb: # 90| [ArrayLiteral] %w(...) # 90| getDesugared: [MethodCall] call to [] @@ -647,18 +651,19 @@ control/loops.rb: # 9| getBlock: [BraceBlock] { ... } # 9| getParameter: [SimpleParameter] __synth__0__1 # 9| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 9| getStmt: [AssignExpr] ... = ... -# 9| getAnOperand/getLeftOperand: [LocalVariableAccess] n -# 9| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 10| getStmt: [AssignAddExpr] ... += ... -# 10| getDesugared: [AssignExpr] ... = ... -# 10| getAnOperand/getLeftOperand: [LocalVariableAccess] sum -# 10| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 10| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum -# 10| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n -# 11| getStmt: [AssignExpr] ... = ... -# 11| getAnOperand/getLeftOperand: [LocalVariableAccess] foo -# 11| getAnOperand/getRightOperand: [LocalVariableAccess] n +# 9| getBody: [StmtSequence] ... +# 9| getStmt: [AssignExpr] ... = ... +# 9| getAnOperand/getLeftOperand: [LocalVariableAccess] n +# 9| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 10| getStmt: [AssignAddExpr] ... += ... +# 10| getDesugared: [AssignExpr] ... = ... +# 10| getAnOperand/getLeftOperand: [LocalVariableAccess] sum +# 10| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 10| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum +# 10| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n +# 11| getStmt: [AssignExpr] ... = ... +# 11| getAnOperand/getLeftOperand: [LocalVariableAccess] foo +# 11| getAnOperand/getRightOperand: [LocalVariableAccess] n # 16| [ForExpr] for ... in ... # 16| getDesugared: [StmtSequence] ... # 16| getStmt: [IfExpr] if ... @@ -675,21 +680,22 @@ control/loops.rb: # 16| getBlock: [BraceBlock] { ... } # 16| getParameter: [SimpleParameter] __synth__0__1 # 16| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 16| getStmt: [AssignExpr] ... = ... -# 16| getAnOperand/getLeftOperand: [LocalVariableAccess] n -# 16| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 17| getStmt: [AssignAddExpr] ... += ... -# 17| getDesugared: [AssignExpr] ... = ... -# 17| getAnOperand/getLeftOperand: [LocalVariableAccess] sum -# 17| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 17| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum -# 17| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n -# 18| getStmt: [AssignSubExpr] ... -= ... -# 18| getDesugared: [AssignExpr] ... = ... -# 18| getAnOperand/getLeftOperand: [LocalVariableAccess] foo -# 18| getAnOperand/getRightOperand: [SubExpr] ... - ... -# 18| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo -# 18| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n +# 16| getBody: [StmtSequence] ... +# 16| getStmt: [AssignExpr] ... = ... +# 16| getAnOperand/getLeftOperand: [LocalVariableAccess] n +# 16| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 17| getStmt: [AssignAddExpr] ... += ... +# 17| getDesugared: [AssignExpr] ... = ... +# 17| getAnOperand/getLeftOperand: [LocalVariableAccess] sum +# 17| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 17| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum +# 17| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n +# 18| getStmt: [AssignSubExpr] ... -= ... +# 18| getDesugared: [AssignExpr] ... = ... +# 18| getAnOperand/getLeftOperand: [LocalVariableAccess] foo +# 18| getAnOperand/getRightOperand: [SubExpr] ... - ... +# 18| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo +# 18| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n # 22| [ForExpr] for ... in ... # 22| getDesugared: [StmtSequence] ... # 22| getStmt: [IfExpr] if ... @@ -721,35 +727,36 @@ control/loops.rb: # 22| getBlock: [BraceBlock] { ... } # 22| getParameter: [SimpleParameter] __synth__0__1 # 22| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 22| getStmt: [AssignExpr] ... = ... -# 22| getDesugared: [StmtSequence] ... -# 22| getStmt: [AssignExpr] ... = ... -# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 -# 22| getAnOperand/getRightOperand: [SplatExpr] * ... -# 22| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 -# 22| getStmt: [AssignExpr] ... = ... -# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] key -# 22| getAnOperand/getRightOperand: [MethodCall] call to [] -# 22| getReceiver: [LocalVariableAccess] __synth__2__1 -# 22| getArgument: [IntegerLiteral] 0 -# 22| getStmt: [AssignExpr] ... = ... -# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] value -# 22| getAnOperand/getRightOperand: [MethodCall] call to [] -# 22| getReceiver: [LocalVariableAccess] __synth__2__1 -# 22| getArgument: [IntegerLiteral] 1 -# 22| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) -# 23| getStmt: [AssignAddExpr] ... += ... -# 23| getDesugared: [AssignExpr] ... = ... -# 23| getAnOperand/getLeftOperand: [LocalVariableAccess] sum -# 23| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 23| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum -# 23| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value -# 24| getStmt: [AssignMulExpr] ... *= ... -# 24| getDesugared: [AssignExpr] ... = ... -# 24| getAnOperand/getLeftOperand: [LocalVariableAccess] foo -# 24| getAnOperand/getRightOperand: [MulExpr] ... * ... -# 24| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo -# 24| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value +# 22| getBody: [StmtSequence] ... +# 22| getStmt: [AssignExpr] ... = ... +# 22| getDesugared: [StmtSequence] ... +# 22| getStmt: [AssignExpr] ... = ... +# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 +# 22| getAnOperand/getRightOperand: [SplatExpr] * ... +# 22| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 +# 22| getStmt: [AssignExpr] ... = ... +# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] key +# 22| getAnOperand/getRightOperand: [MethodCall] call to [] +# 22| getReceiver: [LocalVariableAccess] __synth__2__1 +# 22| getArgument: [IntegerLiteral] 0 +# 22| getStmt: [AssignExpr] ... = ... +# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] value +# 22| getAnOperand/getRightOperand: [MethodCall] call to [] +# 22| getReceiver: [LocalVariableAccess] __synth__2__1 +# 22| getArgument: [IntegerLiteral] 1 +# 22| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) +# 23| getStmt: [AssignAddExpr] ... += ... +# 23| getDesugared: [AssignExpr] ... = ... +# 23| getAnOperand/getLeftOperand: [LocalVariableAccess] sum +# 23| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 23| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum +# 23| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value +# 24| getStmt: [AssignMulExpr] ... *= ... +# 24| getDesugared: [AssignExpr] ... = ... +# 24| getAnOperand/getLeftOperand: [LocalVariableAccess] foo +# 24| getAnOperand/getRightOperand: [MulExpr] ... * ... +# 24| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo +# 24| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value # 28| [ForExpr] for ... in ... # 28| getDesugared: [StmtSequence] ... # 28| getStmt: [IfExpr] if ... @@ -781,36 +788,37 @@ control/loops.rb: # 28| getBlock: [BraceBlock] { ... } # 28| getParameter: [SimpleParameter] __synth__0__1 # 28| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 28| getStmt: [AssignExpr] ... = ... -# 28| getDesugared: [StmtSequence] ... -# 28| getStmt: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 -# 28| getAnOperand/getRightOperand: [SplatExpr] * ... -# 28| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 -# 28| getStmt: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] key -# 28| getAnOperand/getRightOperand: [MethodCall] call to [] -# 28| getReceiver: [LocalVariableAccess] __synth__2__1 -# 28| getArgument: [IntegerLiteral] 0 -# 28| getStmt: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] value -# 28| getAnOperand/getRightOperand: [MethodCall] call to [] -# 28| getReceiver: [LocalVariableAccess] __synth__2__1 -# 28| getArgument: [IntegerLiteral] 1 -# 28| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) -# 29| getStmt: [AssignAddExpr] ... += ... -# 29| getDesugared: [AssignExpr] ... = ... -# 29| getAnOperand/getLeftOperand: [LocalVariableAccess] sum -# 29| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 29| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum -# 29| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value -# 30| getStmt: [AssignDivExpr] ... /= ... -# 30| getDesugared: [AssignExpr] ... = ... -# 30| getAnOperand/getLeftOperand: [LocalVariableAccess] foo -# 30| getAnOperand/getRightOperand: [DivExpr] ... / ... -# 30| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo -# 30| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value -# 31| getStmt: [BreakStmt] break +# 28| getBody: [StmtSequence] ... +# 28| getStmt: [AssignExpr] ... = ... +# 28| getDesugared: [StmtSequence] ... +# 28| getStmt: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 +# 28| getAnOperand/getRightOperand: [SplatExpr] * ... +# 28| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 +# 28| getStmt: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] key +# 28| getAnOperand/getRightOperand: [MethodCall] call to [] +# 28| getReceiver: [LocalVariableAccess] __synth__2__1 +# 28| getArgument: [IntegerLiteral] 0 +# 28| getStmt: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] value +# 28| getAnOperand/getRightOperand: [MethodCall] call to [] +# 28| getReceiver: [LocalVariableAccess] __synth__2__1 +# 28| getArgument: [IntegerLiteral] 1 +# 28| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) +# 29| getStmt: [AssignAddExpr] ... += ... +# 29| getDesugared: [AssignExpr] ... = ... +# 29| getAnOperand/getLeftOperand: [LocalVariableAccess] sum +# 29| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 29| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] sum +# 29| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value +# 30| getStmt: [AssignDivExpr] ... /= ... +# 30| getDesugared: [AssignExpr] ... = ... +# 30| getAnOperand/getLeftOperand: [LocalVariableAccess] foo +# 30| getAnOperand/getRightOperand: [DivExpr] ... / ... +# 30| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo +# 30| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value +# 31| getStmt: [BreakStmt] break # 36| [AssignAddExpr] ... += ... # 36| getDesugared: [AssignExpr] ... = ... # 36| getAnOperand/getLeftOperand: [LocalVariableAccess] x @@ -1090,16 +1098,17 @@ erb/template.html.erb: # 27| getBlock: [BraceBlock] { ... } # 27| getParameter: [SimpleParameter] __synth__0__1 # 27| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 27| getStmt: [AssignExpr] ... = ... -# 27| getAnOperand/getLeftOperand: [LocalVariableAccess] x -# 27| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 28| getStmt: [AssignAddExpr] ... += ... -# 28| getDesugared: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] xs -# 28| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 28| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] xs -# 28| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] x -# 29| getStmt: [LocalVariableAccess] xs +# 27| getBody: [StmtSequence] ... +# 27| getStmt: [AssignExpr] ... = ... +# 27| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 27| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 28| getStmt: [AssignAddExpr] ... += ... +# 28| getDesugared: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] xs +# 28| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 28| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] xs +# 28| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] x +# 29| getStmt: [LocalVariableAccess] xs gems/test.gemspec: # 2| [AssignExpr] ... = ... # 2| getDesugared: [StmtSequence] ... diff --git a/ruby/ql/test/library-tests/modules/methods.expected b/ruby/ql/test/library-tests/modules/methods.expected index 95ca9e9c260..272081218c5 100644 --- a/ruby/ql/test/library-tests/modules/methods.expected +++ b/ruby/ql/test/library-tests/modules/methods.expected @@ -709,32 +709,40 @@ lookupMethod | unresolved_subclass.rb:21:1:22:3 | UnresolvedNamespace::X1::X2::X3::A | puts | calls.rb:102:5:102:30 | puts | | unresolved_subclass.rb:21:1:22:3 | UnresolvedNamespace::X1::X2::X3::A | to_s | calls.rb:172:5:173:7 | to_s | enclosingMethod +| calls.rb:2:5:2:14 | ... | calls.rb:1:1:3:3 | foo | | calls.rb:2:5:2:14 | call to puts | calls.rb:1:1:3:3 | foo | | calls.rb:2:5:2:14 | self | calls.rb:1:1:3:3 | foo | | calls.rb:2:10:2:14 | "foo" | calls.rb:1:1:3:3 | foo | | calls.rb:2:11:2:13 | foo | calls.rb:1:1:3:3 | foo | +| calls.rb:8:5:8:15 | ... | calls.rb:7:1:9:3 | bar | | calls.rb:8:5:8:15 | call to puts | calls.rb:7:1:9:3 | bar | | calls.rb:8:5:8:15 | self | calls.rb:7:1:9:3 | bar | | calls.rb:8:10:8:15 | "bar1" | calls.rb:7:1:9:3 | bar | | calls.rb:8:11:8:14 | bar1 | calls.rb:7:1:9:3 | bar | +| calls.rb:14:5:14:15 | ... | calls.rb:13:1:15:3 | bar | | calls.rb:14:5:14:15 | call to puts | calls.rb:13:1:15:3 | bar | | calls.rb:14:5:14:15 | self | calls.rb:13:1:15:3 | bar | | calls.rb:14:10:14:15 | "bar2" | calls.rb:13:1:15:3 | bar | | calls.rb:14:11:14:14 | bar2 | calls.rb:13:1:15:3 | bar | | calls.rb:23:9:23:19 | call to singleton_m | calls.rb:22:5:24:7 | instance_m | | calls.rb:23:9:23:19 | self | calls.rb:22:5:24:7 | instance_m | +| calls.rb:23:9:23:35 | ... | calls.rb:22:5:24:7 | instance_m | | calls.rb:26:9:26:18 | call to instance_m | calls.rb:25:5:27:7 | singleton_m | | calls.rb:26:9:26:18 | self | calls.rb:25:5:27:7 | singleton_m | +| calls.rb:26:9:26:34 | ... | calls.rb:25:5:27:7 | singleton_m | | calls.rb:40:5:40:14 | call to instance_m | calls.rb:39:1:41:3 | call_instance_m | | calls.rb:40:5:40:14 | self | calls.rb:39:1:41:3 | call_instance_m | +| calls.rb:40:5:40:30 | ... | calls.rb:39:1:41:3 | call_instance_m | | calls.rb:52:9:52:18 | call to instance_m | calls.rb:51:5:57:7 | baz | | calls.rb:52:9:52:18 | self | calls.rb:51:5:57:7 | baz | +| calls.rb:52:9:56:40 | ... | calls.rb:51:5:57:7 | baz | | calls.rb:53:9:53:12 | self | calls.rb:51:5:57:7 | baz | | calls.rb:53:9:53:23 | call to instance_m | calls.rb:51:5:57:7 | baz | | calls.rb:55:9:55:19 | call to singleton_m | calls.rb:51:5:57:7 | baz | | calls.rb:55:9:55:19 | self | calls.rb:51:5:57:7 | baz | | calls.rb:56:9:56:12 | self | calls.rb:51:5:57:7 | baz | | calls.rb:56:9:56:24 | call to singleton_m | calls.rb:51:5:57:7 | baz | +| calls.rb:67:9:67:13 | ... | calls.rb:66:5:68:7 | baz | | calls.rb:67:9:67:13 | super call to baz | calls.rb:66:5:68:7 | baz | | calls.rb:76:18:76:18 | a | calls.rb:76:1:79:3 | optional_arg | | calls.rb:76:18:76:18 | a | calls.rb:76:1:79:3 | optional_arg | @@ -744,12 +752,15 @@ enclosingMethod | calls.rb:76:28:76:28 | 5 | calls.rb:76:1:79:3 | optional_arg | | calls.rb:77:5:77:5 | a | calls.rb:76:1:79:3 | optional_arg | | calls.rb:77:5:77:16 | call to bit_length | calls.rb:76:1:79:3 | optional_arg | +| calls.rb:77:5:78:16 | ... | calls.rb:76:1:79:3 | optional_arg | | calls.rb:78:5:78:5 | b | calls.rb:76:1:79:3 | optional_arg | | calls.rb:78:5:78:16 | call to bit_length | calls.rb:76:1:79:3 | optional_arg | +| calls.rb:82:5:82:11 | ... | calls.rb:81:1:83:3 | call_block | | calls.rb:82:5:82:11 | yield ... | calls.rb:81:1:83:3 | call_block | | calls.rb:82:11:82:11 | 1 | calls.rb:81:1:83:3 | call_block | | calls.rb:86:5:86:7 | var | calls.rb:85:1:89:3 | foo | | calls.rb:86:5:86:18 | ... = ... | calls.rb:85:1:89:3 | foo | +| calls.rb:86:5:88:29 | ... | calls.rb:85:1:89:3 | foo | | calls.rb:86:11:86:14 | Hash | calls.rb:85:1:89:3 | foo | | calls.rb:86:11:86:18 | call to new | calls.rb:85:1:89:3 | foo | | calls.rb:87:5:87:7 | var | calls.rb:85:1:89:3 | foo | @@ -761,25 +772,30 @@ enclosingMethod | calls.rb:88:19:88:19 | x | calls.rb:85:1:89:3 | foo | | calls.rb:88:19:88:19 | x | calls.rb:85:1:89:3 | foo | | calls.rb:88:22:88:24 | var | calls.rb:85:1:89:3 | foo | +| calls.rb:88:22:88:27 | ... | calls.rb:85:1:89:3 | foo | | calls.rb:88:22:88:27 | ...[...] | calls.rb:85:1:89:3 | foo | | calls.rb:88:26:88:26 | x | calls.rb:85:1:89:3 | foo | | calls.rb:102:14:102:14 | x | calls.rb:102:5:102:30 | puts | | calls.rb:102:14:102:14 | x | calls.rb:102:5:102:30 | puts | +| calls.rb:102:17:102:26 | ... | calls.rb:102:5:102:30 | puts | | calls.rb:102:17:102:26 | call to old_puts | calls.rb:102:5:102:30 | puts | | calls.rb:102:17:102:26 | self | calls.rb:102:5:102:30 | puts | | calls.rb:102:26:102:26 | x | calls.rb:102:5:102:30 | puts | | calls.rb:108:17:108:17 | x | calls.rb:108:5:110:7 | include | | calls.rb:108:17:108:17 | x | calls.rb:108:5:110:7 | include | +| calls.rb:109:9:109:21 | ... | calls.rb:108:5:110:7 | include | | calls.rb:109:9:109:21 | call to old_include | calls.rb:108:5:110:7 | include | | calls.rb:109:9:109:21 | self | calls.rb:108:5:110:7 | include | | calls.rb:109:21:109:21 | x | calls.rb:108:5:110:7 | include | | calls.rb:122:12:122:12 | x | calls.rb:122:5:122:31 | [] | | calls.rb:122:12:122:12 | x | calls.rb:122:5:122:31 | [] | +| calls.rb:122:15:122:27 | ... | calls.rb:122:5:122:31 | [] | | calls.rb:122:15:122:27 | call to old_lookup | calls.rb:122:5:122:31 | [] | | calls.rb:122:15:122:27 | self | calls.rb:122:5:122:31 | [] | | calls.rb:122:26:122:26 | x | calls.rb:122:5:122:31 | [] | | calls.rb:127:10:127:10 | x | calls.rb:127:3:127:29 | [] | | calls.rb:127:10:127:10 | x | calls.rb:127:3:127:29 | [] | +| calls.rb:127:13:127:25 | ... | calls.rb:127:3:127:29 | [] | | calls.rb:127:13:127:25 | call to old_lookup | calls.rb:127:3:127:29 | [] | | calls.rb:127:13:127:25 | self | calls.rb:127:3:127:29 | [] | | calls.rb:127:24:127:24 | x | calls.rb:127:3:127:29 | [] | @@ -787,6 +803,7 @@ enclosingMethod | calls.rb:131:16:131:19 | body | calls.rb:131:3:137:5 | foreach | | calls.rb:132:5:132:5 | x | calls.rb:131:3:137:5 | foreach | | calls.rb:132:5:132:9 | ... = ... | calls.rb:131:3:137:5 | foreach | +| calls.rb:132:5:136:7 | ... | calls.rb:131:3:137:5 | foreach | | calls.rb:132:9:132:9 | 0 | calls.rb:131:3:137:5 | foreach | | calls.rb:133:5:136:7 | while ... | calls.rb:131:3:137:5 | foreach | | calls.rb:133:11:133:11 | x | calls.rb:131:3:137:5 | foreach | @@ -805,65 +822,80 @@ enclosingMethod | calls.rb:135:9:135:14 | ... = ... | calls.rb:131:3:137:5 | foreach | | calls.rb:135:11:135:12 | ... + ... | calls.rb:131:3:137:5 | foreach | | calls.rb:135:14:135:14 | 1 | calls.rb:131:3:137:5 | foreach | +| calls.rb:141:5:141:20 | ... | calls.rb:140:1:142:3 | funny | | calls.rb:141:5:141:20 | yield ... | calls.rb:140:1:142:3 | funny | | calls.rb:141:11:141:20 | "prefix: " | calls.rb:140:1:142:3 | funny | | calls.rb:141:12:141:19 | prefix: | calls.rb:140:1:142:3 | funny | | calls.rb:158:14:158:15 | &b | calls.rb:158:1:160:3 | indirect | | calls.rb:158:15:158:15 | b | calls.rb:158:1:160:3 | indirect | +| calls.rb:159:5:159:17 | ... | calls.rb:158:1:160:3 | indirect | | calls.rb:159:5:159:17 | call to call_block | calls.rb:158:1:160:3 | indirect | | calls.rb:159:5:159:17 | self | calls.rb:158:1:160:3 | indirect | | calls.rb:159:16:159:17 | &... | calls.rb:158:1:160:3 | indirect | | calls.rb:159:17:159:17 | b | calls.rb:158:1:160:3 | indirect | | calls.rb:167:9:167:12 | self | calls.rb:166:5:168:7 | s_method | +| calls.rb:167:9:167:17 | ... | calls.rb:166:5:168:7 | s_method | | calls.rb:167:9:167:17 | call to to_s | calls.rb:166:5:168:7 | s_method | | calls.rb:192:9:192:26 | call to puts | calls.rb:191:5:194:7 | singleton_a | | calls.rb:192:9:192:26 | self | calls.rb:191:5:194:7 | singleton_a | +| calls.rb:192:9:193:24 | ... | calls.rb:191:5:194:7 | singleton_a | | calls.rb:192:14:192:26 | "singleton_a" | calls.rb:191:5:194:7 | singleton_a | | calls.rb:192:15:192:25 | singleton_a | calls.rb:191:5:194:7 | singleton_a | | calls.rb:193:9:193:12 | self | calls.rb:191:5:194:7 | singleton_a | | calls.rb:193:9:193:24 | call to singleton_b | calls.rb:191:5:194:7 | singleton_a | | calls.rb:197:9:197:26 | call to puts | calls.rb:196:5:199:7 | singleton_b | | calls.rb:197:9:197:26 | self | calls.rb:196:5:199:7 | singleton_b | +| calls.rb:197:9:198:24 | ... | calls.rb:196:5:199:7 | singleton_b | | calls.rb:197:14:197:26 | "singleton_b" | calls.rb:196:5:199:7 | singleton_b | | calls.rb:197:15:197:25 | singleton_b | calls.rb:196:5:199:7 | singleton_b | | calls.rb:198:9:198:12 | self | calls.rb:196:5:199:7 | singleton_b | | calls.rb:198:9:198:24 | call to singleton_c | calls.rb:196:5:199:7 | singleton_b | +| calls.rb:202:9:202:26 | ... | calls.rb:201:5:203:7 | singleton_c | | calls.rb:202:9:202:26 | call to puts | calls.rb:201:5:203:7 | singleton_c | | calls.rb:202:9:202:26 | self | calls.rb:201:5:203:7 | singleton_c | | calls.rb:202:14:202:26 | "singleton_c" | calls.rb:201:5:203:7 | singleton_c | | calls.rb:202:15:202:25 | singleton_c | calls.rb:201:5:203:7 | singleton_c | | calls.rb:206:9:206:26 | call to puts | calls.rb:205:5:208:7 | singleton_d | | calls.rb:206:9:206:26 | self | calls.rb:205:5:208:7 | singleton_d | +| calls.rb:206:9:207:24 | ... | calls.rb:205:5:208:7 | singleton_d | | calls.rb:206:14:206:26 | "singleton_d" | calls.rb:205:5:208:7 | singleton_d | | calls.rb:206:15:206:25 | singleton_d | calls.rb:205:5:208:7 | singleton_d | | calls.rb:207:9:207:12 | self | calls.rb:205:5:208:7 | singleton_d | | calls.rb:207:9:207:24 | call to singleton_a | calls.rb:205:5:208:7 | singleton_d | | calls.rb:211:9:213:11 | singleton_e | calls.rb:210:5:215:7 | instance | +| calls.rb:211:9:214:19 | ... | calls.rb:210:5:215:7 | instance | | calls.rb:211:13:211:16 | self | calls.rb:210:5:215:7 | instance | +| calls.rb:212:13:212:30 | ... | calls.rb:211:9:213:11 | singleton_e | | calls.rb:212:13:212:30 | call to puts | calls.rb:211:9:213:11 | singleton_e | | calls.rb:212:13:212:30 | self | calls.rb:211:9:213:11 | singleton_e | | calls.rb:212:18:212:30 | "singleton_e" | calls.rb:211:9:213:11 | singleton_e | | calls.rb:212:19:212:29 | singleton_e | calls.rb:211:9:213:11 | singleton_e | | calls.rb:214:9:214:19 | call to singleton_e | calls.rb:210:5:215:7 | instance | | calls.rb:214:9:214:19 | self | calls.rb:210:5:215:7 | instance | +| calls.rb:219:13:219:30 | ... | calls.rb:218:9:220:11 | singleton_f | | calls.rb:219:13:219:30 | call to puts | calls.rb:218:9:220:11 | singleton_f | | calls.rb:219:13:219:30 | self | calls.rb:218:9:220:11 | singleton_f | | calls.rb:219:18:219:30 | "singleton_f" | calls.rb:218:9:220:11 | singleton_f | | calls.rb:219:19:219:29 | singleton_f | calls.rb:218:9:220:11 | singleton_f | | calls.rb:224:9:224:12 | self | calls.rb:223:5:225:7 | call_singleton_g | +| calls.rb:224:9:224:24 | ... | calls.rb:223:5:225:7 | call_singleton_g | | calls.rb:224:9:224:24 | call to singleton_g | calls.rb:223:5:225:7 | call_singleton_g | +| calls.rb:237:5:237:24 | ... | calls.rb:236:1:238:3 | singleton_g | | calls.rb:237:5:237:24 | call to puts | calls.rb:236:1:238:3 | singleton_g | | calls.rb:237:5:237:24 | self | calls.rb:236:1:238:3 | singleton_g | | calls.rb:237:10:237:24 | "singleton_g_1" | calls.rb:236:1:238:3 | singleton_g | | calls.rb:237:11:237:23 | singleton_g_1 | calls.rb:236:1:238:3 | singleton_g | +| calls.rb:244:5:244:24 | ... | calls.rb:243:1:245:3 | singleton_g | | calls.rb:244:5:244:24 | call to puts | calls.rb:243:1:245:3 | singleton_g | | calls.rb:244:5:244:24 | self | calls.rb:243:1:245:3 | singleton_g | | calls.rb:244:10:244:24 | "singleton_g_2" | calls.rb:243:1:245:3 | singleton_g | | calls.rb:244:11:244:23 | singleton_g_2 | calls.rb:243:1:245:3 | singleton_g | +| calls.rb:252:9:252:28 | ... | calls.rb:251:5:253:7 | singleton_g | | calls.rb:252:9:252:28 | call to puts | calls.rb:251:5:253:7 | singleton_g | | calls.rb:252:9:252:28 | self | calls.rb:251:5:253:7 | singleton_g | | calls.rb:252:14:252:28 | "singleton_g_3" | calls.rb:251:5:253:7 | singleton_g | | calls.rb:252:15:252:27 | singleton_g_3 | calls.rb:251:5:253:7 | singleton_g | +| calls.rb:268:5:268:22 | ... | calls.rb:267:1:269:3 | singleton_g | | calls.rb:268:5:268:22 | call to puts | calls.rb:267:1:269:3 | singleton_g | | calls.rb:268:5:268:22 | self | calls.rb:267:1:269:3 | singleton_g | | calls.rb:268:10:268:22 | "singleton_g" | calls.rb:267:1:269:3 | singleton_g | @@ -873,24 +905,29 @@ enclosingMethod | calls.rb:279:5:279:8 | type | calls.rb:278:1:286:3 | create | | calls.rb:279:5:279:12 | call to new | calls.rb:278:1:286:3 | create | | calls.rb:279:5:279:21 | call to instance | calls.rb:278:1:286:3 | create | +| calls.rb:279:5:285:20 | ... | calls.rb:278:1:286:3 | create | | calls.rb:281:5:283:7 | singleton_h | calls.rb:278:1:286:3 | create | | calls.rb:281:9:281:12 | type | calls.rb:278:1:286:3 | create | +| calls.rb:282:9:282:26 | ... | calls.rb:281:5:283:7 | singleton_h | | calls.rb:282:9:282:26 | call to puts | calls.rb:281:5:283:7 | singleton_h | | calls.rb:282:9:282:26 | self | calls.rb:281:5:283:7 | singleton_h | | calls.rb:282:14:282:26 | "singleton_h" | calls.rb:281:5:283:7 | singleton_h | | calls.rb:282:15:282:25 | singleton_h | calls.rb:281:5:283:7 | singleton_h | | calls.rb:285:5:285:8 | type | calls.rb:278:1:286:3 | create | | calls.rb:285:5:285:20 | call to singleton_h | calls.rb:278:1:286:3 | create | +| calls.rb:295:9:295:26 | ... | calls.rb:294:5:296:7 | singleton_i | | calls.rb:295:9:295:26 | call to puts | calls.rb:294:5:296:7 | singleton_i | | calls.rb:295:9:295:26 | self | calls.rb:294:5:296:7 | singleton_i | | calls.rb:295:14:295:26 | "singleton_i" | calls.rb:294:5:296:7 | singleton_i | | calls.rb:295:15:295:25 | singleton_i | calls.rb:294:5:296:7 | singleton_i | +| calls.rb:304:9:304:26 | ... | calls.rb:303:5:305:7 | singleton_j | | calls.rb:304:9:304:26 | call to puts | calls.rb:303:5:305:7 | singleton_j | | calls.rb:304:9:304:26 | self | calls.rb:303:5:305:7 | singleton_j | | calls.rb:304:14:304:26 | "singleton_j" | calls.rb:303:5:305:7 | singleton_j | | calls.rb:304:15:304:25 | singleton_j | calls.rb:303:5:305:7 | singleton_j | | calls.rb:312:9:312:31 | call to puts | calls.rb:311:5:314:7 | instance | | calls.rb:312:9:312:31 | self | calls.rb:311:5:314:7 | instance | +| calls.rb:312:9:313:36 | ... | calls.rb:311:5:314:7 | instance | | calls.rb:312:14:312:31 | "SelfNew#instance" | calls.rb:311:5:314:7 | instance | | calls.rb:312:15:312:30 | SelfNew#instance | calls.rb:311:5:314:7 | instance | | calls.rb:313:9:313:11 | call to new | calls.rb:311:5:314:7 | instance | @@ -898,16 +935,21 @@ enclosingMethod | calls.rb:313:9:313:20 | call to instance | calls.rb:311:5:314:7 | instance | | calls.rb:317:9:317:11 | call to new | calls.rb:316:5:318:7 | singleton | | calls.rb:317:9:317:11 | self | calls.rb:316:5:318:7 | singleton | +| calls.rb:317:9:317:20 | ... | calls.rb:316:5:318:7 | singleton | | calls.rb:317:9:317:20 | call to instance | calls.rb:316:5:318:7 | singleton | +| calls.rb:327:9:327:26 | ... | calls.rb:326:5:328:7 | instance | | calls.rb:327:9:327:26 | call to puts | calls.rb:326:5:328:7 | instance | | calls.rb:327:9:327:26 | self | calls.rb:326:5:328:7 | instance | | calls.rb:327:14:327:26 | "C1#instance" | calls.rb:326:5:328:7 | instance | | calls.rb:327:15:327:25 | C1#instance | calls.rb:326:5:328:7 | instance | +| calls.rb:331:9:331:12 | ... | calls.rb:330:5:332:7 | return_self | | calls.rb:331:9:331:12 | self | calls.rb:330:5:332:7 | return_self | +| calls.rb:337:9:337:26 | ... | calls.rb:336:5:338:7 | instance | | calls.rb:337:9:337:26 | call to puts | calls.rb:336:5:338:7 | instance | | calls.rb:337:9:337:26 | self | calls.rb:336:5:338:7 | instance | | calls.rb:337:14:337:26 | "C2#instance" | calls.rb:336:5:338:7 | instance | | calls.rb:337:15:337:25 | C2#instance | calls.rb:336:5:338:7 | instance | +| calls.rb:343:9:343:26 | ... | calls.rb:342:5:344:7 | instance | | calls.rb:343:9:343:26 | call to puts | calls.rb:342:5:344:7 | instance | | calls.rb:343:9:343:26 | self | calls.rb:342:5:344:7 | instance | | calls.rb:343:14:343:26 | "C3#instance" | calls.rb:342:5:344:7 | instance | @@ -915,6 +957,7 @@ enclosingMethod | calls.rb:347:22:347:22 | x | calls.rb:347:1:363:3 | pattern_dispatch | | calls.rb:347:22:347:22 | x | calls.rb:347:1:363:3 | pattern_dispatch | | calls.rb:348:5:356:7 | case ... | calls.rb:347:1:363:3 | pattern_dispatch | +| calls.rb:348:5:362:7 | ... | calls.rb:347:1:363:3 | pattern_dispatch | | calls.rb:348:10:348:10 | x | calls.rb:347:1:363:3 | pattern_dispatch | | calls.rb:349:5:350:18 | when ... | calls.rb:347:1:363:3 | pattern_dispatch | | calls.rb:349:10:349:11 | C3 | calls.rb:347:1:363:3 | pattern_dispatch | @@ -955,89 +998,111 @@ enclosingMethod | calls.rb:361:26:361:36 | call to instance | calls.rb:347:1:363:3 | pattern_dispatch | | calls.rb:374:19:374:19 | x | calls.rb:374:1:378:3 | add_singleton | | calls.rb:374:19:374:19 | x | calls.rb:374:1:378:3 | add_singleton | +| calls.rb:375:5:377:7 | ... | calls.rb:374:1:378:3 | add_singleton | | calls.rb:375:5:377:7 | instance | calls.rb:374:1:378:3 | add_singleton | | calls.rb:375:9:375:9 | x | calls.rb:374:1:378:3 | add_singleton | +| calls.rb:376:9:376:28 | ... | calls.rb:375:5:377:7 | instance | | calls.rb:376:9:376:28 | call to puts | calls.rb:375:5:377:7 | instance | | calls.rb:376:9:376:28 | self | calls.rb:375:5:377:7 | instance | | calls.rb:376:14:376:28 | "instance_on x" | calls.rb:375:5:377:7 | instance | | calls.rb:376:15:376:27 | instance_on x | calls.rb:375:5:377:7 | instance | +| calls.rb:388:13:388:48 | ... | calls.rb:387:9:389:11 | singleton1 | | calls.rb:388:13:388:48 | call to puts | calls.rb:387:9:389:11 | singleton1 | | calls.rb:388:13:388:48 | self | calls.rb:387:9:389:11 | singleton1 | | calls.rb:388:18:388:48 | "SingletonOverride1#singleton1" | calls.rb:387:9:389:11 | singleton1 | | calls.rb:388:19:388:47 | SingletonOverride1#singleton1 | calls.rb:387:9:389:11 | singleton1 | +| calls.rb:392:13:392:22 | ... | calls.rb:391:9:393:11 | call_singleton1 | | calls.rb:392:13:392:22 | call to singleton1 | calls.rb:391:9:393:11 | call_singleton1 | | calls.rb:392:13:392:22 | self | calls.rb:391:9:393:11 | call_singleton1 | | calls.rb:396:13:396:16 | self | calls.rb:395:9:397:11 | factory | | calls.rb:396:13:396:20 | call to new | calls.rb:395:9:397:11 | factory | +| calls.rb:396:13:396:30 | ... | calls.rb:395:9:397:11 | factory | | calls.rb:396:13:396:30 | call to instance1 | calls.rb:395:9:397:11 | factory | +| calls.rb:401:9:401:44 | ... | calls.rb:400:5:402:7 | singleton2 | | calls.rb:401:9:401:44 | call to puts | calls.rb:400:5:402:7 | singleton2 | | calls.rb:401:9:401:44 | self | calls.rb:400:5:402:7 | singleton2 | | calls.rb:401:14:401:44 | "SingletonOverride1#singleton2" | calls.rb:400:5:402:7 | singleton2 | | calls.rb:401:15:401:43 | SingletonOverride1#singleton2 | calls.rb:400:5:402:7 | singleton2 | +| calls.rb:405:9:405:18 | ... | calls.rb:404:5:406:7 | call_singleton2 | | calls.rb:405:9:405:18 | call to singleton2 | calls.rb:404:5:406:7 | call_singleton2 | | calls.rb:405:9:405:18 | self | calls.rb:404:5:406:7 | call_singleton2 | +| calls.rb:411:9:411:43 | ... | calls.rb:410:5:412:7 | instance1 | | calls.rb:411:9:411:43 | call to puts | calls.rb:410:5:412:7 | instance1 | | calls.rb:411:9:411:43 | self | calls.rb:410:5:412:7 | instance1 | | calls.rb:411:14:411:43 | "SingletonOverride1#instance1" | calls.rb:410:5:412:7 | instance1 | | calls.rb:411:15:411:42 | SingletonOverride1#instance1 | calls.rb:410:5:412:7 | instance1 | +| calls.rb:423:13:423:48 | ... | calls.rb:422:9:424:11 | singleton1 | | calls.rb:423:13:423:48 | call to puts | calls.rb:422:9:424:11 | singleton1 | | calls.rb:423:13:423:48 | self | calls.rb:422:9:424:11 | singleton1 | | calls.rb:423:18:423:48 | "SingletonOverride2#singleton1" | calls.rb:422:9:424:11 | singleton1 | | calls.rb:423:19:423:47 | SingletonOverride2#singleton1 | calls.rb:422:9:424:11 | singleton1 | +| calls.rb:428:9:428:44 | ... | calls.rb:427:5:429:7 | singleton2 | | calls.rb:428:9:428:44 | call to puts | calls.rb:427:5:429:7 | singleton2 | | calls.rb:428:9:428:44 | self | calls.rb:427:5:429:7 | singleton2 | | calls.rb:428:14:428:44 | "SingletonOverride2#singleton2" | calls.rb:427:5:429:7 | singleton2 | | calls.rb:428:15:428:43 | SingletonOverride2#singleton2 | calls.rb:427:5:429:7 | singleton2 | +| calls.rb:432:9:432:43 | ... | calls.rb:431:5:433:7 | instance1 | | calls.rb:432:9:432:43 | call to puts | calls.rb:431:5:433:7 | instance1 | | calls.rb:432:9:432:43 | self | calls.rb:431:5:433:7 | instance1 | | calls.rb:432:14:432:43 | "SingletonOverride2#instance1" | calls.rb:431:5:433:7 | instance1 | | calls.rb:432:15:432:42 | SingletonOverride2#instance1 | calls.rb:431:5:433:7 | instance1 | +| calls.rb:444:13:444:48 | ... | calls.rb:443:9:445:11 | m1 | | calls.rb:444:13:444:48 | call to puts | calls.rb:443:9:445:11 | m1 | | calls.rb:444:13:444:48 | self | calls.rb:443:9:445:11 | m1 | | calls.rb:444:18:444:48 | "ConditionalInstanceMethods#m1" | calls.rb:443:9:445:11 | m1 | | calls.rb:444:19:444:47 | ConditionalInstanceMethods#m1 | calls.rb:443:9:445:11 | m1 | | calls.rb:449:9:449:44 | call to puts | calls.rb:448:5:460:7 | m2 | | calls.rb:449:9:449:44 | self | calls.rb:448:5:460:7 | m2 | +| calls.rb:449:9:459:10 | ... | calls.rb:448:5:460:7 | m2 | | calls.rb:449:14:449:44 | "ConditionalInstanceMethods#m2" | calls.rb:448:5:460:7 | m2 | | calls.rb:449:15:449:43 | ConditionalInstanceMethods#m2 | calls.rb:448:5:460:7 | m2 | | calls.rb:451:9:457:11 | m3 | calls.rb:448:5:460:7 | m2 | | calls.rb:452:13:452:48 | call to puts | calls.rb:451:9:457:11 | m3 | | calls.rb:452:13:452:48 | self | calls.rb:451:9:457:11 | m3 | +| calls.rb:452:13:456:15 | ... | calls.rb:451:9:457:11 | m3 | | calls.rb:452:18:452:48 | "ConditionalInstanceMethods#m3" | calls.rb:451:9:457:11 | m3 | | calls.rb:452:19:452:47 | ConditionalInstanceMethods#m3 | calls.rb:451:9:457:11 | m3 | | calls.rb:454:13:456:15 | m4 | calls.rb:451:9:457:11 | m3 | +| calls.rb:455:17:455:52 | ... | calls.rb:454:13:456:15 | m4 | | calls.rb:455:17:455:52 | call to puts | calls.rb:454:13:456:15 | m4 | | calls.rb:455:17:455:52 | self | calls.rb:454:13:456:15 | m4 | | calls.rb:455:22:455:52 | "ConditionalInstanceMethods#m4" | calls.rb:454:13:456:15 | m4 | | calls.rb:455:23:455:51 | ConditionalInstanceMethods#m4 | calls.rb:454:13:456:15 | m4 | | calls.rb:459:9:459:10 | call to m3 | calls.rb:448:5:460:7 | m2 | | calls.rb:459:9:459:10 | self | calls.rb:448:5:460:7 | m2 | +| calls.rb:465:17:465:40 | ... | calls.rb:464:13:466:15 | m5 | | calls.rb:465:17:465:40 | call to puts | calls.rb:464:13:466:15 | m5 | | calls.rb:465:17:465:40 | self | calls.rb:464:13:466:15 | m5 | | calls.rb:465:22:465:40 | "AnonymousClass#m5" | calls.rb:464:13:466:15 | m5 | | calls.rb:465:23:465:39 | AnonymousClass#m5 | calls.rb:464:13:466:15 | m5 | +| calls.rb:481:13:481:22 | ... | calls.rb:480:9:482:11 | foo | | calls.rb:481:13:481:22 | call to puts | calls.rb:480:9:482:11 | foo | | calls.rb:481:13:481:22 | self | calls.rb:480:9:482:11 | foo | | calls.rb:481:18:481:22 | "foo" | calls.rb:480:9:482:11 | foo | | calls.rb:481:19:481:21 | foo | calls.rb:480:9:482:11 | foo | +| calls.rb:487:13:487:22 | ... | calls.rb:486:9:488:11 | bar | | calls.rb:487:13:487:22 | call to puts | calls.rb:486:9:488:11 | bar | | calls.rb:487:13:487:22 | self | calls.rb:486:9:488:11 | bar | | calls.rb:487:18:487:22 | "bar" | calls.rb:486:9:488:11 | bar | | calls.rb:487:19:487:21 | bar | calls.rb:486:9:488:11 | bar | +| calls.rb:506:9:506:46 | ... | calls.rb:505:5:507:7 | singleton | | calls.rb:506:9:506:46 | call to puts | calls.rb:505:5:507:7 | singleton | | calls.rb:506:9:506:46 | self | calls.rb:505:5:507:7 | singleton | | calls.rb:506:14:506:46 | "ExtendSingletonMethod#singleton" | calls.rb:505:5:507:7 | singleton | | calls.rb:506:15:506:45 | ExtendSingletonMethod#singleton | calls.rb:505:5:507:7 | singleton | +| calls.rb:535:9:535:42 | ... | calls.rb:534:15:536:7 | foo | | calls.rb:535:9:535:42 | call to puts | calls.rb:534:15:536:7 | foo | | calls.rb:535:9:535:42 | self | calls.rb:534:15:536:7 | foo | | calls.rb:535:14:535:42 | "ProtectedMethodInModule#foo" | calls.rb:534:15:536:7 | foo | | calls.rb:535:15:535:41 | ProtectedMethodInModule#foo | calls.rb:534:15:536:7 | foo | +| calls.rb:543:9:543:35 | ... | calls.rb:542:15:544:7 | bar | | calls.rb:543:9:543:35 | call to puts | calls.rb:542:15:544:7 | bar | | calls.rb:543:9:543:35 | self | calls.rb:542:15:544:7 | bar | | calls.rb:543:14:543:35 | "ProtectedMethods#bar" | calls.rb:542:15:544:7 | bar | | calls.rb:543:15:543:34 | ProtectedMethods#bar | calls.rb:542:15:544:7 | bar | | calls.rb:547:9:547:11 | call to foo | calls.rb:546:5:551:7 | baz | | calls.rb:547:9:547:11 | self | calls.rb:546:5:551:7 | baz | +| calls.rb:547:9:550:32 | ... | calls.rb:546:5:551:7 | baz | | calls.rb:548:9:548:11 | call to bar | calls.rb:546:5:551:7 | baz | | calls.rb:548:9:548:11 | self | calls.rb:546:5:551:7 | baz | | calls.rb:549:9:549:24 | ProtectedMethods | calls.rb:546:5:551:7 | baz | @@ -1048,28 +1113,39 @@ enclosingMethod | calls.rb:550:9:550:32 | call to bar | calls.rb:546:5:551:7 | baz | | calls.rb:560:9:560:11 | call to foo | calls.rb:559:5:562:7 | baz | | calls.rb:560:9:560:11 | self | calls.rb:559:5:562:7 | baz | +| calls.rb:560:9:561:35 | ... | calls.rb:559:5:562:7 | baz | | calls.rb:561:9:561:27 | ProtectedMethodsSub | calls.rb:559:5:562:7 | baz | | calls.rb:561:9:561:31 | call to new | calls.rb:559:5:562:7 | baz | | calls.rb:561:9:561:35 | call to foo | calls.rb:559:5:562:7 | baz | | calls.rb:580:9:580:17 | call to singleton | calls.rb:579:5:582:7 | mid_method | | calls.rb:580:9:580:17 | self | calls.rb:579:5:582:7 | mid_method | +| calls.rb:580:9:581:35 | ... | calls.rb:579:5:582:7 | mid_method | | calls.rb:581:9:581:18 | call to singleton2 | calls.rb:579:5:582:7 | mid_method | | calls.rb:581:9:581:18 | self | calls.rb:579:5:582:7 | mid_method | +| calls.rb:596:9:596:18 | ... | calls.rb:595:5:597:7 | call_singleton1 | | calls.rb:596:9:596:18 | call to singleton1 | calls.rb:595:5:597:7 | call_singleton1 | | calls.rb:596:9:596:18 | self | calls.rb:595:5:597:7 | call_singleton1 | +| calls.rb:600:9:600:23 | ... | calls.rb:599:5:601:7 | call_call_singleton1 | | calls.rb:600:9:600:23 | call to call_singleton1 | calls.rb:599:5:601:7 | call_call_singleton1 | | calls.rb:600:9:600:23 | self | calls.rb:599:5:601:7 | call_call_singleton1 | | calls.rb:609:9:609:18 | call to singleton1 | calls.rb:608:5:610:7 | call_singleton1 | | calls.rb:609:9:609:18 | self | calls.rb:608:5:610:7 | call_singleton1 | +| calls.rb:609:9:609:105 | ... | calls.rb:608:5:610:7 | call_singleton1 | | calls.rb:618:9:618:18 | call to singleton1 | calls.rb:617:5:619:7 | call_singleton1 | | calls.rb:618:9:618:18 | self | calls.rb:617:5:619:7 | call_singleton1 | +| calls.rb:618:9:618:105 | ... | calls.rb:617:5:619:7 | call_singleton1 | | calls.rb:628:9:628:12 | self | calls.rb:627:5:629:7 | foo | +| calls.rb:628:9:628:16 | ... | calls.rb:627:5:629:7 | foo | | calls.rb:628:9:628:16 | call to bar | calls.rb:627:5:629:7 | foo | +| calls.rb:637:9:637:13 | ... | calls.rb:636:5:638:7 | bar | | calls.rb:637:9:637:13 | super call to bar | calls.rb:636:5:638:7 | bar | | calls.rb:643:9:643:10 | C1 | calls.rb:642:5:644:7 | new | +| calls.rb:643:9:643:14 | ... | calls.rb:642:5:644:7 | new | | calls.rb:643:9:643:14 | call to new | calls.rb:642:5:644:7 | new | | calls.rb:651:9:651:12 | self | calls.rb:650:5:652:7 | new | +| calls.rb:651:9:651:21 | ... | calls.rb:650:5:652:7 | new | | calls.rb:651:9:651:21 | call to allocate | calls.rb:650:5:652:7 | new | +| calls.rb:655:9:655:34 | ... | calls.rb:654:5:656:7 | instance | | calls.rb:655:9:655:34 | call to puts | calls.rb:654:5:656:7 | instance | | calls.rb:655:9:655:34 | self | calls.rb:654:5:656:7 | instance | | calls.rb:655:14:655:34 | "CustomNew2#instance" | calls.rb:654:5:656:7 | instance | @@ -1079,27 +1155,34 @@ enclosingMethod | calls.rb:662:5:662:11 | Array | calls.rb:661:1:665:3 | capture_parameter | | calls.rb:662:5:662:11 | [...] | calls.rb:661:1:665:3 | capture_parameter | | calls.rb:662:5:662:11 | call to [] | calls.rb:661:1:665:3 | capture_parameter | +| calls.rb:662:5:664:7 | ... | calls.rb:661:1:665:3 | capture_parameter | | calls.rb:662:5:664:7 | call to each | calls.rb:661:1:665:3 | capture_parameter | | calls.rb:662:6:662:6 | 0 | calls.rb:661:1:665:3 | capture_parameter | | calls.rb:662:8:662:8 | 1 | calls.rb:661:1:665:3 | capture_parameter | | calls.rb:662:10:662:10 | 2 | calls.rb:661:1:665:3 | capture_parameter | | calls.rb:662:18:664:7 | do ... end | calls.rb:661:1:665:3 | capture_parameter | +| calls.rb:663:9:663:9 | ... | calls.rb:661:1:665:3 | capture_parameter | | calls.rb:663:9:663:9 | x | calls.rb:661:1:665:3 | capture_parameter | | element_reference.rb:2:12:2:12 | x | element_reference.rb:2:5:4:7 | [] | | element_reference.rb:2:12:2:12 | x | element_reference.rb:2:5:4:7 | [] | +| element_reference.rb:3:9:3:19 | ... | element_reference.rb:2:5:4:7 | [] | | element_reference.rb:3:9:3:19 | yield ... | element_reference.rb:2:5:4:7 | [] | | element_reference.rb:3:15:3:15 | x | element_reference.rb:2:5:4:7 | [] | | element_reference.rb:3:15:3:19 | ... + ... | element_reference.rb:2:5:4:7 | [] | | element_reference.rb:3:19:3:19 | 1 | element_reference.rb:2:5:4:7 | [] | +| hello.rb:3:9:3:22 | ... | hello.rb:2:5:4:7 | hello | | hello.rb:3:9:3:22 | return | hello.rb:2:5:4:7 | hello | | hello.rb:3:16:3:22 | "hello" | hello.rb:2:5:4:7 | hello | | hello.rb:3:17:3:21 | hello | hello.rb:2:5:4:7 | hello | +| hello.rb:6:9:6:22 | ... | hello.rb:5:5:7:7 | world | | hello.rb:6:9:6:22 | return | hello.rb:5:5:7:7 | world | | hello.rb:6:16:6:22 | "world" | hello.rb:5:5:7:7 | world | | hello.rb:6:17:6:21 | world | hello.rb:5:5:7:7 | world | +| hello.rb:14:9:14:20 | ... | hello.rb:13:5:15:7 | message | | hello.rb:14:9:14:20 | return | hello.rb:13:5:15:7 | message | | hello.rb:14:16:14:20 | call to hello | hello.rb:13:5:15:7 | message | | hello.rb:14:16:14:20 | self | hello.rb:13:5:15:7 | message | +| hello.rb:20:9:20:40 | ... | hello.rb:19:5:21:7 | message | | hello.rb:20:9:20:40 | return | hello.rb:19:5:21:7 | message | | hello.rb:20:16:20:20 | super call to message | hello.rb:19:5:21:7 | message | | hello.rb:20:16:20:26 | ... + ... | hello.rb:19:5:21:7 | message | @@ -1113,32 +1196,40 @@ enclosingMethod | hello.rb:20:39:20:39 | ! | hello.rb:19:5:21:7 | message | | instance_fields.rb:4:13:4:18 | @field | instance_fields.rb:3:9:5:11 | create | | instance_fields.rb:4:13:4:18 | self | instance_fields.rb:3:9:5:11 | create | +| instance_fields.rb:4:13:4:35 | ... | instance_fields.rb:3:9:5:11 | create | | instance_fields.rb:4:13:4:35 | ... = ... | instance_fields.rb:3:9:5:11 | create | | instance_fields.rb:4:22:4:31 | A_target | instance_fields.rb:3:9:5:11 | create | | instance_fields.rb:4:22:4:35 | call to new | instance_fields.rb:3:9:5:11 | create | | instance_fields.rb:7:13:7:18 | @field | instance_fields.rb:6:9:8:11 | use | | instance_fields.rb:7:13:7:18 | self | instance_fields.rb:6:9:8:11 | use | +| instance_fields.rb:7:13:7:25 | ... | instance_fields.rb:6:9:8:11 | use | | instance_fields.rb:7:13:7:25 | call to target | instance_fields.rb:6:9:8:11 | use | | instance_fields.rb:19:13:19:18 | @field | instance_fields.rb:18:9:20:11 | create | | instance_fields.rb:19:13:19:18 | self | instance_fields.rb:18:9:20:11 | create | +| instance_fields.rb:19:13:19:35 | ... | instance_fields.rb:18:9:20:11 | create | | instance_fields.rb:19:13:19:35 | ... = ... | instance_fields.rb:18:9:20:11 | create | | instance_fields.rb:19:22:19:31 | B_target | instance_fields.rb:18:9:20:11 | create | | instance_fields.rb:19:22:19:35 | call to new | instance_fields.rb:18:9:20:11 | create | | instance_fields.rb:22:13:22:18 | @field | instance_fields.rb:21:9:23:11 | use | | instance_fields.rb:22:13:22:18 | self | instance_fields.rb:21:9:23:11 | use | +| instance_fields.rb:22:13:22:25 | ... | instance_fields.rb:21:9:23:11 | use | | instance_fields.rb:22:13:22:25 | call to target | instance_fields.rb:21:9:23:11 | use | +| private.rb:84:7:84:32 | ... | private.rb:83:11:85:5 | m1 | | private.rb:84:7:84:32 | call to puts | private.rb:83:11:85:5 | m1 | | private.rb:84:7:84:32 | self | private.rb:83:11:85:5 | m1 | | private.rb:84:12:84:32 | "PrivateOverride1#m1" | private.rb:83:11:85:5 | m1 | | private.rb:84:13:84:31 | PrivateOverride1#m1 | private.rb:83:11:85:5 | m1 | +| private.rb:88:7:88:32 | ... | private.rb:87:11:89:5 | m2 | | private.rb:88:7:88:32 | call to puts | private.rb:87:11:89:5 | m2 | | private.rb:88:7:88:32 | self | private.rb:87:11:89:5 | m2 | | private.rb:88:12:88:32 | "PrivateOverride1#m2" | private.rb:87:11:89:5 | m2 | | private.rb:88:13:88:31 | PrivateOverride1#m2 | private.rb:87:11:89:5 | m2 | +| private.rb:92:7:92:8 | ... | private.rb:91:3:93:5 | call_m1 | | private.rb:92:7:92:8 | call to m1 | private.rb:91:3:93:5 | call_m1 | | private.rb:92:7:92:8 | self | private.rb:91:3:93:5 | call_m1 | | private.rb:98:7:98:32 | call to puts | private.rb:97:11:101:5 | m1 | | private.rb:98:7:98:32 | self | private.rb:97:11:101:5 | m1 | +| private.rb:98:7:100:45 | ... | private.rb:97:11:101:5 | m1 | | private.rb:98:12:98:32 | "PrivateOverride2#m1" | private.rb:97:11:101:5 | m1 | | private.rb:98:13:98:31 | PrivateOverride2#m1 | private.rb:97:11:101:5 | m1 | | private.rb:99:7:99:8 | call to m2 | private.rb:97:11:101:5 | m1 | @@ -1148,11 +1239,15 @@ enclosingMethod | private.rb:100:7:100:29 | call to m1 | private.rb:97:11:101:5 | m1 | | toplevel_self_singleton.rb:10:9:10:27 | call to ab_singleton_method | toplevel_self_singleton.rb:9:5:11:7 | method_in_block | | toplevel_self_singleton.rb:10:9:10:27 | self | toplevel_self_singleton.rb:9:5:11:7 | method_in_block | +| toplevel_self_singleton.rb:10:9:10:60 | ... | toplevel_self_singleton.rb:9:5:11:7 | method_in_block | | toplevel_self_singleton.rb:14:9:14:27 | call to ab_singleton_method | toplevel_self_singleton.rb:13:5:15:7 | method_in_block | | toplevel_self_singleton.rb:14:9:14:27 | self | toplevel_self_singleton.rb:13:5:15:7 | method_in_block | +| toplevel_self_singleton.rb:14:9:14:60 | ... | toplevel_self_singleton.rb:13:5:15:7 | method_in_block | | toplevel_self_singleton.rb:20:9:20:27 | call to ab_singleton_method | toplevel_self_singleton.rb:19:5:21:7 | method_in_struct | | toplevel_self_singleton.rb:20:9:20:27 | self | toplevel_self_singleton.rb:19:5:21:7 | method_in_struct | +| toplevel_self_singleton.rb:20:9:20:60 | ... | toplevel_self_singleton.rb:19:5:21:7 | method_in_struct | | toplevel_self_singleton.rb:30:13:30:19 | call to call_me | toplevel_self_singleton.rb:29:9:32:11 | call_you | | toplevel_self_singleton.rb:30:13:30:19 | self | toplevel_self_singleton.rb:29:9:32:11 | call_you | +| toplevel_self_singleton.rb:30:13:31:20 | ... | toplevel_self_singleton.rb:29:9:32:11 | call_you | | toplevel_self_singleton.rb:31:13:31:20 | call to call_you | toplevel_self_singleton.rb:29:9:32:11 | call_you | | toplevel_self_singleton.rb:31:13:31:20 | self | toplevel_self_singleton.rb:29:9:32:11 | call_you | diff --git a/ruby/ql/test/library-tests/modules/modules.expected b/ruby/ql/test/library-tests/modules/modules.expected index 967e90decaa..09a2236772a 100644 --- a/ruby/ql/test/library-tests/modules/modules.expected +++ b/ruby/ql/test/library-tests/modules/modules.expected @@ -571,6 +571,7 @@ resolveConstantWriteAccess | unresolved_subclass.rb:21:1:22:3 | A | UnresolvedNamespace::X1::X2::X3::A | enclosingModule | calls.rb:1:1:3:3 | foo | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:2:5:2:14 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:2:5:2:14 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:2:5:2:14 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:2:10:2:14 | "foo" | calls.rb:1:1:667:52 | calls.rb | @@ -579,6 +580,7 @@ enclosingModule | calls.rb:5:1:5:3 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:7:1:9:3 | bar | calls.rb:1:1:667:52 | calls.rb | | calls.rb:7:5:7:8 | self | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:8:5:8:15 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:8:5:8:15 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:8:5:8:15 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:8:10:8:15 | "bar1" | calls.rb:1:1:667:52 | calls.rb | @@ -587,6 +589,7 @@ enclosingModule | calls.rb:11:1:11:8 | call to bar | calls.rb:1:1:667:52 | calls.rb | | calls.rb:13:1:15:3 | bar | calls.rb:1:1:667:52 | calls.rb | | calls.rb:13:5:13:8 | self | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:14:5:14:15 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:14:5:14:15 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:14:5:14:15 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:14:10:14:15 | "bar2" | calls.rb:1:1:667:52 | calls.rb | @@ -599,10 +602,12 @@ enclosingModule | calls.rb:22:5:24:7 | instance_m | calls.rb:21:1:34:3 | M | | calls.rb:23:9:23:19 | call to singleton_m | calls.rb:21:1:34:3 | M | | calls.rb:23:9:23:19 | self | calls.rb:21:1:34:3 | M | +| calls.rb:23:9:23:35 | ... | calls.rb:21:1:34:3 | M | | calls.rb:25:5:27:7 | singleton_m | calls.rb:21:1:34:3 | M | | calls.rb:25:9:25:12 | self | calls.rb:21:1:34:3 | M | | calls.rb:26:9:26:18 | call to instance_m | calls.rb:21:1:34:3 | M | | calls.rb:26:9:26:18 | self | calls.rb:21:1:34:3 | M | +| calls.rb:26:9:26:34 | ... | calls.rb:21:1:34:3 | M | | calls.rb:29:5:29:14 | call to instance_m | calls.rb:21:1:34:3 | M | | calls.rb:29:5:29:14 | self | calls.rb:21:1:34:3 | M | | calls.rb:30:5:30:8 | self | calls.rb:21:1:34:3 | M | @@ -618,6 +623,7 @@ enclosingModule | calls.rb:39:1:41:3 | call_instance_m | calls.rb:1:1:667:52 | calls.rb | | calls.rb:40:5:40:14 | call to instance_m | calls.rb:1:1:667:52 | calls.rb | | calls.rb:40:5:40:14 | self | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:40:5:40:30 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:43:1:58:3 | C | calls.rb:1:1:667:52 | calls.rb | | calls.rb:44:5:44:13 | call to include | calls.rb:43:1:58:3 | C | | calls.rb:44:5:44:13 | self | calls.rb:43:1:58:3 | C | @@ -633,6 +639,7 @@ enclosingModule | calls.rb:51:5:57:7 | baz | calls.rb:43:1:58:3 | C | | calls.rb:52:9:52:18 | call to instance_m | calls.rb:43:1:58:3 | C | | calls.rb:52:9:52:18 | self | calls.rb:43:1:58:3 | C | +| calls.rb:52:9:56:40 | ... | calls.rb:43:1:58:3 | C | | calls.rb:53:9:53:12 | self | calls.rb:43:1:58:3 | C | | calls.rb:53:9:53:23 | call to instance_m | calls.rb:43:1:58:3 | C | | calls.rb:55:9:55:19 | call to singleton_m | calls.rb:43:1:58:3 | C | @@ -652,6 +659,7 @@ enclosingModule | calls.rb:65:1:69:3 | D | calls.rb:1:1:667:52 | calls.rb | | calls.rb:65:11:65:11 | C | calls.rb:1:1:667:52 | calls.rb | | calls.rb:66:5:68:7 | baz | calls.rb:65:1:69:3 | D | +| calls.rb:67:9:67:13 | ... | calls.rb:65:1:69:3 | D | | calls.rb:67:9:67:13 | super call to baz | calls.rb:65:1:69:3 | D | | calls.rb:71:1:71:1 | d | calls.rb:1:1:667:52 | calls.rb | | calls.rb:71:1:71:9 | ... = ... | calls.rb:1:1:667:52 | calls.rb | @@ -672,14 +680,17 @@ enclosingModule | calls.rb:76:28:76:28 | 5 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:77:5:77:5 | a | calls.rb:1:1:667:52 | calls.rb | | calls.rb:77:5:77:16 | call to bit_length | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:77:5:78:16 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:78:5:78:5 | b | calls.rb:1:1:667:52 | calls.rb | | calls.rb:78:5:78:16 | call to bit_length | calls.rb:1:1:667:52 | calls.rb | | calls.rb:81:1:83:3 | call_block | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:82:5:82:11 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:82:5:82:11 | yield ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:82:11:82:11 | 1 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:85:1:89:3 | foo | calls.rb:1:1:667:52 | calls.rb | | calls.rb:86:5:86:7 | var | calls.rb:1:1:667:52 | calls.rb | | calls.rb:86:5:86:18 | ... = ... | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:86:5:88:29 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:86:11:86:14 | Hash | calls.rb:1:1:667:52 | calls.rb | | calls.rb:86:11:86:18 | call to new | calls.rb:1:1:667:52 | calls.rb | | calls.rb:87:5:87:7 | var | calls.rb:1:1:667:52 | calls.rb | @@ -691,6 +702,7 @@ enclosingModule | calls.rb:88:19:88:19 | x | calls.rb:1:1:667:52 | calls.rb | | calls.rb:88:19:88:19 | x | calls.rb:1:1:667:52 | calls.rb | | calls.rb:88:22:88:24 | var | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:88:22:88:27 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:88:22:88:27 | ...[...] | calls.rb:1:1:667:52 | calls.rb | | calls.rb:88:26:88:26 | x | calls.rb:1:1:667:52 | calls.rb | | calls.rb:91:1:94:3 | Integer | calls.rb:1:1:667:52 | calls.rb | @@ -707,6 +719,7 @@ enclosingModule | calls.rb:102:5:102:30 | puts | calls.rb:100:1:103:3 | Kernel | | calls.rb:102:14:102:14 | x | calls.rb:100:1:103:3 | Kernel | | calls.rb:102:14:102:14 | x | calls.rb:100:1:103:3 | Kernel | +| calls.rb:102:17:102:26 | ... | calls.rb:100:1:103:3 | Kernel | | calls.rb:102:17:102:26 | call to old_puts | calls.rb:100:1:103:3 | Kernel | | calls.rb:102:17:102:26 | self | calls.rb:100:1:103:3 | Kernel | | calls.rb:102:26:102:26 | x | calls.rb:100:1:103:3 | Kernel | @@ -720,6 +733,7 @@ enclosingModule | calls.rb:108:5:110:7 | include | calls.rb:105:1:113:3 | Module | | calls.rb:108:17:108:17 | x | calls.rb:105:1:113:3 | Module | | calls.rb:108:17:108:17 | x | calls.rb:105:1:113:3 | Module | +| calls.rb:109:9:109:21 | ... | calls.rb:105:1:113:3 | Module | | calls.rb:109:9:109:21 | call to old_include | calls.rb:105:1:113:3 | Module | | calls.rb:109:9:109:21 | self | calls.rb:105:1:113:3 | Module | | calls.rb:109:21:109:21 | x | calls.rb:105:1:113:3 | Module | @@ -740,6 +754,7 @@ enclosingModule | calls.rb:122:5:122:31 | [] | calls.rb:120:1:123:3 | Hash | | calls.rb:122:12:122:12 | x | calls.rb:120:1:123:3 | Hash | | calls.rb:122:12:122:12 | x | calls.rb:120:1:123:3 | Hash | +| calls.rb:122:15:122:27 | ... | calls.rb:120:1:123:3 | Hash | | calls.rb:122:15:122:27 | call to old_lookup | calls.rb:120:1:123:3 | Hash | | calls.rb:122:15:122:27 | self | calls.rb:120:1:123:3 | Hash | | calls.rb:122:26:122:26 | x | calls.rb:120:1:123:3 | Hash | @@ -752,6 +767,7 @@ enclosingModule | calls.rb:127:3:127:29 | [] | calls.rb:125:1:138:3 | Array | | calls.rb:127:10:127:10 | x | calls.rb:125:1:138:3 | Array | | calls.rb:127:10:127:10 | x | calls.rb:125:1:138:3 | Array | +| calls.rb:127:13:127:25 | ... | calls.rb:125:1:138:3 | Array | | calls.rb:127:13:127:25 | call to old_lookup | calls.rb:125:1:138:3 | Array | | calls.rb:127:13:127:25 | self | calls.rb:125:1:138:3 | Array | | calls.rb:127:24:127:24 | x | calls.rb:125:1:138:3 | Array | @@ -761,6 +777,7 @@ enclosingModule | calls.rb:131:16:131:19 | body | calls.rb:125:1:138:3 | Array | | calls.rb:132:5:132:5 | x | calls.rb:125:1:138:3 | Array | | calls.rb:132:5:132:9 | ... = ... | calls.rb:125:1:138:3 | Array | +| calls.rb:132:5:136:7 | ... | calls.rb:125:1:138:3 | Array | | calls.rb:132:9:132:9 | 0 | calls.rb:125:1:138:3 | Array | | calls.rb:133:5:136:7 | while ... | calls.rb:125:1:138:3 | Array | | calls.rb:133:11:133:11 | x | calls.rb:125:1:138:3 | Array | @@ -780,6 +797,7 @@ enclosingModule | calls.rb:135:11:135:12 | ... + ... | calls.rb:125:1:138:3 | Array | | calls.rb:135:14:135:14 | 1 | calls.rb:125:1:138:3 | Array | | calls.rb:140:1:142:3 | funny | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:141:5:141:20 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:141:5:141:20 | yield ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:141:11:141:20 | "prefix: " | calls.rb:1:1:667:52 | calls.rb | | calls.rb:141:12:141:19 | prefix: | calls.rb:1:1:667:52 | calls.rb | @@ -788,6 +806,7 @@ enclosingModule | calls.rb:144:7:144:30 | { ... } | calls.rb:1:1:667:52 | calls.rb | | calls.rb:144:10:144:10 | i | calls.rb:1:1:667:52 | calls.rb | | calls.rb:144:10:144:10 | i | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:144:13:144:29 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:144:13:144:29 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:144:13:144:29 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:144:18:144:18 | i | calls.rb:1:1:667:52 | calls.rb | @@ -814,6 +833,7 @@ enclosingModule | calls.rb:150:26:150:26 | i | calls.rb:1:1:667:52 | calls.rb | | calls.rb:150:29:150:29 | v | calls.rb:1:1:667:52 | calls.rb | | calls.rb:150:29:150:29 | v | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:150:32:150:61 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:150:32:150:61 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:150:32:150:61 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:150:37:150:61 | "#{...} -> #{...}" | calls.rb:1:1:667:52 | calls.rb | @@ -834,6 +854,7 @@ enclosingModule | calls.rb:152:20:152:20 | i | calls.rb:1:1:667:52 | calls.rb | | calls.rb:152:20:152:20 | i | calls.rb:1:1:667:52 | calls.rb | | calls.rb:152:23:152:23 | i | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:152:23:152:34 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:152:23:152:34 | call to bit_length | calls.rb:1:1:667:52 | calls.rb | | calls.rb:154:1:154:7 | Array | calls.rb:1:1:667:52 | calls.rb | | calls.rb:154:1:154:7 | [...] | calls.rb:1:1:667:52 | calls.rb | @@ -845,6 +866,7 @@ enclosingModule | calls.rb:154:17:154:40 | { ... } | calls.rb:1:1:667:52 | calls.rb | | calls.rb:154:20:154:20 | i | calls.rb:1:1:667:52 | calls.rb | | calls.rb:154:20:154:20 | i | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:154:23:154:39 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:154:23:154:39 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:154:23:154:39 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:154:28:154:28 | i | calls.rb:1:1:667:52 | calls.rb | @@ -862,6 +884,7 @@ enclosingModule | calls.rb:156:21:156:21 | _ | calls.rb:1:1:667:52 | calls.rb | | calls.rb:156:24:156:24 | v | calls.rb:1:1:667:52 | calls.rb | | calls.rb:156:24:156:24 | v | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:156:27:156:36 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:156:27:156:36 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:156:27:156:36 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:156:32:156:32 | v | calls.rb:1:1:667:52 | calls.rb | @@ -869,6 +892,7 @@ enclosingModule | calls.rb:158:1:160:3 | indirect | calls.rb:1:1:667:52 | calls.rb | | calls.rb:158:14:158:15 | &b | calls.rb:1:1:667:52 | calls.rb | | calls.rb:158:15:158:15 | b | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:159:5:159:17 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:159:5:159:17 | call to call_block | calls.rb:1:1:667:52 | calls.rb | | calls.rb:159:5:159:17 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:159:16:159:17 | &... | calls.rb:1:1:667:52 | calls.rb | @@ -879,10 +903,12 @@ enclosingModule | calls.rb:162:13:162:13 | i | calls.rb:1:1:667:52 | calls.rb | | calls.rb:162:13:162:13 | i | calls.rb:1:1:667:52 | calls.rb | | calls.rb:162:16:162:16 | i | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:162:16:162:27 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:162:16:162:27 | call to bit_length | calls.rb:1:1:667:52 | calls.rb | | calls.rb:165:1:169:3 | S | calls.rb:1:1:667:52 | calls.rb | | calls.rb:166:5:168:7 | s_method | calls.rb:165:1:169:3 | S | | calls.rb:167:9:167:12 | self | calls.rb:165:1:169:3 | S | +| calls.rb:167:9:167:17 | ... | calls.rb:165:1:169:3 | S | | calls.rb:167:9:167:17 | call to to_s | calls.rb:165:1:169:3 | S | | calls.rb:171:1:174:3 | A | calls.rb:1:1:667:52 | calls.rb | | calls.rb:171:11:171:11 | S | calls.rb:1:1:667:52 | calls.rb | @@ -907,6 +933,7 @@ enclosingModule | calls.rb:191:9:191:12 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:192:9:192:26 | call to puts | calls.rb:190:1:226:3 | Singletons | | calls.rb:192:9:192:26 | self | calls.rb:190:1:226:3 | Singletons | +| calls.rb:192:9:193:24 | ... | calls.rb:190:1:226:3 | Singletons | | calls.rb:192:14:192:26 | "singleton_a" | calls.rb:190:1:226:3 | Singletons | | calls.rb:192:15:192:25 | singleton_a | calls.rb:190:1:226:3 | Singletons | | calls.rb:193:9:193:12 | self | calls.rb:190:1:226:3 | Singletons | @@ -915,12 +942,14 @@ enclosingModule | calls.rb:196:9:196:12 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:197:9:197:26 | call to puts | calls.rb:190:1:226:3 | Singletons | | calls.rb:197:9:197:26 | self | calls.rb:190:1:226:3 | Singletons | +| calls.rb:197:9:198:24 | ... | calls.rb:190:1:226:3 | Singletons | | calls.rb:197:14:197:26 | "singleton_b" | calls.rb:190:1:226:3 | Singletons | | calls.rb:197:15:197:25 | singleton_b | calls.rb:190:1:226:3 | Singletons | | calls.rb:198:9:198:12 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:198:9:198:24 | call to singleton_c | calls.rb:190:1:226:3 | Singletons | | calls.rb:201:5:203:7 | singleton_c | calls.rb:190:1:226:3 | Singletons | | calls.rb:201:9:201:12 | self | calls.rb:190:1:226:3 | Singletons | +| calls.rb:202:9:202:26 | ... | calls.rb:190:1:226:3 | Singletons | | calls.rb:202:9:202:26 | call to puts | calls.rb:190:1:226:3 | Singletons | | calls.rb:202:9:202:26 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:202:14:202:26 | "singleton_c" | calls.rb:190:1:226:3 | Singletons | @@ -929,13 +958,16 @@ enclosingModule | calls.rb:205:9:205:12 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:206:9:206:26 | call to puts | calls.rb:190:1:226:3 | Singletons | | calls.rb:206:9:206:26 | self | calls.rb:190:1:226:3 | Singletons | +| calls.rb:206:9:207:24 | ... | calls.rb:190:1:226:3 | Singletons | | calls.rb:206:14:206:26 | "singleton_d" | calls.rb:190:1:226:3 | Singletons | | calls.rb:206:15:206:25 | singleton_d | calls.rb:190:1:226:3 | Singletons | | calls.rb:207:9:207:12 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:207:9:207:24 | call to singleton_a | calls.rb:190:1:226:3 | Singletons | | calls.rb:210:5:215:7 | instance | calls.rb:190:1:226:3 | Singletons | | calls.rb:211:9:213:11 | singleton_e | calls.rb:190:1:226:3 | Singletons | +| calls.rb:211:9:214:19 | ... | calls.rb:190:1:226:3 | Singletons | | calls.rb:211:13:211:16 | self | calls.rb:190:1:226:3 | Singletons | +| calls.rb:212:13:212:30 | ... | calls.rb:190:1:226:3 | Singletons | | calls.rb:212:13:212:30 | call to puts | calls.rb:190:1:226:3 | Singletons | | calls.rb:212:13:212:30 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:212:18:212:30 | "singleton_e" | calls.rb:190:1:226:3 | Singletons | @@ -945,12 +977,14 @@ enclosingModule | calls.rb:217:5:221:7 | class << ... | calls.rb:190:1:226:3 | Singletons | | calls.rb:217:14:217:17 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:218:9:220:11 | singleton_f | calls.rb:217:5:221:7 | class << ... | +| calls.rb:219:13:219:30 | ... | calls.rb:217:5:221:7 | class << ... | | calls.rb:219:13:219:30 | call to puts | calls.rb:217:5:221:7 | class << ... | | calls.rb:219:13:219:30 | self | calls.rb:217:5:221:7 | class << ... | | calls.rb:219:18:219:30 | "singleton_f" | calls.rb:217:5:221:7 | class << ... | | calls.rb:219:19:219:29 | singleton_f | calls.rb:217:5:221:7 | class << ... | | calls.rb:223:5:225:7 | call_singleton_g | calls.rb:190:1:226:3 | Singletons | | calls.rb:224:9:224:12 | self | calls.rb:190:1:226:3 | Singletons | +| calls.rb:224:9:224:24 | ... | calls.rb:190:1:226:3 | Singletons | | calls.rb:224:9:224:24 | call to singleton_g | calls.rb:190:1:226:3 | Singletons | | calls.rb:228:1:228:10 | Singletons | calls.rb:1:1:667:52 | calls.rb | | calls.rb:228:1:228:22 | call to singleton_a | calls.rb:1:1:667:52 | calls.rb | @@ -966,6 +1000,7 @@ enclosingModule | calls.rb:234:1:234:14 | call to singleton_e | calls.rb:1:1:667:52 | calls.rb | | calls.rb:236:1:238:3 | singleton_g | calls.rb:1:1:667:52 | calls.rb | | calls.rb:236:5:236:6 | c1 | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:237:5:237:24 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:237:5:237:24 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:237:5:237:24 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:237:10:237:24 | "singleton_g_1" | calls.rb:1:1:667:52 | calls.rb | @@ -976,6 +1011,7 @@ enclosingModule | calls.rb:241:1:241:19 | call to call_singleton_g | calls.rb:1:1:667:52 | calls.rb | | calls.rb:243:1:245:3 | singleton_g | calls.rb:1:1:667:52 | calls.rb | | calls.rb:243:5:243:6 | c1 | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:244:5:244:24 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:244:5:244:24 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:244:5:244:24 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:244:10:244:24 | "singleton_g_2" | calls.rb:1:1:667:52 | calls.rb | @@ -987,6 +1023,7 @@ enclosingModule | calls.rb:250:1:254:3 | class << ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:250:10:250:11 | c1 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:251:5:253:7 | singleton_g | calls.rb:250:1:254:3 | class << ... | +| calls.rb:252:9:252:28 | ... | calls.rb:250:1:254:3 | class << ... | | calls.rb:252:9:252:28 | call to puts | calls.rb:250:1:254:3 | class << ... | | calls.rb:252:9:252:28 | self | calls.rb:250:1:254:3 | class << ... | | calls.rb:252:14:252:28 | "singleton_g_3" | calls.rb:250:1:254:3 | class << ... | @@ -1011,6 +1048,7 @@ enclosingModule | calls.rb:265:7:265:15 | top-level | calls.rb:1:1:667:52 | calls.rb | | calls.rb:267:1:269:3 | singleton_g | calls.rb:1:1:667:52 | calls.rb | | calls.rb:267:5:267:14 | Singletons | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:268:5:268:22 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:268:5:268:22 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:268:5:268:22 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:268:10:268:22 | "singleton_g" | calls.rb:1:1:667:52 | calls.rb | @@ -1035,8 +1073,10 @@ enclosingModule | calls.rb:279:5:279:8 | type | calls.rb:1:1:667:52 | calls.rb | | calls.rb:279:5:279:12 | call to new | calls.rb:1:1:667:52 | calls.rb | | calls.rb:279:5:279:21 | call to instance | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:279:5:285:20 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:281:5:283:7 | singleton_h | calls.rb:1:1:667:52 | calls.rb | | calls.rb:281:9:281:12 | type | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:282:9:282:26 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:282:9:282:26 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:282:9:282:26 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:282:14:282:26 | "singleton_h" | calls.rb:1:1:667:52 | calls.rb | @@ -1054,6 +1094,7 @@ enclosingModule | calls.rb:293:1:297:3 | class << ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:293:10:293:10 | x | calls.rb:1:1:667:52 | calls.rb | | calls.rb:294:5:296:7 | singleton_i | calls.rb:293:1:297:3 | class << ... | +| calls.rb:295:9:295:26 | ... | calls.rb:293:1:297:3 | class << ... | | calls.rb:295:9:295:26 | call to puts | calls.rb:293:1:297:3 | class << ... | | calls.rb:295:9:295:26 | self | calls.rb:293:1:297:3 | class << ... | | calls.rb:295:14:295:26 | "singleton_i" | calls.rb:293:1:297:3 | class << ... | @@ -1065,6 +1106,7 @@ enclosingModule | calls.rb:302:1:306:3 | class << ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:302:10:302:19 | Singletons | calls.rb:1:1:667:52 | calls.rb | | calls.rb:303:5:305:7 | singleton_j | calls.rb:302:1:306:3 | class << ... | +| calls.rb:304:9:304:26 | ... | calls.rb:302:1:306:3 | class << ... | | calls.rb:304:9:304:26 | call to puts | calls.rb:302:1:306:3 | class << ... | | calls.rb:304:9:304:26 | self | calls.rb:302:1:306:3 | class << ... | | calls.rb:304:14:304:26 | "singleton_j" | calls.rb:302:1:306:3 | class << ... | @@ -1075,6 +1117,7 @@ enclosingModule | calls.rb:311:5:314:7 | instance | calls.rb:310:1:321:3 | SelfNew | | calls.rb:312:9:312:31 | call to puts | calls.rb:310:1:321:3 | SelfNew | | calls.rb:312:9:312:31 | self | calls.rb:310:1:321:3 | SelfNew | +| calls.rb:312:9:313:36 | ... | calls.rb:310:1:321:3 | SelfNew | | calls.rb:312:14:312:31 | "SelfNew#instance" | calls.rb:310:1:321:3 | SelfNew | | calls.rb:312:15:312:30 | SelfNew#instance | calls.rb:310:1:321:3 | SelfNew | | calls.rb:313:9:313:11 | call to new | calls.rb:310:1:321:3 | SelfNew | @@ -1084,6 +1127,7 @@ enclosingModule | calls.rb:316:9:316:12 | self | calls.rb:310:1:321:3 | SelfNew | | calls.rb:317:9:317:11 | call to new | calls.rb:310:1:321:3 | SelfNew | | calls.rb:317:9:317:11 | self | calls.rb:310:1:321:3 | SelfNew | +| calls.rb:317:9:317:20 | ... | calls.rb:310:1:321:3 | SelfNew | | calls.rb:317:9:317:20 | call to instance | calls.rb:310:1:321:3 | SelfNew | | calls.rb:320:5:320:7 | call to new | calls.rb:310:1:321:3 | SelfNew | | calls.rb:320:5:320:7 | self | calls.rb:310:1:321:3 | SelfNew | @@ -1092,15 +1136,18 @@ enclosingModule | calls.rb:323:1:323:17 | call to singleton | calls.rb:1:1:667:52 | calls.rb | | calls.rb:325:1:333:3 | C1 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:326:5:328:7 | instance | calls.rb:325:1:333:3 | C1 | +| calls.rb:327:9:327:26 | ... | calls.rb:325:1:333:3 | C1 | | calls.rb:327:9:327:26 | call to puts | calls.rb:325:1:333:3 | C1 | | calls.rb:327:9:327:26 | self | calls.rb:325:1:333:3 | C1 | | calls.rb:327:14:327:26 | "C1#instance" | calls.rb:325:1:333:3 | C1 | | calls.rb:327:15:327:25 | C1#instance | calls.rb:325:1:333:3 | C1 | | calls.rb:330:5:332:7 | return_self | calls.rb:325:1:333:3 | C1 | +| calls.rb:331:9:331:12 | ... | calls.rb:325:1:333:3 | C1 | | calls.rb:331:9:331:12 | self | calls.rb:325:1:333:3 | C1 | | calls.rb:335:1:339:3 | C2 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:335:12:335:13 | C1 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:336:5:338:7 | instance | calls.rb:335:1:339:3 | C2 | +| calls.rb:337:9:337:26 | ... | calls.rb:335:1:339:3 | C2 | | calls.rb:337:9:337:26 | call to puts | calls.rb:335:1:339:3 | C2 | | calls.rb:337:9:337:26 | self | calls.rb:335:1:339:3 | C2 | | calls.rb:337:14:337:26 | "C2#instance" | calls.rb:335:1:339:3 | C2 | @@ -1108,6 +1155,7 @@ enclosingModule | calls.rb:341:1:345:3 | C3 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:341:12:341:13 | C2 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:342:5:344:7 | instance | calls.rb:341:1:345:3 | C3 | +| calls.rb:343:9:343:26 | ... | calls.rb:341:1:345:3 | C3 | | calls.rb:343:9:343:26 | call to puts | calls.rb:341:1:345:3 | C3 | | calls.rb:343:9:343:26 | self | calls.rb:341:1:345:3 | C3 | | calls.rb:343:14:343:26 | "C3#instance" | calls.rb:341:1:345:3 | C3 | @@ -1116,6 +1164,7 @@ enclosingModule | calls.rb:347:22:347:22 | x | calls.rb:1:1:667:52 | calls.rb | | calls.rb:347:22:347:22 | x | calls.rb:1:1:667:52 | calls.rb | | calls.rb:348:5:356:7 | case ... | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:348:5:362:7 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:348:10:348:10 | x | calls.rb:1:1:667:52 | calls.rb | | calls.rb:349:5:350:18 | when ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:349:10:349:11 | C3 | calls.rb:1:1:667:52 | calls.rb | @@ -1182,8 +1231,10 @@ enclosingModule | calls.rb:374:1:378:3 | add_singleton | calls.rb:1:1:667:52 | calls.rb | | calls.rb:374:19:374:19 | x | calls.rb:1:1:667:52 | calls.rb | | calls.rb:374:19:374:19 | x | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:375:5:377:7 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:375:5:377:7 | instance | calls.rb:1:1:667:52 | calls.rb | | calls.rb:375:9:375:9 | x | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:376:9:376:28 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:376:9:376:28 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:376:9:376:28 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:376:14:376:28 | "instance_on x" | calls.rb:1:1:667:52 | calls.rb | @@ -1204,30 +1255,36 @@ enclosingModule | calls.rb:386:5:398:7 | class << ... | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:386:14:386:17 | self | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:387:9:389:11 | singleton1 | calls.rb:386:5:398:7 | class << ... | +| calls.rb:388:13:388:48 | ... | calls.rb:386:5:398:7 | class << ... | | calls.rb:388:13:388:48 | call to puts | calls.rb:386:5:398:7 | class << ... | | calls.rb:388:13:388:48 | self | calls.rb:386:5:398:7 | class << ... | | calls.rb:388:18:388:48 | "SingletonOverride1#singleton1" | calls.rb:386:5:398:7 | class << ... | | calls.rb:388:19:388:47 | SingletonOverride1#singleton1 | calls.rb:386:5:398:7 | class << ... | | calls.rb:391:9:393:11 | call_singleton1 | calls.rb:386:5:398:7 | class << ... | +| calls.rb:392:13:392:22 | ... | calls.rb:386:5:398:7 | class << ... | | calls.rb:392:13:392:22 | call to singleton1 | calls.rb:386:5:398:7 | class << ... | | calls.rb:392:13:392:22 | self | calls.rb:386:5:398:7 | class << ... | | calls.rb:395:9:397:11 | factory | calls.rb:386:5:398:7 | class << ... | | calls.rb:396:13:396:16 | self | calls.rb:386:5:398:7 | class << ... | | calls.rb:396:13:396:20 | call to new | calls.rb:386:5:398:7 | class << ... | +| calls.rb:396:13:396:30 | ... | calls.rb:386:5:398:7 | class << ... | | calls.rb:396:13:396:30 | call to instance1 | calls.rb:386:5:398:7 | class << ... | | calls.rb:400:5:402:7 | singleton2 | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:400:9:400:12 | self | calls.rb:385:1:413:3 | SingletonOverride1 | +| calls.rb:401:9:401:44 | ... | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:401:9:401:44 | call to puts | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:401:9:401:44 | self | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:401:14:401:44 | "SingletonOverride1#singleton2" | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:401:15:401:43 | SingletonOverride1#singleton2 | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:404:5:406:7 | call_singleton2 | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:404:9:404:12 | self | calls.rb:385:1:413:3 | SingletonOverride1 | +| calls.rb:405:9:405:18 | ... | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:405:9:405:18 | call to singleton2 | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:405:9:405:18 | self | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:408:5:408:14 | call to singleton2 | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:408:5:408:14 | self | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:410:5:412:7 | instance1 | calls.rb:385:1:413:3 | SingletonOverride1 | +| calls.rb:411:9:411:43 | ... | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:411:9:411:43 | call to puts | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:411:9:411:43 | self | calls.rb:385:1:413:3 | SingletonOverride1 | | calls.rb:411:14:411:43 | "SingletonOverride1#instance1" | calls.rb:385:1:413:3 | SingletonOverride1 | @@ -1245,17 +1302,20 @@ enclosingModule | calls.rb:421:5:425:7 | class << ... | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:421:14:421:17 | self | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:422:9:424:11 | singleton1 | calls.rb:421:5:425:7 | class << ... | +| calls.rb:423:13:423:48 | ... | calls.rb:421:5:425:7 | class << ... | | calls.rb:423:13:423:48 | call to puts | calls.rb:421:5:425:7 | class << ... | | calls.rb:423:13:423:48 | self | calls.rb:421:5:425:7 | class << ... | | calls.rb:423:18:423:48 | "SingletonOverride2#singleton1" | calls.rb:421:5:425:7 | class << ... | | calls.rb:423:19:423:47 | SingletonOverride2#singleton1 | calls.rb:421:5:425:7 | class << ... | | calls.rb:427:5:429:7 | singleton2 | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:427:9:427:12 | self | calls.rb:420:1:434:3 | SingletonOverride2 | +| calls.rb:428:9:428:44 | ... | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:428:9:428:44 | call to puts | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:428:9:428:44 | self | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:428:14:428:44 | "SingletonOverride2#singleton2" | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:428:15:428:43 | SingletonOverride2#singleton2 | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:431:5:433:7 | instance1 | calls.rb:420:1:434:3 | SingletonOverride2 | +| calls.rb:432:9:432:43 | ... | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:432:9:432:43 | call to puts | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:432:9:432:43 | self | calls.rb:420:1:434:3 | SingletonOverride2 | | calls.rb:432:14:432:43 | "SingletonOverride2#instance1" | calls.rb:420:1:434:3 | SingletonOverride2 | @@ -1276,6 +1336,7 @@ enclosingModule | calls.rb:442:17:442:17 | 0 | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:442:19:445:11 | then ... | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:443:9:445:11 | m1 | calls.rb:441:1:469:3 | ConditionalInstanceMethods | +| calls.rb:444:13:444:48 | ... | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:444:13:444:48 | call to puts | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:444:13:444:48 | self | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:444:18:444:48 | "ConditionalInstanceMethods#m1" | calls.rb:441:1:469:3 | ConditionalInstanceMethods | @@ -1283,14 +1344,17 @@ enclosingModule | calls.rb:448:5:460:7 | m2 | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:449:9:449:44 | call to puts | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:449:9:449:44 | self | calls.rb:441:1:469:3 | ConditionalInstanceMethods | +| calls.rb:449:9:459:10 | ... | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:449:14:449:44 | "ConditionalInstanceMethods#m2" | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:449:15:449:43 | ConditionalInstanceMethods#m2 | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:451:9:457:11 | m3 | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:452:13:452:48 | call to puts | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:452:13:452:48 | self | calls.rb:441:1:469:3 | ConditionalInstanceMethods | +| calls.rb:452:13:456:15 | ... | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:452:18:452:48 | "ConditionalInstanceMethods#m3" | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:452:19:452:47 | ConditionalInstanceMethods#m3 | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:454:13:456:15 | m4 | calls.rb:441:1:469:3 | ConditionalInstanceMethods | +| calls.rb:455:17:455:52 | ... | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:455:17:455:52 | call to puts | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:455:17:455:52 | self | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:455:22:455:52 | "ConditionalInstanceMethods#m4" | calls.rb:441:1:469:3 | ConditionalInstanceMethods | @@ -1308,7 +1372,9 @@ enclosingModule | calls.rb:463:9:467:15 | call to new | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:463:9:467:18 | call to m5 | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:463:19:467:11 | do ... end | calls.rb:441:1:469:3 | ConditionalInstanceMethods | +| calls.rb:464:13:466:15 | ... | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:464:13:466:15 | m5 | calls.rb:441:1:469:3 | ConditionalInstanceMethods | +| calls.rb:465:17:465:40 | ... | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:465:17:465:40 | call to puts | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:465:17:465:40 | self | calls.rb:441:1:469:3 | ConditionalInstanceMethods | | calls.rb:465:22:465:40 | "AnonymousClass#m5" | calls.rb:441:1:469:3 | ConditionalInstanceMethods | @@ -1340,11 +1406,14 @@ enclosingModule | calls.rb:479:5:479:11 | [...] | calls.rb:1:1:667:52 | calls.rb | | calls.rb:479:5:479:11 | call to [] | calls.rb:1:1:667:52 | calls.rb | | calls.rb:479:5:483:7 | call to each | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:479:5:495:7 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:479:6:479:6 | 0 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:479:8:479:8 | 1 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:479:10:479:10 | 2 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:479:18:483:7 | do ... end | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:480:9:482:11 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:480:9:482:11 | foo | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:481:13:481:22 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:481:13:481:22 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:481:13:481:22 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:481:18:481:22 | "foo" | calls.rb:1:1:667:52 | calls.rb | @@ -1354,7 +1423,9 @@ enclosingModule | calls.rb:485:5:489:11 | call to new | calls.rb:1:1:667:52 | calls.rb | | calls.rb:485:5:489:15 | call to bar | calls.rb:1:1:667:52 | calls.rb | | calls.rb:485:15:489:7 | do ... end | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:486:9:488:11 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:486:9:488:11 | bar | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:487:13:487:22 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:487:13:487:22 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:487:13:487:22 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:487:18:487:22 | "bar" | calls.rb:1:1:667:52 | calls.rb | @@ -1369,6 +1440,7 @@ enclosingModule | calls.rb:491:18:495:7 | do ... end | calls.rb:1:1:667:52 | calls.rb | | calls.rb:491:22:491:22 | i | calls.rb:1:1:667:52 | calls.rb | | calls.rb:491:22:491:22 | i | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:492:9:494:11 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:492:9:494:11 | call to define_method | calls.rb:1:1:667:52 | calls.rb | | calls.rb:492:9:494:11 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:492:23:492:32 | "baz_#{...}" | calls.rb:1:1:667:52 | calls.rb | @@ -1376,6 +1448,7 @@ enclosingModule | calls.rb:492:28:492:31 | #{...} | calls.rb:1:1:667:52 | calls.rb | | calls.rb:492:30:492:30 | i | calls.rb:1:1:667:52 | calls.rb | | calls.rb:492:35:494:11 | do ... end | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:493:13:493:27 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:493:13:493:27 | call to puts | calls.rb:1:1:667:52 | calls.rb | | calls.rb:493:13:493:27 | self | calls.rb:1:1:667:52 | calls.rb | | calls.rb:493:18:493:27 | "baz_#{...}" | calls.rb:1:1:667:52 | calls.rb | @@ -1399,6 +1472,7 @@ enclosingModule | calls.rb:502:1:502:33 | call to baz_2 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:504:1:510:3 | ExtendSingletonMethod | calls.rb:1:1:667:52 | calls.rb | | calls.rb:505:5:507:7 | singleton | calls.rb:504:1:510:3 | ExtendSingletonMethod | +| calls.rb:506:9:506:46 | ... | calls.rb:504:1:510:3 | ExtendSingletonMethod | | calls.rb:506:9:506:46 | call to puts | calls.rb:504:1:510:3 | ExtendSingletonMethod | | calls.rb:506:9:506:46 | self | calls.rb:504:1:510:3 | ExtendSingletonMethod | | calls.rb:506:14:506:46 | "ExtendSingletonMethod#singleton" | calls.rb:504:1:510:3 | ExtendSingletonMethod | @@ -1435,6 +1509,7 @@ enclosingModule | calls.rb:534:5:536:7 | call to protected | calls.rb:533:1:537:3 | ProtectedMethodInModule | | calls.rb:534:5:536:7 | self | calls.rb:533:1:537:3 | ProtectedMethodInModule | | calls.rb:534:15:536:7 | foo | calls.rb:533:1:537:3 | ProtectedMethodInModule | +| calls.rb:535:9:535:42 | ... | calls.rb:533:1:537:3 | ProtectedMethodInModule | | calls.rb:535:9:535:42 | call to puts | calls.rb:533:1:537:3 | ProtectedMethodInModule | | calls.rb:535:9:535:42 | self | calls.rb:533:1:537:3 | ProtectedMethodInModule | | calls.rb:535:14:535:42 | "ProtectedMethodInModule#foo" | calls.rb:533:1:537:3 | ProtectedMethodInModule | @@ -1446,6 +1521,7 @@ enclosingModule | calls.rb:542:5:544:7 | call to protected | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:542:5:544:7 | self | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:542:15:544:7 | bar | calls.rb:539:1:552:3 | ProtectedMethods | +| calls.rb:543:9:543:35 | ... | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:543:9:543:35 | call to puts | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:543:9:543:35 | self | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:543:14:543:35 | "ProtectedMethods#bar" | calls.rb:539:1:552:3 | ProtectedMethods | @@ -1453,6 +1529,7 @@ enclosingModule | calls.rb:546:5:551:7 | baz | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:547:9:547:11 | call to foo | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:547:9:547:11 | self | calls.rb:539:1:552:3 | ProtectedMethods | +| calls.rb:547:9:550:32 | ... | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:548:9:548:11 | call to bar | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:548:9:548:11 | self | calls.rb:539:1:552:3 | ProtectedMethods | | calls.rb:549:9:549:24 | ProtectedMethods | calls.rb:539:1:552:3 | ProtectedMethods | @@ -1475,6 +1552,7 @@ enclosingModule | calls.rb:559:5:562:7 | baz | calls.rb:558:1:563:3 | ProtectedMethodsSub | | calls.rb:560:9:560:11 | call to foo | calls.rb:558:1:563:3 | ProtectedMethodsSub | | calls.rb:560:9:560:11 | self | calls.rb:558:1:563:3 | ProtectedMethodsSub | +| calls.rb:560:9:561:35 | ... | calls.rb:558:1:563:3 | ProtectedMethodsSub | | calls.rb:561:9:561:27 | ProtectedMethodsSub | calls.rb:558:1:563:3 | ProtectedMethodsSub | | calls.rb:561:9:561:31 | call to new | calls.rb:558:1:563:3 | ProtectedMethodsSub | | calls.rb:561:9:561:35 | call to foo | calls.rb:558:1:563:3 | ProtectedMethodsSub | @@ -1497,6 +1575,7 @@ enclosingModule | calls.rb:569:17:569:17 | c | calls.rb:1:1:667:52 | calls.rb | | calls.rb:569:17:569:17 | c | calls.rb:1:1:667:52 | calls.rb | | calls.rb:569:20:569:20 | c | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:569:20:569:24 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:569:20:569:24 | call to baz | calls.rb:1:1:667:52 | calls.rb | | calls.rb:570:1:570:13 | Array | calls.rb:1:1:667:52 | calls.rb | | calls.rb:570:1:570:13 | [...] | calls.rb:1:1:667:52 | calls.rb | @@ -1512,6 +1591,7 @@ enclosingModule | calls.rb:570:23:570:23 | s | calls.rb:1:1:667:52 | calls.rb | | calls.rb:570:23:570:23 | s | calls.rb:1:1:667:52 | calls.rb | | calls.rb:570:26:570:26 | s | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:570:26:570:37 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:570:26:570:37 | call to capitalize | calls.rb:1:1:667:52 | calls.rb | | calls.rb:572:1:575:3 | SingletonUpCall_Base | calls.rb:1:1:667:52 | calls.rb | | calls.rb:573:5:574:7 | singleton | calls.rb:572:1:575:3 | SingletonUpCall_Base | @@ -1526,6 +1606,7 @@ enclosingModule | calls.rb:579:9:579:12 | self | calls.rb:576:1:583:3 | SingletonUpCall_Sub | | calls.rb:580:9:580:17 | call to singleton | calls.rb:576:1:583:3 | SingletonUpCall_Sub | | calls.rb:580:9:580:17 | self | calls.rb:576:1:583:3 | SingletonUpCall_Sub | +| calls.rb:580:9:581:35 | ... | calls.rb:576:1:583:3 | SingletonUpCall_Sub | | calls.rb:581:9:581:18 | call to singleton2 | calls.rb:576:1:583:3 | SingletonUpCall_Sub | | calls.rb:581:9:581:18 | self | calls.rb:576:1:583:3 | SingletonUpCall_Sub | | calls.rb:584:1:589:3 | SingletonUpCall_SubSub | calls.rb:1:1:667:52 | calls.rb | @@ -1539,10 +1620,12 @@ enclosingModule | calls.rb:592:9:592:12 | self | calls.rb:591:1:602:3 | SingletonA | | calls.rb:595:5:597:7 | call_singleton1 | calls.rb:591:1:602:3 | SingletonA | | calls.rb:595:9:595:12 | self | calls.rb:591:1:602:3 | SingletonA | +| calls.rb:596:9:596:18 | ... | calls.rb:591:1:602:3 | SingletonA | | calls.rb:596:9:596:18 | call to singleton1 | calls.rb:591:1:602:3 | SingletonA | | calls.rb:596:9:596:18 | self | calls.rb:591:1:602:3 | SingletonA | | calls.rb:599:5:601:7 | call_call_singleton1 | calls.rb:591:1:602:3 | SingletonA | | calls.rb:599:9:599:12 | self | calls.rb:591:1:602:3 | SingletonA | +| calls.rb:600:9:600:23 | ... | calls.rb:591:1:602:3 | SingletonA | | calls.rb:600:9:600:23 | call to call_singleton1 | calls.rb:591:1:602:3 | SingletonA | | calls.rb:600:9:600:23 | self | calls.rb:591:1:602:3 | SingletonA | | calls.rb:604:1:611:3 | SingletonB | calls.rb:1:1:667:52 | calls.rb | @@ -1553,6 +1636,7 @@ enclosingModule | calls.rb:608:9:608:12 | self | calls.rb:604:1:611:3 | SingletonB | | calls.rb:609:9:609:18 | call to singleton1 | calls.rb:604:1:611:3 | SingletonB | | calls.rb:609:9:609:18 | self | calls.rb:604:1:611:3 | SingletonB | +| calls.rb:609:9:609:105 | ... | calls.rb:604:1:611:3 | SingletonB | | calls.rb:613:1:620:3 | SingletonC | calls.rb:1:1:667:52 | calls.rb | | calls.rb:613:20:613:29 | SingletonA | calls.rb:1:1:667:52 | calls.rb | | calls.rb:614:5:615:7 | singleton1 | calls.rb:613:1:620:3 | SingletonC | @@ -1561,6 +1645,7 @@ enclosingModule | calls.rb:617:9:617:12 | self | calls.rb:613:1:620:3 | SingletonC | | calls.rb:618:9:618:18 | call to singleton1 | calls.rb:613:1:620:3 | SingletonC | | calls.rb:618:9:618:18 | self | calls.rb:613:1:620:3 | SingletonC | +| calls.rb:618:9:618:105 | ... | calls.rb:613:1:620:3 | SingletonC | | calls.rb:622:1:622:10 | SingletonA | calls.rb:1:1:667:52 | calls.rb | | calls.rb:622:1:622:31 | call to call_call_singleton1 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:623:1:623:10 | SingletonB | calls.rb:1:1:667:52 | calls.rb | @@ -1570,6 +1655,7 @@ enclosingModule | calls.rb:626:1:632:3 | Included | calls.rb:1:1:667:52 | calls.rb | | calls.rb:627:5:629:7 | foo | calls.rb:626:1:632:3 | Included | | calls.rb:628:9:628:12 | self | calls.rb:626:1:632:3 | Included | +| calls.rb:628:9:628:16 | ... | calls.rb:626:1:632:3 | Included | | calls.rb:628:9:628:16 | call to bar | calls.rb:626:1:632:3 | Included | | calls.rb:630:5:631:7 | bar | calls.rb:626:1:632:3 | Included | | calls.rb:634:1:639:3 | IncludesIncluded | calls.rb:1:1:667:52 | calls.rb | @@ -1577,11 +1663,13 @@ enclosingModule | calls.rb:635:5:635:20 | self | calls.rb:634:1:639:3 | IncludesIncluded | | calls.rb:635:13:635:20 | Included | calls.rb:634:1:639:3 | IncludesIncluded | | calls.rb:636:5:638:7 | bar | calls.rb:634:1:639:3 | IncludesIncluded | +| calls.rb:637:9:637:13 | ... | calls.rb:634:1:639:3 | IncludesIncluded | | calls.rb:637:9:637:13 | super call to bar | calls.rb:634:1:639:3 | IncludesIncluded | | calls.rb:641:1:645:3 | CustomNew1 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:642:5:644:7 | new | calls.rb:641:1:645:3 | CustomNew1 | | calls.rb:642:9:642:12 | self | calls.rb:641:1:645:3 | CustomNew1 | | calls.rb:643:9:643:10 | C1 | calls.rb:641:1:645:3 | CustomNew1 | +| calls.rb:643:9:643:14 | ... | calls.rb:641:1:645:3 | CustomNew1 | | calls.rb:643:9:643:14 | call to new | calls.rb:641:1:645:3 | CustomNew1 | | calls.rb:647:1:647:10 | CustomNew1 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:647:1:647:14 | call to new | calls.rb:1:1:667:52 | calls.rb | @@ -1590,8 +1678,10 @@ enclosingModule | calls.rb:650:5:652:7 | new | calls.rb:649:1:657:3 | CustomNew2 | | calls.rb:650:9:650:12 | self | calls.rb:649:1:657:3 | CustomNew2 | | calls.rb:651:9:651:12 | self | calls.rb:649:1:657:3 | CustomNew2 | +| calls.rb:651:9:651:21 | ... | calls.rb:649:1:657:3 | CustomNew2 | | calls.rb:651:9:651:21 | call to allocate | calls.rb:649:1:657:3 | CustomNew2 | | calls.rb:654:5:656:7 | instance | calls.rb:649:1:657:3 | CustomNew2 | +| calls.rb:655:9:655:34 | ... | calls.rb:649:1:657:3 | CustomNew2 | | calls.rb:655:9:655:34 | call to puts | calls.rb:649:1:657:3 | CustomNew2 | | calls.rb:655:9:655:34 | self | calls.rb:649:1:657:3 | CustomNew2 | | calls.rb:655:14:655:34 | "CustomNew2#instance" | calls.rb:649:1:657:3 | CustomNew2 | @@ -1605,11 +1695,13 @@ enclosingModule | calls.rb:662:5:662:11 | Array | calls.rb:1:1:667:52 | calls.rb | | calls.rb:662:5:662:11 | [...] | calls.rb:1:1:667:52 | calls.rb | | calls.rb:662:5:662:11 | call to [] | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:662:5:664:7 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:662:5:664:7 | call to each | calls.rb:1:1:667:52 | calls.rb | | calls.rb:662:6:662:6 | 0 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:662:8:662:8 | 1 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:662:10:662:10 | 2 | calls.rb:1:1:667:52 | calls.rb | | calls.rb:662:18:664:7 | do ... end | calls.rb:1:1:667:52 | calls.rb | +| calls.rb:663:9:663:9 | ... | calls.rb:1:1:667:52 | calls.rb | | calls.rb:663:9:663:9 | x | calls.rb:1:1:667:52 | calls.rb | | calls.rb:667:1:667:26 | ( ... ) | calls.rb:1:1:667:52 | calls.rb | | calls.rb:667:1:667:35 | call to instance | calls.rb:1:1:667:52 | calls.rb | @@ -1621,6 +1713,7 @@ enclosingModule | element_reference.rb:2:5:4:7 | [] | element_reference.rb:1:1:5:3 | ClassWithElementRef | | element_reference.rb:2:12:2:12 | x | element_reference.rb:1:1:5:3 | ClassWithElementRef | | element_reference.rb:2:12:2:12 | x | element_reference.rb:1:1:5:3 | ClassWithElementRef | +| element_reference.rb:3:9:3:19 | ... | element_reference.rb:1:1:5:3 | ClassWithElementRef | | element_reference.rb:3:9:3:19 | yield ... | element_reference.rb:1:1:5:3 | ClassWithElementRef | | element_reference.rb:3:15:3:15 | x | element_reference.rb:1:1:5:3 | ClassWithElementRef | | element_reference.rb:3:15:3:19 | ... + ... | element_reference.rb:1:1:5:3 | ClassWithElementRef | @@ -1635,6 +1728,7 @@ enclosingModule | element_reference.rb:9:6:9:19 | { ... } | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:9:9:9:9 | x | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:9:9:9:9 | x | element_reference.rb:1:1:13:4 | element_reference.rb | +| element_reference.rb:9:12:9:17 | ... | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:9:12:9:17 | call to puts | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:9:12:9:17 | self | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:9:17:9:17 | x | element_reference.rb:1:1:13:4 | element_reference.rb | @@ -1644,15 +1738,18 @@ enclosingModule | element_reference.rb:11:6:13:3 | do ... end | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:11:10:11:10 | x | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:11:10:11:10 | x | element_reference.rb:1:1:13:4 | element_reference.rb | +| element_reference.rb:12:5:12:10 | ... | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:12:5:12:10 | call to puts | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:12:5:12:10 | self | element_reference.rb:1:1:13:4 | element_reference.rb | | element_reference.rb:12:10:12:10 | x | element_reference.rb:1:1:13:4 | element_reference.rb | | hello.rb:1:1:8:3 | EnglishWords | hello.rb:1:1:22:3 | hello.rb | | hello.rb:2:5:4:7 | hello | hello.rb:1:1:8:3 | EnglishWords | +| hello.rb:3:9:3:22 | ... | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:3:9:3:22 | return | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:3:16:3:22 | "hello" | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:3:17:3:21 | hello | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:5:5:7:7 | world | hello.rb:1:1:8:3 | EnglishWords | +| hello.rb:6:9:6:22 | ... | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:6:9:6:22 | return | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:6:16:6:22 | "world" | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:6:17:6:21 | world | hello.rb:1:1:8:3 | EnglishWords | @@ -1661,12 +1758,14 @@ enclosingModule | hello.rb:12:5:12:24 | self | hello.rb:11:1:16:3 | Greeting | | hello.rb:12:13:12:24 | EnglishWords | hello.rb:11:1:16:3 | Greeting | | hello.rb:13:5:15:7 | message | hello.rb:11:1:16:3 | Greeting | +| hello.rb:14:9:14:20 | ... | hello.rb:11:1:16:3 | Greeting | | hello.rb:14:9:14:20 | return | hello.rb:11:1:16:3 | Greeting | | hello.rb:14:16:14:20 | call to hello | hello.rb:11:1:16:3 | Greeting | | hello.rb:14:16:14:20 | self | hello.rb:11:1:16:3 | Greeting | | hello.rb:18:1:22:3 | HelloWorld | hello.rb:1:1:22:3 | hello.rb | | hello.rb:18:20:18:27 | Greeting | hello.rb:1:1:22:3 | hello.rb | | hello.rb:19:5:21:7 | message | hello.rb:18:1:22:3 | HelloWorld | +| hello.rb:20:9:20:40 | ... | hello.rb:18:1:22:3 | HelloWorld | | hello.rb:20:9:20:40 | return | hello.rb:18:1:22:3 | HelloWorld | | hello.rb:20:16:20:20 | super call to message | hello.rb:18:1:22:3 | HelloWorld | | hello.rb:20:16:20:26 | ... + ... | hello.rb:18:1:22:3 | HelloWorld | @@ -1684,12 +1783,14 @@ enclosingModule | instance_fields.rb:3:9:5:11 | create | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:4:13:4:18 | @field | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:4:13:4:18 | self | instance_fields.rb:2:5:9:7 | class << ... | +| instance_fields.rb:4:13:4:35 | ... | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:4:13:4:35 | ... = ... | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:4:22:4:31 | A_target | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:4:22:4:35 | call to new | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:6:9:8:11 | use | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:7:13:7:18 | @field | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:7:13:7:18 | self | instance_fields.rb:2:5:9:7 | class << ... | +| instance_fields.rb:7:13:7:25 | ... | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:7:13:7:25 | call to target | instance_fields.rb:2:5:9:7 | class << ... | | instance_fields.rb:11:1:14:3 | A_target | instance_fields.rb:1:1:29:4 | instance_fields.rb | | instance_fields.rb:12:5:13:7 | target | instance_fields.rb:11:1:14:3 | A_target | @@ -1699,12 +1800,14 @@ enclosingModule | instance_fields.rb:18:9:20:11 | create | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:19:13:19:18 | @field | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:19:13:19:18 | self | instance_fields.rb:17:5:24:7 | class << ... | +| instance_fields.rb:19:13:19:35 | ... | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:19:13:19:35 | ... = ... | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:19:22:19:31 | B_target | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:19:22:19:35 | call to new | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:21:9:23:11 | use | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:22:13:22:18 | @field | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:22:13:22:18 | self | instance_fields.rb:17:5:24:7 | class << ... | +| instance_fields.rb:22:13:22:25 | ... | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:22:13:22:25 | call to target | instance_fields.rb:17:5:24:7 | class << ... | | instance_fields.rb:26:1:29:3 | B_target | instance_fields.rb:1:1:29:4 | instance_fields.rb | | instance_fields.rb:27:5:28:7 | target | instance_fields.rb:26:1:29:3 | B_target | @@ -1784,6 +1887,7 @@ enclosingModule | modules.rb:90:3:90:8 | Object | modules.rb:88:1:93:3 | IncludeTest | | modules.rb:90:3:90:38 | call to module_eval | modules.rb:88:1:93:3 | IncludeTest | | modules.rb:90:22:90:38 | { ... } | modules.rb:88:1:93:3 | IncludeTest | +| modules.rb:90:24:90:36 | ... | modules.rb:88:1:93:3 | IncludeTest | | modules.rb:90:24:90:36 | call to prepend | modules.rb:88:1:93:3 | IncludeTest | | modules.rb:90:24:90:36 | self | modules.rb:88:1:93:3 | IncludeTest | | modules.rb:90:32:90:36 | Other | modules.rb:88:1:93:3 | IncludeTest | @@ -1908,6 +2012,7 @@ enclosingModule | private.rb:83:3:85:5 | call to private | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:83:3:85:5 | self | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:83:11:85:5 | m1 | private.rb:82:1:94:3 | PrivateOverride1 | +| private.rb:84:7:84:32 | ... | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:84:7:84:32 | call to puts | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:84:7:84:32 | self | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:84:12:84:32 | "PrivateOverride1#m1" | private.rb:82:1:94:3 | PrivateOverride1 | @@ -1915,11 +2020,13 @@ enclosingModule | private.rb:87:3:89:5 | call to private | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:87:3:89:5 | self | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:87:11:89:5 | m2 | private.rb:82:1:94:3 | PrivateOverride1 | +| private.rb:88:7:88:32 | ... | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:88:7:88:32 | call to puts | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:88:7:88:32 | self | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:88:12:88:32 | "PrivateOverride1#m2" | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:88:13:88:31 | PrivateOverride1#m2 | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:91:3:93:5 | call_m1 | private.rb:82:1:94:3 | PrivateOverride1 | +| private.rb:92:7:92:8 | ... | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:92:7:92:8 | call to m1 | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:92:7:92:8 | self | private.rb:82:1:94:3 | PrivateOverride1 | | private.rb:96:1:102:3 | PrivateOverride2 | private.rb:1:1:105:40 | private.rb | @@ -1929,6 +2036,7 @@ enclosingModule | private.rb:97:11:101:5 | m1 | private.rb:96:1:102:3 | PrivateOverride2 | | private.rb:98:7:98:32 | call to puts | private.rb:96:1:102:3 | PrivateOverride2 | | private.rb:98:7:98:32 | self | private.rb:96:1:102:3 | PrivateOverride2 | +| private.rb:98:7:100:45 | ... | private.rb:96:1:102:3 | PrivateOverride2 | | private.rb:98:12:98:32 | "PrivateOverride2#m1" | private.rb:96:1:102:3 | PrivateOverride2 | | private.rb:98:13:98:31 | PrivateOverride2#m1 | private.rb:96:1:102:3 | PrivateOverride2 | | private.rb:99:7:99:8 | call to m2 | private.rb:96:1:102:3 | PrivateOverride2 | @@ -1950,8 +2058,10 @@ enclosingModule | toplevel_self_singleton.rb:8:1:16:3 | self | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:8:14:16:3 | do ... end | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:9:5:11:7 | method_in_block | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | +| toplevel_self_singleton.rb:9:5:15:7 | ... | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:10:9:10:27 | call to ab_singleton_method | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:10:9:10:27 | self | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | +| toplevel_self_singleton.rb:10:9:10:60 | ... | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:12:5:12:7 | obj | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:12:5:12:12 | ... = ... | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:12:9:12:12 | self | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | @@ -1959,6 +2069,7 @@ enclosingModule | toplevel_self_singleton.rb:13:9:13:11 | obj | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:14:9:14:27 | call to ab_singleton_method | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:14:9:14:27 | self | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | +| toplevel_self_singleton.rb:14:9:14:60 | ... | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:18:1:18:8 | MyStruct | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:18:1:22:1 | ... = ... | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:18:12:18:17 | Struct | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | @@ -1968,10 +2079,12 @@ enclosingModule | toplevel_self_singleton.rb:18:29:18:32 | :bar | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:18:29:18:32 | bar | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:18:35:22:1 | { ... } | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | +| toplevel_self_singleton.rb:19:5:21:7 | ... | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:19:5:21:7 | method_in_struct | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:19:9:19:12 | self | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:20:9:20:27 | call to ab_singleton_method | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:20:9:20:27 | self | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | +| toplevel_self_singleton.rb:20:9:20:60 | ... | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:24:1:34:3 | Good | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | | toplevel_self_singleton.rb:25:5:33:7 | class << ... | toplevel_self_singleton.rb:24:1:34:3 | Good | | toplevel_self_singleton.rb:25:14:25:17 | self | toplevel_self_singleton.rb:24:1:34:3 | Good | @@ -1979,6 +2092,7 @@ enclosingModule | toplevel_self_singleton.rb:29:9:32:11 | call_you | toplevel_self_singleton.rb:25:5:33:7 | class << ... | | toplevel_self_singleton.rb:30:13:30:19 | call to call_me | toplevel_self_singleton.rb:25:5:33:7 | class << ... | | toplevel_self_singleton.rb:30:13:30:19 | self | toplevel_self_singleton.rb:25:5:33:7 | class << ... | +| toplevel_self_singleton.rb:30:13:31:20 | ... | toplevel_self_singleton.rb:25:5:33:7 | class << ... | | toplevel_self_singleton.rb:31:13:31:20 | call to call_you | toplevel_self_singleton.rb:25:5:33:7 | class << ... | | toplevel_self_singleton.rb:31:13:31:20 | self | toplevel_self_singleton.rb:25:5:33:7 | class << ... | | unresolved_subclass.rb:1:1:2:3 | ResolvableBaseClass | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | From 44a914e40fb111008169c1b8c4d0fc01dcb3cbd4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 25 May 2026 10:23:26 +0000 Subject: [PATCH 097/226] Release preparation for version 2.25.6 --- actions/ql/lib/CHANGELOG.md | 6 ++++++ .../0.4.37.md} | 9 +++++---- actions/ql/lib/codeql-pack.release.yml | 2 +- actions/ql/lib/qlpack.yml | 2 +- actions/ql/src/CHANGELOG.md | 19 +++++++++++++++++++ .../2026-05-05-untrusted-checkout-high.md | 4 ---- .../2026-05-12-sha256-pinned-actions.md | 4 ---- ...n-untrusted-checkout-improvements-alert.md | 4 ---- ...ntrusted-checkout-improvements-helpfile.md | 4 ---- ...ntrusted-checkout-improvements-metadata.md | 4 ---- .../ql/src/change-notes/released/0.6.29.md | 18 ++++++++++++++++++ actions/ql/src/codeql-pack.release.yml | 2 +- actions/ql/src/qlpack.yml | 2 +- cpp/ql/lib/CHANGELOG.md | 16 ++++++++++++++++ .../change-notes/2026-05-15-secure-scanf.md | 5 ----- .../change-notes/2026-05-16-alias-template.md | 4 ---- .../lib/change-notes/2026-05-18-alias-type.md | 4 ---- .../change-notes/2026-05-21-generated-from.md | 4 ---- cpp/ql/lib/change-notes/released/10.2.0.md | 15 +++++++++++++++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 4 ++++ cpp/ql/src/change-notes/released/1.6.4.md | 3 +++ cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++++ .../lib/change-notes/released/1.7.68.md | 3 +++ .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++++ .../src/change-notes/released/1.7.68.md | 3 +++ .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 7 +++++++ .../2026-05-12-user-increment-decrement.md | 4 ---- .../6.0.2.md} | 8 +++++--- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 4 ++++ csharp/ql/src/change-notes/released/1.7.4.md | 3 +++ csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.51.md | 3 +++ .../codeql-pack.release.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 4 ++++ go/ql/lib/change-notes/released/7.1.2.md | 3 +++ go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ++++ go/ql/src/change-notes/released/1.6.4.md | 3 +++ go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 6 ++++++ .../9.1.2.md} | 7 ++++--- java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 4 ++++ java/ql/src/change-notes/released/1.11.4.md | 3 +++ java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 6 ++++++ .../2.7.2.md} | 7 ++++--- javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 4 ++++ .../ql/src/change-notes/released/2.3.11.md | 3 +++ javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.51.md | 3 +++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 6 ++++++ .../7.1.2.md} | 7 ++++--- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ++++ python/ql/src/change-notes/released/1.8.4.md | 3 +++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 4 ++++ ruby/ql/lib/change-notes/released/5.2.2.md | 3 +++ ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ++++ ruby/ql/src/change-notes/released/1.6.4.md | 3 +++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- rust/ql/lib/CHANGELOG.md | 6 ++++++ .../0.2.15.md} | 7 ++++--- rust/ql/lib/codeql-pack.release.yml | 2 +- rust/ql/lib/qlpack.yml | 2 +- rust/ql/src/CHANGELOG.md | 4 ++++ rust/ql/src/change-notes/released/0.1.36.md | 3 +++ rust/ql/src/codeql-pack.release.yml | 2 +- rust/ql/src/qlpack.yml | 2 +- shared/concepts/CHANGELOG.md | 4 ++++ .../concepts/change-notes/released/0.0.25.md | 3 +++ shared/concepts/codeql-pack.release.yml | 2 +- shared/concepts/qlpack.yml | 2 +- shared/controlflow/CHANGELOG.md | 4 ++++ .../change-notes/released/2.0.35.md | 3 +++ shared/controlflow/codeql-pack.release.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/CHANGELOG.md | 4 ++++ .../dataflow/change-notes/released/2.1.7.md | 3 +++ shared/dataflow/codeql-pack.release.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/CHANGELOG.md | 4 ++++ shared/mad/change-notes/released/1.0.51.md | 3 +++ shared/mad/codeql-pack.release.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/quantum/CHANGELOG.md | 4 ++++ .../quantum/change-notes/released/0.0.29.md | 3 +++ shared/quantum/codeql-pack.release.yml | 2 +- shared/quantum/qlpack.yml | 2 +- shared/rangeanalysis/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.51.md | 3 +++ shared/rangeanalysis/codeql-pack.release.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ++++ shared/regex/change-notes/released/1.0.51.md | 3 +++ shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++++ shared/ssa/change-notes/released/2.0.27.md | 3 +++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.51.md | 3 +++ shared/threat-models/codeql-pack.release.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ++++ .../tutorial/change-notes/released/1.0.51.md | 3 +++ shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/CHANGELOG.md | 4 ++++ .../typeflow/change-notes/released/1.0.51.md | 3 +++ shared/typeflow/codeql-pack.release.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typeinference/CHANGELOG.md | 4 ++++ .../change-notes/released/0.0.32.md | 3 +++ shared/typeinference/codeql-pack.release.yml | 2 +- shared/typeinference/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ++++ .../change-notes/released/2.0.35.md | 3 +++ shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++++ shared/typos/change-notes/released/1.0.51.md | 3 +++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 4 ++++ shared/util/change-notes/released/2.0.38.md | 3 +++ shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/CHANGELOG.md | 4 ++++ shared/xml/change-notes/released/1.0.51.md | 3 +++ shared/xml/codeql-pack.release.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ++++ shared/yaml/change-notes/released/1.0.51.md | 3 +++ shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/CHANGELOG.md | 10 ++++++++++ .../change-notes/2026-05-19-swift-6.3.2.md | 4 ---- .../6.7.0.md} | 11 ++++++++--- swift/ql/lib/codeql-pack.release.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/CHANGELOG.md | 4 ++++ swift/ql/src/change-notes/released/1.3.4.md | 3 +++ swift/ql/src/codeql-pack.release.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 175 files changed, 455 insertions(+), 149 deletions(-) rename actions/ql/lib/change-notes/{2026-05-12-improved-alphanumeric-regex.md => released/0.4.37.md} (80%) delete mode 100644 actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md delete mode 100644 actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md delete mode 100644 actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md delete mode 100644 actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md delete mode 100644 actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md create mode 100644 actions/ql/src/change-notes/released/0.6.29.md delete mode 100644 cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md delete mode 100644 cpp/ql/lib/change-notes/2026-05-16-alias-template.md delete mode 100644 cpp/ql/lib/change-notes/2026-05-18-alias-type.md delete mode 100644 cpp/ql/lib/change-notes/2026-05-21-generated-from.md create mode 100644 cpp/ql/lib/change-notes/released/10.2.0.md create mode 100644 cpp/ql/src/change-notes/released/1.6.4.md create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md delete mode 100644 csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md rename csharp/ql/lib/change-notes/{2026-05-20-csharp14-dotnet10.md => released/6.0.2.md} (67%) create mode 100644 csharp/ql/src/change-notes/released/1.7.4.md create mode 100644 go/ql/consistency-queries/change-notes/released/1.0.51.md create mode 100644 go/ql/lib/change-notes/released/7.1.2.md create mode 100644 go/ql/src/change-notes/released/1.6.4.md rename java/ql/lib/change-notes/{2026-05-19-avro-mads.md => released/9.1.2.md} (61%) create mode 100644 java/ql/src/change-notes/released/1.11.4.md rename javascript/ql/lib/change-notes/{2026-05-14-sensitive-data.md => released/2.7.2.md} (89%) create mode 100644 javascript/ql/src/change-notes/released/2.3.11.md create mode 100644 misc/suite-helpers/change-notes/released/1.0.51.md rename python/ql/lib/change-notes/{2026-05-14-sensitive-data.md => released/7.1.2.md} (90%) create mode 100644 python/ql/src/change-notes/released/1.8.4.md create mode 100644 ruby/ql/lib/change-notes/released/5.2.2.md create mode 100644 ruby/ql/src/change-notes/released/1.6.4.md rename rust/ql/lib/change-notes/{2026-05-14-sensitive-data.md => released/0.2.15.md} (89%) create mode 100644 rust/ql/src/change-notes/released/0.1.36.md create mode 100644 shared/concepts/change-notes/released/0.0.25.md create mode 100644 shared/controlflow/change-notes/released/2.0.35.md create mode 100644 shared/dataflow/change-notes/released/2.1.7.md create mode 100644 shared/mad/change-notes/released/1.0.51.md create mode 100644 shared/quantum/change-notes/released/0.0.29.md create mode 100644 shared/rangeanalysis/change-notes/released/1.0.51.md create mode 100644 shared/regex/change-notes/released/1.0.51.md create mode 100644 shared/ssa/change-notes/released/2.0.27.md create mode 100644 shared/threat-models/change-notes/released/1.0.51.md create mode 100644 shared/tutorial/change-notes/released/1.0.51.md create mode 100644 shared/typeflow/change-notes/released/1.0.51.md create mode 100644 shared/typeinference/change-notes/released/0.0.32.md create mode 100644 shared/typetracking/change-notes/released/2.0.35.md create mode 100644 shared/typos/change-notes/released/1.0.51.md create mode 100644 shared/util/change-notes/released/2.0.38.md create mode 100644 shared/xml/change-notes/released/1.0.51.md create mode 100644 shared/yaml/change-notes/released/1.0.51.md delete mode 100644 swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md rename swift/ql/lib/change-notes/{2026-05-14-sensitive-data.md => released/6.7.0.md} (76%) create mode 100644 swift/ql/src/change-notes/released/1.3.4.md diff --git a/actions/ql/lib/CHANGELOG.md b/actions/ql/lib/CHANGELOG.md index ddd0b0f1aec..7a61a60c379 100644 --- a/actions/ql/lib/CHANGELOG.md +++ b/actions/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.37 + +### Minor Analysis Improvements + +* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. + ## 0.4.36 ### Minor Analysis Improvements diff --git a/actions/ql/lib/change-notes/2026-05-12-improved-alphanumeric-regex.md b/actions/ql/lib/change-notes/released/0.4.37.md similarity index 80% rename from actions/ql/lib/change-notes/2026-05-12-improved-alphanumeric-regex.md rename to actions/ql/lib/change-notes/released/0.4.37.md index df3aaf3613f..4809796b3ab 100644 --- a/actions/ql/lib/change-notes/2026-05-12-improved-alphanumeric-regex.md +++ b/actions/ql/lib/change-notes/released/0.4.37.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- -* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. \ No newline at end of file +## 0.4.37 + +### Minor Analysis Improvements + +* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. diff --git a/actions/ql/lib/codeql-pack.release.yml b/actions/ql/lib/codeql-pack.release.yml index 45433e3ec03..df274514780 100644 --- a/actions/ql/lib/codeql-pack.release.yml +++ b/actions/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.36 +lastReleaseVersion: 0.4.37 diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml index ae4a57aa944..71c9cadbf28 100644 --- a/actions/ql/lib/qlpack.yml +++ b/actions/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-all -version: 0.4.37-dev +version: 0.4.37 library: true warnOnImplicitThis: true dependencies: diff --git a/actions/ql/src/CHANGELOG.md b/actions/ql/src/CHANGELOG.md index 1670f0af5be..c37cd20761b 100644 --- a/actions/ql/src/CHANGELOG.md +++ b/actions/ql/src/CHANGELOG.md @@ -1,3 +1,22 @@ +## 0.6.29 + +### Query Metadata Changes + +* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`. + +### Major Analysis Improvements + +* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. + +### Minor Analysis Improvements + +* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`. +* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. + +### Bug Fixes + +* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. + ## 0.6.28 ### Query Metadata Changes diff --git a/actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md b/actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md deleted file mode 100644 index 098c60a3753..00000000000 --- a/actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. \ No newline at end of file diff --git a/actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md b/actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md deleted file mode 100644 index 521a5878c37..00000000000 --- a/actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. diff --git a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md deleted file mode 100644 index f5ad3271a62..00000000000 --- a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`. \ No newline at end of file diff --git a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md deleted file mode 100644 index 83e6528c86b..00000000000 --- a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: fix ---- -* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. \ No newline at end of file diff --git a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md deleted file mode 100644 index 5df1f3347ea..00000000000 --- a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: queryMetadata ---- -* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`. \ No newline at end of file diff --git a/actions/ql/src/change-notes/released/0.6.29.md b/actions/ql/src/change-notes/released/0.6.29.md new file mode 100644 index 00000000000..82ca8174954 --- /dev/null +++ b/actions/ql/src/change-notes/released/0.6.29.md @@ -0,0 +1,18 @@ +## 0.6.29 + +### Query Metadata Changes + +* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`. + +### Major Analysis Improvements + +* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. + +### Minor Analysis Improvements + +* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`. +* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. + +### Bug Fixes + +* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. diff --git a/actions/ql/src/codeql-pack.release.yml b/actions/ql/src/codeql-pack.release.yml index 90f3f09295a..e785984cacc 100644 --- a/actions/ql/src/codeql-pack.release.yml +++ b/actions/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.28 +lastReleaseVersion: 0.6.29 diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml index 33ab175fb18..3615c08b583 100644 --- a/actions/ql/src/qlpack.yml +++ b/actions/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-queries -version: 0.6.29-dev +version: 0.6.29 library: false warnOnImplicitThis: true groups: [actions, queries] diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 3b95c10fbb5..0b3413f9d3c 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,19 @@ +## 10.2.0 + +### Deprecated APIs + +* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead. + +### New Features + +* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. +* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. + +### Minor Analysis Improvements + +* Added flow source models for `scanf_s` and related functions. +* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported. + ## 10.1.1 ### Minor Analysis Improvements diff --git a/cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md b/cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md deleted file mode 100644 index 0b8d5a79a72..00000000000 --- a/cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* Added flow source models for `scanf_s` and related functions. -* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2026-05-16-alias-template.md b/cpp/ql/lib/change-notes/2026-05-16-alias-template.md deleted file mode 100644 index 2777da94abf..00000000000 --- a/cpp/ql/lib/change-notes/2026-05-16-alias-template.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. diff --git a/cpp/ql/lib/change-notes/2026-05-18-alias-type.md b/cpp/ql/lib/change-notes/2026-05-18-alias-type.md deleted file mode 100644 index b744dd2fa95..00000000000 --- a/cpp/ql/lib/change-notes/2026-05-18-alias-type.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: deprecated ---- -* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead. diff --git a/cpp/ql/lib/change-notes/2026-05-21-generated-from.md b/cpp/ql/lib/change-notes/2026-05-21-generated-from.md deleted file mode 100644 index bf3ddcb1070..00000000000 --- a/cpp/ql/lib/change-notes/2026-05-21-generated-from.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. diff --git a/cpp/ql/lib/change-notes/released/10.2.0.md b/cpp/ql/lib/change-notes/released/10.2.0.md new file mode 100644 index 00000000000..cb514b82cbb --- /dev/null +++ b/cpp/ql/lib/change-notes/released/10.2.0.md @@ -0,0 +1,15 @@ +## 10.2.0 + +### Deprecated APIs + +* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead. + +### New Features + +* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. +* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. + +### Minor Analysis Improvements + +* Added flow source models for `scanf_s` and related functions. +* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 940a668bbf3..a230efed2a4 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 10.1.1 +lastReleaseVersion: 10.2.0 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index bca102a1048..04ee2d76ae9 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 10.1.2-dev +version: 10.2.0 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 901d2092283..e8a2af1383c 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.4 + +No user-facing changes. + ## 1.6.3 ### Minor Analysis Improvements diff --git a/cpp/ql/src/change-notes/released/1.6.4.md b/cpp/ql/src/change-notes/released/1.6.4.md new file mode 100644 index 00000000000..5c811dc4638 --- /dev/null +++ b/cpp/ql/src/change-notes/released/1.6.4.md @@ -0,0 +1,3 @@ +## 1.6.4 + +No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 00b51441d88..1910e09d6a6 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.3 +lastReleaseVersion: 1.6.4 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 74055b4cf11..4915f969278 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.6.4-dev +version: 1.6.4 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index eefb35f174a..3ceb4374a77 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.68 + +No user-facing changes. + ## 1.7.67 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md new file mode 100644 index 00000000000..774ffcebdfe --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md @@ -0,0 +1,3 @@ +## 1.7.68 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 0293fdade8f..f737dfa0972 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.67 +lastReleaseVersion: 1.7.68 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 659dd5b0038..1de44f9e1d8 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.68-dev +version: 1.7.68 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index eefb35f174a..3ceb4374a77 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.68 + +No user-facing changes. + ## 1.7.67 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md new file mode 100644 index 00000000000..774ffcebdfe --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md @@ -0,0 +1,3 @@ +## 1.7.68 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 0293fdade8f..f737dfa0972 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.67 +lastReleaseVersion: 1.7.68 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index c7f243d86f0..e99c5a26b32 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.68-dev +version: 1.7.68 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 17fd83bcda7..a45a993832e 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 6.0.2 + +### Minor Analysis Improvements + +* Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime. +* C# 14: Added support for user-defined instance increment/decrement operators. + ## 6.0.1 No user-facing changes. diff --git a/csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md b/csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md deleted file mode 100644 index a840fdf4fe3..00000000000 --- a/csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* C# 14: Added support for user-defined instance increment/decrement operators. diff --git a/csharp/ql/lib/change-notes/2026-05-20-csharp14-dotnet10.md b/csharp/ql/lib/change-notes/released/6.0.2.md similarity index 67% rename from csharp/ql/lib/change-notes/2026-05-20-csharp14-dotnet10.md rename to csharp/ql/lib/change-notes/released/6.0.2.md index 84e3833860a..ea98fb2257e 100644 --- a/csharp/ql/lib/change-notes/2026-05-20-csharp14-dotnet10.md +++ b/csharp/ql/lib/change-notes/released/6.0.2.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 6.0.2 + +### Minor Analysis Improvements + * Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime. +* C# 14: Added support for user-defined instance increment/decrement operators. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index d1f3c68c812..70437ec53b8 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 6.0.1 +lastReleaseVersion: 6.0.2 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index b3a0dab7303..0745dfdd527 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 6.0.2-dev +version: 6.0.2 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 8c4388fe2bb..5c196df3614 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.4 + +No user-facing changes. + ## 1.7.3 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/1.7.4.md b/csharp/ql/src/change-notes/released/1.7.4.md new file mode 100644 index 00000000000..801ed5f5e71 --- /dev/null +++ b/csharp/ql/src/change-notes/released/1.7.4.md @@ -0,0 +1,3 @@ +## 1.7.4 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 9f9661b1e77..f4f3a4d5120 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.3 +lastReleaseVersion: 1.7.4 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index bfb1852bacb..d9269a9fd1b 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.7.4-dev +version: 1.7.4 groups: - csharp - queries diff --git a/go/ql/consistency-queries/CHANGELOG.md b/go/ql/consistency-queries/CHANGELOG.md index 512a5732ccd..14258018aea 100644 --- a/go/ql/consistency-queries/CHANGELOG.md +++ b/go/ql/consistency-queries/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/go/ql/consistency-queries/change-notes/released/1.0.51.md b/go/ql/consistency-queries/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/go/ql/consistency-queries/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/go/ql/consistency-queries/codeql-pack.release.yml b/go/ql/consistency-queries/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/go/ql/consistency-queries/codeql-pack.release.yml +++ b/go/ql/consistency-queries/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 4c65036e5cf..c07260f76da 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.51-dev +version: 1.0.51 groups: - go - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 54afc3a977b..0d5738ad029 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 7.1.2 + +No user-facing changes. + ## 7.1.1 No user-facing changes. diff --git a/go/ql/lib/change-notes/released/7.1.2.md b/go/ql/lib/change-notes/released/7.1.2.md new file mode 100644 index 00000000000..d55cf91e249 --- /dev/null +++ b/go/ql/lib/change-notes/released/7.1.2.md @@ -0,0 +1,3 @@ +## 7.1.2 + +No user-facing changes. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 8e970df6cae..547681cc440 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.1.1 +lastReleaseVersion: 7.1.2 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index f12cd33e5e0..8a9a9624de5 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 7.1.2-dev +version: 7.1.2 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 84d9ae7de59..c58883ee3c2 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.4 + +No user-facing changes. + ## 1.6.3 No user-facing changes. diff --git a/go/ql/src/change-notes/released/1.6.4.md b/go/ql/src/change-notes/released/1.6.4.md new file mode 100644 index 00000000000..5c811dc4638 --- /dev/null +++ b/go/ql/src/change-notes/released/1.6.4.md @@ -0,0 +1,3 @@ +## 1.6.4 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 00b51441d88..1910e09d6a6 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.3 +lastReleaseVersion: 1.6.4 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 40ad8f32001..601e81ea035 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.6.4-dev +version: 1.6.4 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index a6c0cfc278a..2e702064d7f 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 9.1.2 + +### Minor Analysis Improvements + +* Added LLM-generated source and sink models for `org.apache.avro`. + ## 9.1.1 ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/2026-05-19-avro-mads.md b/java/ql/lib/change-notes/released/9.1.2.md similarity index 61% rename from java/ql/lib/change-notes/2026-05-19-avro-mads.md rename to java/ql/lib/change-notes/released/9.1.2.md index 43368b098b1..c10b69f0fe9 100644 --- a/java/ql/lib/change-notes/2026-05-19-avro-mads.md +++ b/java/ql/lib/change-notes/released/9.1.2.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 9.1.2 + +### Minor Analysis Improvements + * Added LLM-generated source and sink models for `org.apache.avro`. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 02e630d3384..1fd7d868f4e 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 9.1.1 +lastReleaseVersion: 9.1.2 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index aa9a2957362..561ef7db55c 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 9.1.2-dev +version: 9.1.2 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index fbbc339797b..e013e79ce9e 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.11.4 + +No user-facing changes. + ## 1.11.3 ### Minor Analysis Improvements diff --git a/java/ql/src/change-notes/released/1.11.4.md b/java/ql/src/change-notes/released/1.11.4.md new file mode 100644 index 00000000000..3ebd37b0be7 --- /dev/null +++ b/java/ql/src/change-notes/released/1.11.4.md @@ -0,0 +1,3 @@ +## 1.11.4 + +No user-facing changes. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 220561dc648..813a925461f 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.11.3 +lastReleaseVersion: 1.11.4 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 2005542ba0d..cfd8dbc56c8 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.11.4-dev +version: 1.11.4 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index c201b3a4b13..6471aa3fe68 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.7.2 + +### Minor Analysis Improvements + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `js/clear-text-logging`) may find more correct results and fewer false positive results after these changes. + ## 2.7.1 No user-facing changes. diff --git a/javascript/ql/lib/change-notes/2026-05-14-sensitive-data.md b/javascript/ql/lib/change-notes/released/2.7.2.md similarity index 89% rename from javascript/ql/lib/change-notes/2026-05-14-sensitive-data.md rename to javascript/ql/lib/change-notes/released/2.7.2.md index f6e6caed325..9d0eca2cb4e 100644 --- a/javascript/ql/lib/change-notes/2026-05-14-sensitive-data.md +++ b/javascript/ql/lib/change-notes/released/2.7.2.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 2.7.2 + +### Minor Analysis Improvements + * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `js/clear-text-logging`) may find more correct results and fewer false positive results after these changes. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 820fb65a5c7..5160df7b1b7 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.7.1 +lastReleaseVersion: 2.7.2 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 6e8e84b394d..6caebf91399 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.7.2-dev +version: 2.7.2 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 1a69291d145..b3a62befc5e 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.3.11 + +No user-facing changes. + ## 2.3.10 No user-facing changes. diff --git a/javascript/ql/src/change-notes/released/2.3.11.md b/javascript/ql/src/change-notes/released/2.3.11.md new file mode 100644 index 00000000000..31b11998b74 --- /dev/null +++ b/javascript/ql/src/change-notes/released/2.3.11.md @@ -0,0 +1,3 @@ +## 2.3.11 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index a4a2f98d509..5ac091006e8 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.3.10 +lastReleaseVersion: 2.3.11 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index e58cb3d2d94..03a7153c05a 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 2.3.11-dev +version: 2.3.11 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 8e20945c6bf..8f96c9ba8dd 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/1.0.51.md b/misc/suite-helpers/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/misc/suite-helpers/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index fd00605cfd1..a6aeeb719fa 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.51-dev +version: 1.0.51 groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 3d09821803b..3efb4e57482 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 7.1.2 + +### Minor Analysis Improvements + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes. + ## 7.1.1 No user-facing changes. diff --git a/python/ql/lib/change-notes/2026-05-14-sensitive-data.md b/python/ql/lib/change-notes/released/7.1.2.md similarity index 90% rename from python/ql/lib/change-notes/2026-05-14-sensitive-data.md rename to python/ql/lib/change-notes/released/7.1.2.md index 49754de35ce..523a14edfbe 100644 --- a/python/ql/lib/change-notes/2026-05-14-sensitive-data.md +++ b/python/ql/lib/change-notes/released/7.1.2.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 7.1.2 + +### Minor Analysis Improvements + * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 8e970df6cae..547681cc440 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.1.1 +lastReleaseVersion: 7.1.2 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 981ab78ff33..a53a716fbf0 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 7.1.2-dev +version: 7.1.2 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 544b9778d4d..27698f1d3df 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.8.4 + +No user-facing changes. + ## 1.8.3 No user-facing changes. diff --git a/python/ql/src/change-notes/released/1.8.4.md b/python/ql/src/change-notes/released/1.8.4.md new file mode 100644 index 00000000000..9aef6d10d1c --- /dev/null +++ b/python/ql/src/change-notes/released/1.8.4.md @@ -0,0 +1,3 @@ +## 1.8.4 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 8071ef421ab..f2a60cd1327 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.8.3 +lastReleaseVersion: 1.8.4 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 2fc026ff480..afa318334b6 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.8.4-dev +version: 1.8.4 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 07859d0f0e6..d26bfa6f205 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.2.2 + +No user-facing changes. + ## 5.2.1 No user-facing changes. diff --git a/ruby/ql/lib/change-notes/released/5.2.2.md b/ruby/ql/lib/change-notes/released/5.2.2.md new file mode 100644 index 00000000000..22402d6e8fa --- /dev/null +++ b/ruby/ql/lib/change-notes/released/5.2.2.md @@ -0,0 +1,3 @@ +## 5.2.2 + +No user-facing changes. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 1684d0e72a2..e3b1b0c079d 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.2.1 +lastReleaseVersion: 5.2.2 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index df8efbe68de..b36aada4770 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 5.2.2-dev +version: 5.2.2 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index c874059c151..384ca633202 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.4 + +No user-facing changes. + ## 1.6.3 No user-facing changes. diff --git a/ruby/ql/src/change-notes/released/1.6.4.md b/ruby/ql/src/change-notes/released/1.6.4.md new file mode 100644 index 00000000000..5c811dc4638 --- /dev/null +++ b/ruby/ql/src/change-notes/released/1.6.4.md @@ -0,0 +1,3 @@ +## 1.6.4 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 00b51441d88..1910e09d6a6 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.3 +lastReleaseVersion: 1.6.4 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index b68d13e5908..e0c8c6b4c0c 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.6.4-dev +version: 1.6.4 groups: - ruby - queries diff --git a/rust/ql/lib/CHANGELOG.md b/rust/ql/lib/CHANGELOG.md index d85d27d88d6..3651026d737 100644 --- a/rust/ql/lib/CHANGELOG.md +++ b/rust/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.15 + +### Minor Analysis Improvements + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `rust/cleartext-logging`) may find more correct results and fewer false positive results after these changes. + ## 0.2.14 No user-facing changes. diff --git a/rust/ql/lib/change-notes/2026-05-14-sensitive-data.md b/rust/ql/lib/change-notes/released/0.2.15.md similarity index 89% rename from rust/ql/lib/change-notes/2026-05-14-sensitive-data.md rename to rust/ql/lib/change-notes/released/0.2.15.md index 5aa6febd49b..3644126ec1f 100644 --- a/rust/ql/lib/change-notes/2026-05-14-sensitive-data.md +++ b/rust/ql/lib/change-notes/released/0.2.15.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.2.15 + +### Minor Analysis Improvements + * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `rust/cleartext-logging`) may find more correct results and fewer false positive results after these changes. diff --git a/rust/ql/lib/codeql-pack.release.yml b/rust/ql/lib/codeql-pack.release.yml index c53820a76d5..0f574e080e4 100644 --- a/rust/ql/lib/codeql-pack.release.yml +++ b/rust/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 062c2f4e635..49c4dddd4c6 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-all -version: 0.2.15-dev +version: 0.2.15 groups: rust extractor: rust dbscheme: rust.dbscheme diff --git a/rust/ql/src/CHANGELOG.md b/rust/ql/src/CHANGELOG.md index ad1e8ef3bfe..4f4807ff82e 100644 --- a/rust/ql/src/CHANGELOG.md +++ b/rust/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.36 + +No user-facing changes. + ## 0.1.35 No user-facing changes. diff --git a/rust/ql/src/change-notes/released/0.1.36.md b/rust/ql/src/change-notes/released/0.1.36.md new file mode 100644 index 00000000000..8685189c564 --- /dev/null +++ b/rust/ql/src/change-notes/released/0.1.36.md @@ -0,0 +1,3 @@ +## 0.1.36 + +No user-facing changes. diff --git a/rust/ql/src/codeql-pack.release.yml b/rust/ql/src/codeql-pack.release.yml index 6a5806eec2b..270bd27a7aa 100644 --- a/rust/ql/src/codeql-pack.release.yml +++ b/rust/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.35 +lastReleaseVersion: 0.1.36 diff --git a/rust/ql/src/qlpack.yml b/rust/ql/src/qlpack.yml index 67966540de6..853aefb020d 100644 --- a/rust/ql/src/qlpack.yml +++ b/rust/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-queries -version: 0.1.36-dev +version: 0.1.36 groups: - rust - queries diff --git a/shared/concepts/CHANGELOG.md b/shared/concepts/CHANGELOG.md index e2de2975455..787779674f0 100644 --- a/shared/concepts/CHANGELOG.md +++ b/shared/concepts/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.25 + +No user-facing changes. + ## 0.0.24 No user-facing changes. diff --git a/shared/concepts/change-notes/released/0.0.25.md b/shared/concepts/change-notes/released/0.0.25.md new file mode 100644 index 00000000000..e41a9acfa06 --- /dev/null +++ b/shared/concepts/change-notes/released/0.0.25.md @@ -0,0 +1,3 @@ +## 0.0.25 + +No user-facing changes. diff --git a/shared/concepts/codeql-pack.release.yml b/shared/concepts/codeql-pack.release.yml index b956773a07f..6d0e80a50c3 100644 --- a/shared/concepts/codeql-pack.release.yml +++ b/shared/concepts/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.24 +lastReleaseVersion: 0.0.25 diff --git a/shared/concepts/qlpack.yml b/shared/concepts/qlpack.yml index c51537b2228..98ae75ca6ca 100644 --- a/shared/concepts/qlpack.yml +++ b/shared/concepts/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/concepts -version: 0.0.25-dev +version: 0.0.25 groups: shared library: true dependencies: diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index dc02f115c99..8ac7faf2554 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.35 + +No user-facing changes. + ## 2.0.34 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/2.0.35.md b/shared/controlflow/change-notes/released/2.0.35.md new file mode 100644 index 00000000000..526e1fc9f4c --- /dev/null +++ b/shared/controlflow/change-notes/released/2.0.35.md @@ -0,0 +1,3 @@ +## 2.0.35 + +No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index 339a3ce7c57..27eb8ef8ece 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.34 +lastReleaseVersion: 2.0.35 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index e33617ca4f0..a28d74ae749 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 2.0.35-dev +version: 2.0.35 groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index 7ecbeda3b21..b2cf75110ac 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.7 + +No user-facing changes. + ## 2.1.6 No user-facing changes. diff --git a/shared/dataflow/change-notes/released/2.1.7.md b/shared/dataflow/change-notes/released/2.1.7.md new file mode 100644 index 00000000000..af7772169fe --- /dev/null +++ b/shared/dataflow/change-notes/released/2.1.7.md @@ -0,0 +1,3 @@ +## 2.1.7 + +No user-facing changes. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index 1c810b60c4a..cfa57a47251 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.1.6 +lastReleaseVersion: 2.1.7 diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 2058b35be64..6564305a246 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 2.1.7-dev +version: 2.1.7 groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index 964c1bb1d98..6619a18079c 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/mad/change-notes/released/1.0.51.md b/shared/mad/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/mad/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index fb135546a90..c8d8eb47b4a 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/quantum/CHANGELOG.md b/shared/quantum/CHANGELOG.md index 7153b9314b1..c8b656e4f35 100644 --- a/shared/quantum/CHANGELOG.md +++ b/shared/quantum/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.29 + +No user-facing changes. + ## 0.0.28 No user-facing changes. diff --git a/shared/quantum/change-notes/released/0.0.29.md b/shared/quantum/change-notes/released/0.0.29.md new file mode 100644 index 00000000000..4428927c79d --- /dev/null +++ b/shared/quantum/change-notes/released/0.0.29.md @@ -0,0 +1,3 @@ +## 0.0.29 + +No user-facing changes. diff --git a/shared/quantum/codeql-pack.release.yml b/shared/quantum/codeql-pack.release.yml index 3462db7d348..c81f1813120 100644 --- a/shared/quantum/codeql-pack.release.yml +++ b/shared/quantum/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.28 +lastReleaseVersion: 0.0.29 diff --git a/shared/quantum/qlpack.yml b/shared/quantum/qlpack.yml index 951cce392ae..a8d3a71823b 100644 --- a/shared/quantum/qlpack.yml +++ b/shared/quantum/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/quantum -version: 0.0.29-dev +version: 0.0.29 groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/CHANGELOG.md b/shared/rangeanalysis/CHANGELOG.md index e2a893046c9..a400a91f8c9 100644 --- a/shared/rangeanalysis/CHANGELOG.md +++ b/shared/rangeanalysis/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/rangeanalysis/change-notes/released/1.0.51.md b/shared/rangeanalysis/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/rangeanalysis/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/rangeanalysis/codeql-pack.release.yml b/shared/rangeanalysis/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/rangeanalysis/codeql-pack.release.yml +++ b/shared/rangeanalysis/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index 41f319731b0..5ea1c83b182 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index bb83dfc0a1f..c4b7fc6e87f 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/regex/change-notes/released/1.0.51.md b/shared/regex/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/regex/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 198bf43da04..3c01106e9b8 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index f9145f2c88b..9cfe68398b2 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.27 + +No user-facing changes. + ## 2.0.26 No user-facing changes. diff --git a/shared/ssa/change-notes/released/2.0.27.md b/shared/ssa/change-notes/released/2.0.27.md new file mode 100644 index 00000000000..639cf77090e --- /dev/null +++ b/shared/ssa/change-notes/released/2.0.27.md @@ -0,0 +1,3 @@ +## 2.0.27 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index 63d57bef481..a047558f018 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.26 +lastReleaseVersion: 2.0.27 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 5f8de945745..c10e0892660 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 2.0.27-dev +version: 2.0.27 groups: shared library: true dependencies: diff --git a/shared/threat-models/CHANGELOG.md b/shared/threat-models/CHANGELOG.md index 512a5732ccd..14258018aea 100644 --- a/shared/threat-models/CHANGELOG.md +++ b/shared/threat-models/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/threat-models/change-notes/released/1.0.51.md b/shared/threat-models/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/threat-models/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/threat-models/codeql-pack.release.yml b/shared/threat-models/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/threat-models/codeql-pack.release.yml +++ b/shared/threat-models/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index c3ac3656b3a..855242656c8 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.51-dev +version: 1.0.51 library: true groups: shared dataExtensions: diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index c98a035d149..9e78286a1a4 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/1.0.51.md b/shared/tutorial/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/tutorial/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index e68fe7948ff..39bfd9cc21d 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/CHANGELOG.md b/shared/typeflow/CHANGELOG.md index de43834a84e..e9334c9da8d 100644 --- a/shared/typeflow/CHANGELOG.md +++ b/shared/typeflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/typeflow/change-notes/released/1.0.51.md b/shared/typeflow/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/typeflow/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/typeflow/codeql-pack.release.yml b/shared/typeflow/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/typeflow/codeql-pack.release.yml +++ b/shared/typeflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index 482138349ac..f06ea443f79 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/typeinference/CHANGELOG.md b/shared/typeinference/CHANGELOG.md index 3bbb96e59a9..24dc81f3aa2 100644 --- a/shared/typeinference/CHANGELOG.md +++ b/shared/typeinference/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.32 + +No user-facing changes. + ## 0.0.31 No user-facing changes. diff --git a/shared/typeinference/change-notes/released/0.0.32.md b/shared/typeinference/change-notes/released/0.0.32.md new file mode 100644 index 00000000000..c390443f09a --- /dev/null +++ b/shared/typeinference/change-notes/released/0.0.32.md @@ -0,0 +1,3 @@ +## 0.0.32 + +No user-facing changes. diff --git a/shared/typeinference/codeql-pack.release.yml b/shared/typeinference/codeql-pack.release.yml index 54b504d06ec..714fcfc1828 100644 --- a/shared/typeinference/codeql-pack.release.yml +++ b/shared/typeinference/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.31 +lastReleaseVersion: 0.0.32 diff --git a/shared/typeinference/qlpack.yml b/shared/typeinference/qlpack.yml index d7dbeae2e09..ece5dd3b6e8 100644 --- a/shared/typeinference/qlpack.yml +++ b/shared/typeinference/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeinference -version: 0.0.32-dev +version: 0.0.32 groups: shared library: true dependencies: diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index 313862d5bc7..e9b5492b0d8 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.35 + +No user-facing changes. + ## 2.0.34 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/2.0.35.md b/shared/typetracking/change-notes/released/2.0.35.md new file mode 100644 index 00000000000..526e1fc9f4c --- /dev/null +++ b/shared/typetracking/change-notes/released/2.0.35.md @@ -0,0 +1,3 @@ +## 2.0.35 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index 339a3ce7c57..27eb8ef8ece 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.34 +lastReleaseVersion: 2.0.35 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 891f8d0b1b1..bd874407aff 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 2.0.35-dev +version: 2.0.35 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 5838cd3c535..dbafbea9b98 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/typos/change-notes/released/1.0.51.md b/shared/typos/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/typos/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index b4705122b0a..9a2ed996444 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index 24a4f7d09a2..df741ed9d73 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.38 + +No user-facing changes. + ## 2.0.37 No user-facing changes. diff --git a/shared/util/change-notes/released/2.0.38.md b/shared/util/change-notes/released/2.0.38.md new file mode 100644 index 00000000000..0fab2ede165 --- /dev/null +++ b/shared/util/change-notes/released/2.0.38.md @@ -0,0 +1,3 @@ +## 2.0.38 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index 108259a7400..4ec9eb0980c 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.37 +lastReleaseVersion: 2.0.38 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 6190a3b4275..dc654fca261 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.38-dev +version: 2.0.38 groups: shared library: true dependencies: null diff --git a/shared/xml/CHANGELOG.md b/shared/xml/CHANGELOG.md index 96dfbcadf56..685a8032d64 100644 --- a/shared/xml/CHANGELOG.md +++ b/shared/xml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/xml/change-notes/released/1.0.51.md b/shared/xml/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/xml/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/xml/codeql-pack.release.yml b/shared/xml/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/xml/codeql-pack.release.yml +++ b/shared/xml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index c8e51461dae..40cf2695728 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index e006acbeb21..4f57ee07cfa 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/yaml/change-notes/released/1.0.51.md b/shared/yaml/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/yaml/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index c499501ab26..0b4fd245f3b 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index 01461fd5bfe..1eb5afb48e7 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 6.7.0 + +### Major Analysis Improvements + +* Upgraded to allow analysis of Swift 6.3.2. + +### Minor Analysis Improvements + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `swift/cleartext-logging`) may find more correct results and fewer false positive results after these changes. + ## 6.6.0 ### New Features diff --git a/swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md b/swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md deleted file mode 100644 index 530b7187e7a..00000000000 --- a/swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Upgraded to allow analysis of Swift 6.3.2. diff --git a/swift/ql/lib/change-notes/2026-05-14-sensitive-data.md b/swift/ql/lib/change-notes/released/6.7.0.md similarity index 76% rename from swift/ql/lib/change-notes/2026-05-14-sensitive-data.md rename to swift/ql/lib/change-notes/released/6.7.0.md index 70e96a3469c..8d7bf41cc1d 100644 --- a/swift/ql/lib/change-notes/2026-05-14-sensitive-data.md +++ b/swift/ql/lib/change-notes/released/6.7.0.md @@ -1,4 +1,9 @@ ---- -category: minorAnalysis ---- +## 6.7.0 + +### Major Analysis Improvements + +* Upgraded to allow analysis of Swift 6.3.2. + +### Minor Analysis Improvements + * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `swift/cleartext-logging`) may find more correct results and fewer false positive results after these changes. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 4d7f31f2d8e..55a13d309e5 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 6.6.0 +lastReleaseVersion: 6.7.0 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 5e2f7c2942d..f62f77afa0e 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 6.6.1-dev +version: 6.7.0 groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index 4bd8088718a..4e3b53c37b3 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.4 + +No user-facing changes. + ## 1.3.3 No user-facing changes. diff --git a/swift/ql/src/change-notes/released/1.3.4.md b/swift/ql/src/change-notes/released/1.3.4.md new file mode 100644 index 00000000000..5073aca7222 --- /dev/null +++ b/swift/ql/src/change-notes/released/1.3.4.md @@ -0,0 +1,3 @@ +## 1.3.4 + +No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index eb1f7dabc84..8263ddf2c8b 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.3 +lastReleaseVersion: 1.3.4 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index da4df6ae6d9..05710b29874 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.3.4-dev +version: 1.3.4 groups: - swift - queries From 26da373bd46bc03c80c10ea294613936f93f02ee Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 26 May 2026 14:11:36 +0200 Subject: [PATCH 098/226] C#: Update Roslyn and other pinned dependencies. --- csharp/paket.dependencies | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/csharp/paket.dependencies b/csharp/paket.dependencies index 61cb1d3d8d9..19a45cd7530 100644 --- a/csharp/paket.dependencies +++ b/csharp/paket.dependencies @@ -4,7 +4,7 @@ source https://api.nuget.org/v3/index.json # behave like nuget in choosing transitive dependency versions strategy: max -nuget Basic.CompilerLog.Util 0.9.25 +nuget Basic.CompilerLog.Util 0.9.39 nuget Mono.Posix.NETStandard nuget Newtonsoft.Json nuget NuGet.Versioning @@ -12,7 +12,7 @@ nuget xunit nuget xunit.runner.visualstudio nuget xunit.runner.utility nuget Microsoft.NET.Test.Sdk -nuget Microsoft.CodeAnalysis.CSharp 5.0.0 -nuget Microsoft.CodeAnalysis 5.0.0 -nuget Microsoft.Build 18.0.2 +nuget Microsoft.CodeAnalysis.CSharp 5.3.0 +nuget Microsoft.CodeAnalysis 5.3.0 +nuget Microsoft.Build 18.6.3 nuget Microsoft.VisualStudio.SolutionPersistence From 769b1957a56dc843059766952fdbd7ddafbc1f89 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 26 May 2026 14:13:02 +0200 Subject: [PATCH 099/226] C#: Update generated files. --- csharp/paket.lock | 100 ++++++++++++++++++++---------------------- csharp/paket.main.bzl | 31 +++++++------ 2 files changed, 63 insertions(+), 68 deletions(-) diff --git a/csharp/paket.lock b/csharp/paket.lock index 5e114b0d19f..f76a8afa7eb 100644 --- a/csharp/paket.lock +++ b/csharp/paket.lock @@ -3,45 +3,42 @@ STRATEGY: MAX RESTRICTION: == net10.0 NUGET remote: https://api.nuget.org/v3/index.json - Basic.CompilerLog.Util (0.9.25) + Basic.CompilerLog.Util (0.9.39) MessagePack (>= 3.1.4) - Microsoft.Bcl.Memory (>= 9.0.10) + Microsoft.Bcl.Memory (>= 10.0.7) Microsoft.CodeAnalysis (>= 4.8) Microsoft.CodeAnalysis.CSharp (>= 4.8) Microsoft.CodeAnalysis.VisualBasic (>= 4.8) - Microsoft.Extensions.ObjectPool (>= 9.0.10) - MSBuild.StructuredLogger (>= 2.3.71) - NaturalSort.Extension (>= 4.4) - NuGet.Versioning (>= 6.14) + Microsoft.Extensions.ObjectPool (>= 10.0.7) + MSBuild.StructuredLogger (>= 2.3.178) Humanizer.Core (3.0.10) - MessagePack (3.1.4) - MessagePack.Annotations (>= 3.1.4) - MessagePackAnalyzer (>= 3.1.4) + MessagePack (3.1.6) + MessagePack.Annotations (>= 3.1.6) + MessagePackAnalyzer (>= 3.1.6) Microsoft.NET.StringTools (>= 17.11.4) - MessagePack.Annotations (3.1.4) - MessagePackAnalyzer (3.1.4) + MessagePack.Annotations (3.1.6) + MessagePackAnalyzer (3.1.6) Microsoft.Bcl.AsyncInterfaces (10.0.8) Microsoft.Bcl.Memory (10.0.8) - Microsoft.Build (18.0.2) - Microsoft.Build.Framework (>= 18.0.2) - Microsoft.NET.StringTools (>= 18.0.2) - System.Configuration.ConfigurationManager (>= 9.0) - System.Diagnostics.EventLog (>= 9.0) - System.Reflection.MetadataLoadContext (>= 9.0) - System.Security.Cryptography.ProtectedData (>= 9.0.6) - Microsoft.Build.Framework (18.4) - Microsoft.Build.Utilities.Core (18.4) - Microsoft.Build.Framework (>= 18.4) - Microsoft.NET.StringTools (>= 18.4) - System.Configuration.ConfigurationManager (>= 10.0.1) - System.Diagnostics.EventLog (>= 10.0.1) - System.Security.Cryptography.ProtectedData (>= 10.0.1) - Microsoft.CodeAnalysis (5.0) + Microsoft.Build (18.6.3) + Microsoft.Build.Framework (>= 18.6.3) + System.Configuration.ConfigurationManager (>= 10.0.3) + System.Diagnostics.EventLog (>= 10.0.3) + System.Reflection.MetadataLoadContext (>= 10.0.3) + System.Security.Cryptography.ProtectedData (>= 10.0.3) + Microsoft.Build.Framework (18.6.3) + Microsoft.NET.StringTools (>= 18.6.3) + Microsoft.Build.Utilities.Core (18.6.3) + Microsoft.Build.Framework (>= 18.6.3) + System.Configuration.ConfigurationManager (>= 10.0.3) + System.Diagnostics.EventLog (>= 10.0.3) + System.Security.Cryptography.ProtectedData (>= 10.0.3) + Microsoft.CodeAnalysis (5.3) Humanizer.Core (>= 2.14.1) Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.CodeAnalysis.Analyzers (>= 3.11) - Microsoft.CodeAnalysis.CSharp.Workspaces (5.0) - Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.0) + Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1) + Microsoft.CodeAnalysis.CSharp.Workspaces (5.3) + Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.3) System.Buffers (>= 4.6) System.Collections.Immutable (>= 9.0) System.Composition (>= 9.0) @@ -54,36 +51,36 @@ NUGET System.Threading.Channels (>= 8.0) System.Threading.Tasks.Extensions (>= 4.6) Microsoft.CodeAnalysis.Analyzers (5.3) - Microsoft.CodeAnalysis.Common (5.0) - Microsoft.CodeAnalysis.Analyzers (>= 3.11) - Microsoft.CodeAnalysis.CSharp (5.0) - Microsoft.CodeAnalysis.Analyzers (>= 3.11) - Microsoft.CodeAnalysis.Common (5.0) - Microsoft.CodeAnalysis.CSharp.Workspaces (5.0) + Microsoft.CodeAnalysis.Common (5.3) + Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1) + Microsoft.CodeAnalysis.CSharp (5.3) + Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1) + Microsoft.CodeAnalysis.Common (5.3) + Microsoft.CodeAnalysis.CSharp.Workspaces (5.3) Humanizer.Core (>= 2.14.1) - Microsoft.CodeAnalysis.Analyzers (>= 3.11) - Microsoft.CodeAnalysis.Common (5.0) - Microsoft.CodeAnalysis.CSharp (5.0) - Microsoft.CodeAnalysis.Workspaces.Common (5.0) + Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1) + Microsoft.CodeAnalysis.Common (5.3) + Microsoft.CodeAnalysis.CSharp (5.3) + Microsoft.CodeAnalysis.Workspaces.Common (5.3) System.Composition (>= 9.0) - Microsoft.CodeAnalysis.VisualBasic (5.0) - Microsoft.CodeAnalysis.Analyzers (>= 3.11) - Microsoft.CodeAnalysis.Common (5.0) - Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.0) + Microsoft.CodeAnalysis.VisualBasic (5.3) + Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1) + Microsoft.CodeAnalysis.Common (5.3) + Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.3) Humanizer.Core (>= 2.14.1) - Microsoft.CodeAnalysis.Analyzers (>= 3.11) - Microsoft.CodeAnalysis.Common (5.0) - Microsoft.CodeAnalysis.VisualBasic (5.0) - Microsoft.CodeAnalysis.Workspaces.Common (5.0) + Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1) + Microsoft.CodeAnalysis.Common (5.3) + Microsoft.CodeAnalysis.VisualBasic (5.3) + Microsoft.CodeAnalysis.Workspaces.Common (5.3) System.Composition (>= 9.0) - Microsoft.CodeAnalysis.Workspaces.Common (5.0) + Microsoft.CodeAnalysis.Workspaces.Common (5.3) Humanizer.Core (>= 2.14.1) - Microsoft.CodeAnalysis.Analyzers (>= 3.11) - Microsoft.CodeAnalysis.Common (5.0) + Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1) + Microsoft.CodeAnalysis.Common (5.3) System.Composition (>= 9.0) Microsoft.CodeCoverage (18.5.1) Microsoft.Extensions.ObjectPool (10.0.8) - Microsoft.NET.StringTools (18.4) + Microsoft.NET.StringTools (18.6.3) Microsoft.NET.Test.Sdk (18.5.1) Microsoft.CodeCoverage (>= 18.5.1) Microsoft.TestPlatform.TestHost (>= 18.5.1) @@ -97,7 +94,6 @@ NUGET MSBuild.StructuredLogger (2.3.204) Microsoft.Build.Framework (>= 17.5) Microsoft.Build.Utilities.Core (>= 17.5) - NaturalSort.Extension (4.4.1) Newtonsoft.Json (13.0.4) NuGet.Versioning (7.6) System.Buffers (4.6.1) diff --git a/csharp/paket.main.bzl b/csharp/paket.main.bzl index 115b23ac9f1..0c1b1333424 100644 --- a/csharp/paket.main.bzl +++ b/csharp/paket.main.bzl @@ -7,34 +7,33 @@ def main(): nuget_repo( name = "paket.main", packages = [ - {"name": "Basic.CompilerLog.Util", "id": "Basic.CompilerLog.Util", "version": "0.9.25", "sha512": "sha512-AU428QscGy1Z9eM4WqAqlO19pRIyHPZ+K63jgKX+sBWFzVLHMlyc97RVdm8VUAqVVBauS7kwaiA3S1sE/mBr4w==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "net462": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "net47": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "net471": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "net472": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "net48": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "net5.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "net6.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "net7.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "net8.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning"], "net9.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "netcoreapp2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "netcoreapp2.2": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "netcoreapp3.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "netcoreapp3.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"], "netstandard2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "NaturalSort.Extension", "NuGet.Versioning", "System.Buffers"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Basic.CompilerLog.Util", "id": "Basic.CompilerLog.Util", "version": "0.9.39", "sha512": "sha512-/Kqh12aedOvhOPuFDk/yE8HauuxXFuzB8Qt+NxEUopKnxyXtV0uPIVgBU3mLNC1Dj2E5Yhcz1rtECwnu4Tv1eg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net462": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net47": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net471": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net472": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net48": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net5.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net6.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net7.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net8.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "net9.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp2.2": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netcoreapp3.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"], "netstandard2.1": ["MSBuild.StructuredLogger", "MessagePack", "Microsoft.Bcl.Memory", "Microsoft.CodeAnalysis", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.Extensions.ObjectPool", "System.Buffers"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Humanizer.Core", "id": "Humanizer.Core", "version": "3.0.10", "sha512": "sha512-86jRQVvMLU7xxsdHrK87TSqu5kL0lg4EiRjvTBglkrtLw242dMON4vTrFbGKr2CRjqbThBuIpodF2MWbCFKZYA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Collections.Immutable", "System.Memory"], "net462": ["System.Collections.Immutable", "System.Memory"], "net47": ["System.Collections.Immutable", "System.Memory"], "net471": ["System.Collections.Immutable", "System.Memory"], "net472": ["System.Collections.Immutable", "System.Memory"], "net48": ["System.Collections.Immutable", "System.Memory"], "net5.0": ["System.Collections.Immutable", "System.Memory"], "net6.0": ["System.Collections.Immutable", "System.Memory"], "net7.0": ["System.Collections.Immutable", "System.Memory"], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Collections.Immutable", "System.Memory"], "netcoreapp2.1": ["System.Collections.Immutable", "System.Memory"], "netcoreapp2.2": ["System.Collections.Immutable", "System.Memory"], "netcoreapp3.0": ["System.Collections.Immutable", "System.Memory"], "netcoreapp3.1": ["System.Collections.Immutable", "System.Memory"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Collections.Immutable", "System.Memory"], "netstandard2.1": ["System.Collections.Immutable", "System.Memory"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "MessagePack", "id": "MessagePack", "version": "3.1.4", "sha512": "sha512-O0JoklM97ru+Rqr1hGnlCbSAxi8MOk48pwoaT458RzboCHuAkQWTh+Of9MUoN3LE0Cb2tapku0FRPt2hnk+o0g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "net6.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "net7.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "net8.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools"], "net9.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "netcoreapp3.1": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "MessagePack.Annotations", "id": "MessagePack.Annotations", "version": "3.1.4", "sha512": "sha512-kIgD3A0OHs8+VUabMhIJT9ZF4oGHqjCocaRDmERI/Ds2hzJ5q3kcvzn5zI7V3CJ2NlQ4HDI80uh6zCqglwgQCQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "MessagePackAnalyzer", "id": "MessagePackAnalyzer", "version": "3.1.4", "sha512": "sha512-DFlhiA5fia4iK6i0S+L7sYMYmo5XRgWydKxiaxwz7tfcbvIhU7nmG4JzN1D9Y2XCEmLNExvNwTzXVEgURu4GnA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "MessagePack", "id": "MessagePack", "version": "3.1.6", "sha512": "sha512-vkEho7kN4kxlkd238214A0/FGz6DB1Dalexql8CtUpsbtr0DhKmhBLsmZlqc9H6rRiRvG2VJyt+UqUmQxZoqyw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "net6.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "net7.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "net8.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools"], "net9.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "netcoreapp3.1": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Threading.Tasks.Extensions", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["MessagePackAnalyzer", "MessagePack.Annotations", "Microsoft.NET.StringTools", "System.Collections.Immutable"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "MessagePack.Annotations", "id": "MessagePack.Annotations", "version": "3.1.6", "sha512": "sha512-7uF/iFA6NSB5Eo0HijkyEAHPURQC2ESmzoqNFd2bVqu2opQnuvutGYvcZKV91FXQ6YMDhzYvYbIlSTJ/Jru5+Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "MessagePackAnalyzer", "id": "MessagePackAnalyzer", "version": "3.1.6", "sha512": "sha512-eLmNdEFDwLjBiv3/rv/mBtIu18pu9eujlZ8pb0EsbnMzuNyNUp3GJ0WLL0h4qYRW5N41f8zN1N627h/kChe3oA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Microsoft.Bcl.AsyncInterfaces", "id": "Microsoft.Bcl.AsyncInterfaces", "version": "10.0.8", "sha512": "sha512-FzE/KnOmwCmg2KMPjuyevkS5fAzNt2DBLSJs3HsJ+I/CoBSW6i0mighH6ryZ8JHQhNLxMK04X7J8BTt0kEG5/g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Threading.Tasks.Extensions"], "net462": ["System.Threading.Tasks.Extensions"], "net47": ["System.Threading.Tasks.Extensions"], "net471": ["System.Threading.Tasks.Extensions"], "net472": ["System.Threading.Tasks.Extensions"], "net48": ["System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["System.Threading.Tasks.Extensions"], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Threading.Tasks.Extensions"], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Microsoft.Bcl.Memory", "id": "Microsoft.Bcl.Memory", "version": "10.0.8", "sha512": "sha512-Gd9LaF0vnR5noQP7/LPjSKvXw22b51ejGGs/HJHbzNbMOzT1KqGzW2329gP8DKKMj5iYACBKISwl6nDr32WFWA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Runtime.CompilerServices.Unsafe"], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.Build", "id": "Microsoft.Build", "version": "18.0.2", "sha512": "sha512-/rRET3AtEAUTKFDboKvp/GTDxGwU7VBBfwaKeZtzGg+pyqYdvasHeR3ERTuoxSrgJqnu1J23xd4H481IiJFhnA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Configuration.ConfigurationManager", "System.Reflection.MetadataLoadContext", "System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.Build.Framework", "id": "Microsoft.Build.Framework", "version": "18.4.0", "sha512": "sha512-VmOBicA4RSSTO857wrg91S9eOAsfnZLPeZZdXCsffJAZ8zQAMmZjATuin/LZFH21ajS9nPj7GBe+jvFRNzJPhA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe", "System.Memory", "System.Threading.Tasks.Extensions"], "net48": ["System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe", "System.Memory", "System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.Build.Utilities.Core", "id": "Microsoft.Build.Utilities.Core", "version": "18.4.0", "sha512": "sha512-cW8W3/rloKlL12/CjTrPsFIOk7gHr6RsosBk9K6Qi6vSMdibgVLTicymvem+pBWPSQ5EG/m7Uwb7jF3qqJMwog==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Configuration.ConfigurationManager", "System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework"], "net462": ["Microsoft.Build.Framework"], "net47": ["Microsoft.Build.Framework"], "net471": ["Microsoft.Build.Framework"], "net472": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.Build.Framework", "Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.Build.Framework"], "net6.0": ["Microsoft.Build.Framework"], "net7.0": ["Microsoft.Build.Framework"], "net8.0": ["Microsoft.Build.Framework"], "net9.0": ["Microsoft.Build.Framework"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework"], "netcoreapp2.1": ["Microsoft.Build.Framework"], "netcoreapp2.2": ["Microsoft.Build.Framework"], "netcoreapp3.0": ["Microsoft.Build.Framework"], "netcoreapp3.1": ["Microsoft.Build.Framework"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework"], "netstandard2.1": ["Microsoft.Build.Framework"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.CodeAnalysis", "id": "Microsoft.CodeAnalysis", "version": "5.0.0", "sha512": "sha512-ToXzcZLcHA9vT4e1A6jNafAPuTJj4osfqJck562Be8ByvzS78pY9I+SdO5yo2Kwka0lz++hOWypW1Qdf1TtR4w==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net9.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.Build", "id": "Microsoft.Build", "version": "18.6.3", "sha512": "sha512-KC9xCNrucJlKrA0KFXiYUHZI74kNBOaZ/BLHSCm06fS7aoHnlAlRZizti+i4V0AsaJlaIBjtN/Cf6LkcmENi4w==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.Build.Framework", "System.Configuration.ConfigurationManager", "System.Reflection.MetadataLoadContext", "System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["Microsoft.Build.Framework", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.Build.Framework", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Reflection.MetadataLoadContext", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.Build.Framework", "id": "Microsoft.Build.Framework", "version": "18.6.3", "sha512": "sha512-p11xRx05A+bU2oUIsKKuAEOEPyroo2ygUwQVDLAGV3ZkNtHBsQs9RojvRqr+wiql7KPUXv0qbwKcACUpsbbmcA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.NET.StringTools"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe", "System.Memory", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.NET.StringTools", "System.Collections.Immutable", "System.Runtime.CompilerServices.Unsafe", "System.Memory", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["Microsoft.NET.StringTools", "System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.Build.Utilities.Core", "id": "Microsoft.Build.Utilities.Core", "version": "18.6.3", "sha512": "sha512-uB3c5znytjARTsycmhOfnTavdGTYalYWcCtb6RAFqHcXv2y8JxGsdgQQ39n9IqXpt9JyxPSWz2uVuztuG/Oplw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.Build.Framework", "System.Configuration.ConfigurationManager", "System.Diagnostics.EventLog", "System.Security.Cryptography.ProtectedData"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["Microsoft.Build.Framework", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.Build.Framework", "System.Collections.Immutable", "System.Configuration.ConfigurationManager", "System.Memory", "System.Runtime.CompilerServices.Unsafe", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["Microsoft.Build.Framework", "System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.CodeAnalysis", "id": "Microsoft.CodeAnalysis", "version": "5.3.0", "sha512": "sha512-gCuN2a/33HYRrRg4P2LvbgSsUaGP/FSHTaz6FapSaEATYnbXBoiR9Nk/ItHAknc6IQPtodkUYKvX78MkBdoOSg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net9.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.CSharp.Workspaces", "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Microsoft.CodeAnalysis.Analyzers", "id": "Microsoft.CodeAnalysis.Analyzers", "version": "5.3.0", "sha512": "sha512-v9jPlSs/fE7AU2/eZOw5EUzq0JOaWgP+2gghwIP2XbbTv56PZZZsy1QgEiMa3jjO8hR8SN1+NJvG1xxHL2FDgw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.CodeAnalysis.Common", "id": "Microsoft.CodeAnalysis.Common", "version": "5.0.0", "sha512": "sha512-uK5yslTJQ2UznzYlttFuDCa/6KruN1aQW/ZNFFHvK+yyA6q7vZ5o0BSPvLj+Com1/R7wGJ07c2O0lPcbDrmQdw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Analyzers"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net462": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net47": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net471": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net472": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net48": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net5.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net6.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net7.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net8.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Analyzers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netstandard2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.CodeAnalysis.CSharp", "id": "Microsoft.CodeAnalysis.CSharp", "version": "5.0.0", "sha512": "sha512-wwT/CJOQyQ72Ldouy7gjS/3Vi92hbAAoU3Y0e/6mb39+Vp7aXr3PxuBD73U2QrK1zzgTyv3QhvJPrQX0EiWS8Q==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.CodeAnalysis.CSharp.Workspaces", "id": "Microsoft.CodeAnalysis.CSharp.Workspaces", "version": "5.0.0", "sha512": "sha512-Fy0BNxco9b7XC7LKdTgq+Kk62HKapyEM05LN5ua3Nt6PZ4pzfAAh+9Dg/VW4aSflgYoiQw/mjnotgUuM9NP6Kw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Composition"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Composition"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.CodeAnalysis.VisualBasic", "id": "Microsoft.CodeAnalysis.VisualBasic", "version": "5.0.0", "sha512": "sha512-jGrTRyHgUXYd0iH1wF4svuGnB/3kPerq+iIbaLq5XpNv2+3hbZPyyDla+k/Ylpur6+9ZsDoP0ymhribbgXLmYA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "id": "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "version": "5.0.0", "sha512": "sha512-sgWa3mUtCHIfPcSCyKKksrZNlYnmKWeivbZdENrPLTJQXiKXCjFcVYaxRvGBcYeAQES5J63iV03XVviSkJyMqQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Composition"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Composition"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.CodeAnalysis.Workspaces.Common", "id": "Microsoft.CodeAnalysis.Workspaces.Common", "version": "5.0.0", "sha512": "sha512-zbKJyIkFW+2Bx5eQl/IWBLmbPTpo9/UyAbt8vaVTXsoi4EYlXrJftCRZmUsmyQP7pg3qKMiR6czPdUjTadNkhA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "Microsoft.CodeAnalysis.Analyzers"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "Microsoft.CodeAnalysis.Analyzers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.CodeAnalysis.Common", "id": "Microsoft.CodeAnalysis.Common", "version": "5.3.0", "sha512": "sha512-lt42ETYkJrzJrf99jQ9n7xnanR/ETh92o6LX03kTjQKfKFrJGm5/+4OQJyIz8Kj4/ClbeZ3kvxytsyds4jQ5Tg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Analyzers"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net462": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net47": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net471": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net472": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net48": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net5.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net6.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net7.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "net8.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Analyzers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"], "netstandard2.1": ["Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Memory", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions", "System.Buffers", "System.Numerics.Vectors"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.CodeAnalysis.CSharp", "id": "Microsoft.CodeAnalysis.CSharp", "version": "5.3.0", "sha512": "sha512-TD8ulDx0+qjf3oi5gcToiNaxVGzn0rsPN0hCQOq+skYGgugKGLVl8obs0KxrxAOx2xkjySbOcEBumgJ0uhzzgA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.CodeAnalysis.CSharp.Workspaces", "id": "Microsoft.CodeAnalysis.CSharp.Workspaces", "version": "5.3.0", "sha512": "sha512-XwemsUpvFZ8zLvu9QxRdgh4rgoI1WypKHn9D4zrvN5V3p+CSJKmFBS1w09DuBSLe+DIITIu7JQmzmDsHXZow1g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Composition"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Composition"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.CSharp", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.CodeAnalysis.VisualBasic", "id": "Microsoft.CodeAnalysis.VisualBasic", "version": "5.3.0", "sha512": "sha512-0zqIJspSNg8iBDho82FwYt4ajoBRzMEtzdIPs5KBeisxNIBMpZh8CXJED8RY32HCsIOA5tx870xpgPsXOysMqA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "id": "Microsoft.CodeAnalysis.VisualBasic.Workspaces", "version": "5.3.0", "sha512": "sha512-FhpamkHtKiOd/2wlQ4l9K+NQLfAtBniWj2TWjgHp5rY+PNDRsOZpiTVBdrlwRTIR2oe6lz6cKYTxwBKVrPjOzQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Composition"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.CodeAnalysis.Analyzers", "System.Composition"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Microsoft.CodeAnalysis.VisualBasic", "Microsoft.CodeAnalysis.Workspaces.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Composition", "System.IO.Pipelines", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Channels", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.CodeAnalysis.Workspaces.Common", "id": "Microsoft.CodeAnalysis.Workspaces.Common", "version": "5.3.0", "sha512": "sha512-pPJy45QDPFZNUpmgJz7fKL6Tte+CZ7NRw8GyluMBGLRAcwrZNMpWOKkV81MGnkCYOs8UA1b510MrQpevf0iQWw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "Microsoft.CodeAnalysis.Analyzers"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net462": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net47": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net471": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net472": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net48": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net5.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net6.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net7.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "net8.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "System.IO.Pipelines", "Microsoft.CodeAnalysis.Analyzers", "System.Collections.Immutable", "System.Reflection.Metadata"], "net9.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "System.Composition", "Microsoft.CodeAnalysis.Analyzers"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp2.2": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netcoreapp3.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"], "netstandard2.1": ["Microsoft.CodeAnalysis.Common", "Humanizer.Core", "Microsoft.Bcl.AsyncInterfaces", "System.Composition", "System.IO.Pipelines", "System.Threading.Channels", "Microsoft.CodeAnalysis.Analyzers", "System.Buffers", "System.Collections.Immutable", "System.Memory", "System.Numerics.Vectors", "System.Reflection.Metadata", "System.Runtime.CompilerServices.Unsafe", "System.Text.Encoding.CodePages", "System.Threading.Tasks.Extensions"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Microsoft.CodeCoverage", "id": "Microsoft.CodeCoverage", "version": "18.5.1", "sha512": "sha512-BjoX00WuEWNnHFo591eXZIcl3IYm1iln65ub545zWF1o6pHicSHcX2eUBWEJW9W6GA/9cf/ZgJ2XuGOyDdep2A==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Microsoft.Extensions.ObjectPool", "id": "Microsoft.Extensions.ObjectPool", "version": "10.0.8", "sha512": "sha512-XOzhf+i3nZIyqy5sFaEdnNsPOPEYcEz9tL3YIU8RjK3aKIMLPLMaXDCGoOxKeOTN+03Faaz5le8X1RlKsW9rPQ==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "Microsoft.NET.StringTools", "id": "Microsoft.NET.StringTools", "version": "18.4.0", "sha512": "sha512-1II5n0nHfqVnFteNZsg1YLpbNM96P8VcX6UwCtYy4lXFrGNIvPnmfvz1y4ekxGQjHnxDvyphXkqIci9WhKcmBg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, + {"name": "Microsoft.NET.StringTools", "id": "Microsoft.NET.StringTools", "version": "18.6.3", "sha512": "sha512-8RtWydTzV9i25v80XBoNxZDxmxuClq0PVejE2dHfpLhD8jFoEEPP2S+q5oS9HdSKOVDurUDTdjMCEWUB+DiGZg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Microsoft.NET.Test.Sdk", "id": "Microsoft.NET.Test.Sdk", "version": "18.5.1", "sha512": "sha512-5/ucicw/H9/VNCmMTCjCQhNHEJc08ZeSLSrjvdZR/rtVUY8Enw+bi9LQTP1K97aRCqw/BG7cIV+VVFvgj3fKiw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": ["Microsoft.CodeCoverage"], "net47": ["Microsoft.CodeCoverage"], "net471": ["Microsoft.CodeCoverage"], "net472": ["Microsoft.CodeCoverage"], "net48": ["Microsoft.CodeCoverage"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "net9.0": ["Microsoft.TestPlatform.TestHost", "Microsoft.CodeCoverage"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Microsoft.TestPlatform.ObjectModel", "id": "Microsoft.TestPlatform.ObjectModel", "version": "18.5.1", "sha512": "sha512-SJHvdEawgdOUuyN2/eVWZCwe14DKPgQPDsQGiwfeKFgjzYDUvhESRpohG9IvQQuYiCvAv7Tn+ozZ2fDPfpwdzg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["System.Reflection.Metadata"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["System.Reflection.Metadata"], "net462": ["System.Reflection.Metadata"], "net47": ["System.Reflection.Metadata"], "net471": ["System.Reflection.Metadata"], "net472": ["System.Reflection.Metadata"], "net48": ["System.Reflection.Metadata"], "net5.0": ["System.Reflection.Metadata"], "net6.0": ["System.Reflection.Metadata"], "net7.0": ["System.Reflection.Metadata"], "net8.0": ["System.Reflection.Metadata"], "net9.0": ["System.Reflection.Metadata"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["System.Reflection.Metadata"], "netcoreapp2.1": ["System.Reflection.Metadata"], "netcoreapp2.2": ["System.Reflection.Metadata"], "netcoreapp3.0": ["System.Reflection.Metadata"], "netcoreapp3.1": ["System.Reflection.Metadata"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["System.Reflection.Metadata"], "netstandard2.1": ["System.Reflection.Metadata"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Microsoft.TestPlatform.TestHost", "id": "Microsoft.TestPlatform.TestHost", "version": "18.5.1", "sha512": "sha512-CbWth1jMU2wVyAy1SVMexSyD3JXG8FYYyyrcY+B1aWhzFzRLh8JdThoibXTqXxZ2NRC9me+N4XIQC75dfLcgiA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "net9.0": ["Microsoft.TestPlatform.ObjectModel", "Newtonsoft.Json"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Microsoft.VisualStudio.SolutionPersistence", "id": "Microsoft.VisualStudio.SolutionPersistence", "version": "1.0.52", "sha512": "sha512-lHyMm5j5wRwVaC3vlCWrFH2FGy2SpFUZqLvYhzwf1cEUIQCUChU960h8kteFSf01ZkLSgJwrznmspwjW8kPtrA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": ["System.Memory", "System.Threading.Tasks.Extensions"], "net48": ["System.Memory", "System.Threading.Tasks.Extensions"], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Mono.Posix.NETStandard", "id": "Mono.Posix.NETStandard", "version": "1.0.0", "sha512": "sha512-RtGiutQZJAmajvQ0QvBvh73VJye85iW9f9tjZlzF88idLxNMo4lAktP/4Y9ilCpais0LDO0tpoICt9Hdv6wooA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "MSBuild.StructuredLogger", "id": "MSBuild.StructuredLogger", "version": "2.3.204", "sha512": "sha512-MnrlWYtNUl0db/2lePRJhtOCzbQkJ1L9tyrA4xlKTFqjvpw8wnnX6AQ+PXYhjlMJ8ET9aoXGJOn/3e9j07NSwg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core"], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net462": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net47": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net471": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net472": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net48": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net5.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net6.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net7.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net8.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "net9.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp2.2": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netcoreapp3.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"], "netstandard2.1": ["Microsoft.Build.Framework", "Microsoft.Build.Utilities.Core", "System.Collections.Immutable", "System.Memory", "System.Runtime.CompilerServices.Unsafe"]}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, - {"name": "NaturalSort.Extension", "id": "NaturalSort.Extension", "version": "4.4.1", "sha512": "sha512-UTrcQcgmn7pBdx+0Oi/NxlyPslWbMt7U8I1sg/4m36OkOCS+7QKZWY3O4dKcjHD2wQaBr9L2/XWnx3ViTaehZw==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "Newtonsoft.Json", "id": "Newtonsoft.Json", "version": "13.0.4", "sha512": "sha512-bR+v+E/yJ6g7GV2uXw2OrUSjYYfjLkOLC8JD4kCS23msLapnKtdJPBJA75fwHH++ErIffeIqzYITLxAur4KAXA==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "NuGet.Versioning", "id": "NuGet.Versioning", "version": "7.6.0", "sha512": "sha512-JwbvmbG+1EOilFOAtjT2A7p05UgeOqzTZluUJ4mFgPZUSpYcHPPaK15x+RiqpKsVmKy741MaLN0fjOYxhGXr3g==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, {"name": "System.Buffers", "id": "System.Buffers", "version": "4.6.1", "sha512": "sha512-qve/dFwECwehSWlZmpkrrlIeATCvo/Hw2koyMrUVcDBy5gXAQrnwX8pHEoqgj8DgkrWuWW1DrQbFqoMbo+Fvrg==", "sources": ["https://api.nuget.org/v3/index.json"], "dependencies": {"net10.0": [], "net11": [], "net20": [], "net30": [], "net35": [], "net40": [], "net403": [], "net45": [], "net451": [], "net452": [], "net46": [], "net461": [], "net462": [], "net47": [], "net471": [], "net472": [], "net48": [], "net5.0": [], "net6.0": [], "net7.0": [], "net8.0": [], "net9.0": [], "netcoreapp1.0": [], "netcoreapp1.1": [], "netcoreapp2.0": [], "netcoreapp2.1": [], "netcoreapp2.2": [], "netcoreapp3.0": [], "netcoreapp3.1": [], "netstandard": [], "netstandard1.0": [], "netstandard1.1": [], "netstandard1.2": [], "netstandard1.3": [], "netstandard1.4": [], "netstandard1.5": [], "netstandard1.6": [], "netstandard2.0": [], "netstandard2.1": []}, "targeting_pack_overrides": [], "framework_list": [], "tools": {}}, From 7f2fb2eb99540575d3808188ce4f4e9cea295661 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 26 May 2026 15:59:00 +0200 Subject: [PATCH 100/226] C#: Use the generic version of the associated implementation. --- .../CodeAnalysisExtensions/SymbolExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs b/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs index fbc1b52c99b..dd7246fa659 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs @@ -664,7 +664,7 @@ namespace Semmle.Extraction.CSharp // Find the (possibly unbound) original extension method that maps to this implementation (if any). var unboundDeclaration = extensions.SelectMany(e => e.GetMembers()) .OfType() - .FirstOrDefault(m => SymbolEqualityComparer.Default.Equals(m.AssociatedExtensionImplementation, method.ConstructedFrom)); + .FirstOrDefault(m => SymbolEqualityComparer.Default.Equals(m.AssociatedExtensionImplementation?.ConstructedFrom, method.ConstructedFrom)); var isFullyConstructed = method.IsBoundGenericMethod(); if (isFullyConstructed && unboundDeclaration?.ContainingType is INamedTypeSymbol extensionType) From fbc861e7a407fea2f809e0094a6f0457bdd2a5ed Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 26 May 2026 16:19:02 +0200 Subject: [PATCH 101/226] unified: Clarify grammar comment Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- unified/extractor/tree-sitter-swift/grammar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unified/extractor/tree-sitter-swift/grammar.js b/unified/extractor/tree-sitter-swift/grammar.js index b6197b345e0..1e63a7eaabb 100644 --- a/unified/extractor/tree-sitter-swift/grammar.js +++ b/unified/extractor/tree-sitter-swift/grammar.js @@ -272,8 +272,8 @@ module.exports = grammar({ comment: ($) => token(prec(PRECS.comment, seq("//", /.*/))), // Named wrapper for the unnamed `_multiline_comment` external token, so // that multi-line comments still appear in the AST (e.g. as extras between - // top-level statements) without bleeding into class_body's $children when - // used as a class member separator. + // top-level statements) without being extracted as class body members when + // used only to separate those members. multiline_comment: ($) => $._multiline_comment, // Identifiers simple_identifier: ($) => From 7862922e5cd788819bc4d0dc99a69318208ad4cf Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 May 2026 17:54:51 +0200 Subject: [PATCH 102/226] C++: Remove deprecated code --- cpp/ql/lib/DefaultOptions.qll | 16 +----- cpp/ql/lib/Options.qll | 54 ------------------ cpp/ql/lib/cpp.qll | 1 - cpp/ql/lib/semmle/code/cpp/Location.qll | 25 -------- cpp/ql/lib/semmle/code/cpp/Member.qll | 6 -- .../lib/semmle/code/cpp/TemplateParameter.qll | 7 --- .../semmle/code/cpp/internal/ResolveClass.qll | 57 ------------------- 7 files changed, 2 insertions(+), 164 deletions(-) delete mode 100644 cpp/ql/lib/semmle/code/cpp/Member.qll diff --git a/cpp/ql/lib/DefaultOptions.qll b/cpp/ql/lib/DefaultOptions.qll index e4aa8d1f2d7..e6631f1307a 100644 --- a/cpp/ql/lib/DefaultOptions.qll +++ b/cpp/ql/lib/DefaultOptions.qll @@ -30,8 +30,6 @@ class Options extends string { predicate overrideReturnsNull(Call call) { // Used in CVS: call.(FunctionCall).getTarget().hasGlobalName("Xstrdup") - or - CustomOptions::overrideReturnsNull(call) // old Options.qll } /** @@ -45,8 +43,6 @@ class Options extends string { // Used in CVS: call.(FunctionCall).getTarget().hasGlobalName("Xstrdup") and nullValue(call.getArgument(0)) - or - CustomOptions::returnsNull(call) // old Options.qll } /** @@ -65,8 +61,6 @@ class Options extends string { f.hasGlobalOrStdName([ "exit", "_exit", "_Exit", "abort", "__assert_fail", "longjmp", "__builtin_unreachable" ]) - or - CustomOptions::exits(f) // old Options.qll } /** @@ -79,8 +73,7 @@ class Options extends string { * runtime, the program's behavior is undefined) */ predicate exprExits(Expr e) { - e.(AssumeExpr).getChild(0).(CompileTimeConstantInt).getIntValue() = 0 or - CustomOptions::exprExits(e) // old Options.qll + e.(AssumeExpr).getChild(0).(CompileTimeConstantInt).getIntValue() = 0 } /** @@ -88,10 +81,7 @@ class Options extends string { * * By default holds only for `fgets`. */ - predicate alwaysCheckReturnValue(Function f) { - f.hasGlobalOrStdName("fgets") or - CustomOptions::alwaysCheckReturnValue(f) // old Options.qll - } + predicate alwaysCheckReturnValue(Function f) { f.hasGlobalOrStdName("fgets") } /** * Holds if it is reasonable to ignore the return value of function @@ -107,8 +97,6 @@ class Options extends string { // common way of sleeping using select: fc.getTarget().hasGlobalName("select") and fc.getArgument(0).getValue() = "0" - or - CustomOptions::okToIgnoreReturnValue(fc) // old Options.qll } } diff --git a/cpp/ql/lib/Options.qll b/cpp/ql/lib/Options.qll index c4652e3f6ca..fb2f24119db 100644 --- a/cpp/ql/lib/Options.qll +++ b/cpp/ql/lib/Options.qll @@ -98,57 +98,3 @@ class CustomMutexType extends MutexType { */ override predicate unlockAccess(FunctionCall fc, Expr arg) { none() } } - -/** - * DEPRECATED: customize `CustomOptions.overrideReturnsNull` instead. - * - * This predicate is required to support backwards compatibility for - * older `Options.qll` files. It should not be removed or modified by - * end users. - */ -predicate overrideReturnsNull(Call call) { none() } - -/** - * DEPRECATED: customize `CustomOptions.returnsNull` instead. - * - * This predicate is required to support backwards compatibility for - * older `Options.qll` files. It should not be removed or modified by - * end users. - */ -predicate returnsNull(Call call) { none() } - -/** - * DEPRECATED: customize `CustomOptions.exits` instead. - * - * This predicate is required to support backwards compatibility for - * older `Options.qll` files. It should not be removed or modified by - * end users. - */ -predicate exits(Function f) { none() } - -/** - * DEPRECATED: customize `CustomOptions.exprExits` instead. - * - * This predicate is required to support backwards compatibility for - * older `Options.qll` files. It should not be removed or modified by - * end users. - */ -predicate exprExits(Expr e) { none() } - -/** - * DEPRECATED: customize `CustomOptions.alwaysCheckReturnValue` instead. - * - * This predicate is required to support backwards compatibility for - * older `Options.qll` files. It should not be removed or modified by - * end users. - */ -predicate alwaysCheckReturnValue(Function f) { none() } - -/** - * DEPRECATED: customize `CustomOptions.okToIgnoreReturnValue` instead. - * - * This predicate is required to support backwards compatibility for - * older `Options.qll` files. It should not be removed or modified by - * end users. - */ -predicate okToIgnoreReturnValue(FunctionCall fc) { none() } diff --git a/cpp/ql/lib/cpp.qll b/cpp/ql/lib/cpp.qll index 560a4444bfa..9cc9f7eb1ef 100644 --- a/cpp/ql/lib/cpp.qll +++ b/cpp/ql/lib/cpp.qll @@ -32,7 +32,6 @@ import semmle.code.cpp.Class import semmle.code.cpp.Struct import semmle.code.cpp.Union import semmle.code.cpp.Enum -import semmle.code.cpp.Member import semmle.code.cpp.Field import semmle.code.cpp.Function import semmle.code.cpp.MemberFunction diff --git a/cpp/ql/lib/semmle/code/cpp/Location.qll b/cpp/ql/lib/semmle/code/cpp/Location.qll index 8b0a78f91aa..92668206a9f 100644 --- a/cpp/ql/lib/semmle/code/cpp/Location.qll +++ b/cpp/ql/lib/semmle/code/cpp/Location.qll @@ -148,28 +148,3 @@ class UnknownLocation extends Location { this.getFile().getAbsolutePath() = "" and locations_default(this, _, 0, 0, 0, 0) } } - -/** - * A dummy location which is used when something doesn't have a location in - * the source code but needs to have a `Location` associated with it. - * - * DEPRECATED: use `UnknownLocation` - */ -deprecated class UnknownDefaultLocation extends UnknownLocation { } - -/** - * A dummy location which is used when an expression doesn't have a - * location in the source code but needs to have a `Location` associated - * with it. - * - * DEPRECATED: use `UnknownLocation` - */ -deprecated class UnknownExprLocation extends UnknownLocation { } - -/** - * A dummy location which is used when a statement doesn't have a location - * in the source code but needs to have a `Location` associated with it. - * - * DEPRECATED: use `UnknownLocation` - */ -deprecated class UnknownStmtLocation extends UnknownLocation { } diff --git a/cpp/ql/lib/semmle/code/cpp/Member.qll b/cpp/ql/lib/semmle/code/cpp/Member.qll deleted file mode 100644 index f47edbddeba..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/Member.qll +++ /dev/null @@ -1,6 +0,0 @@ -/** - * DEPRECATED: import `semmle.code.cpp.Element` and/or `semmle.code.cpp.Type` directly as required. - */ - -import semmle.code.cpp.Element -import semmle.code.cpp.Type diff --git a/cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll b/cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll index 6ece9cb82a4..e95b5b07073 100644 --- a/cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll +++ b/cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll @@ -35,13 +35,6 @@ class NonTypeTemplateParameter extends Literal, TemplateParameterImpl { override string getAPrimaryQlClass() { result = "NonTypeTemplateParameter" } } -/** - * A C++ `typename` (or `class`) template parameter. - * - * DEPRECATED: Use `TypeTemplateParameter` instead. - */ -deprecated class TemplateParameter = TypeTemplateParameter; - /** * A C++ `typename` (or `class`) template parameter. * diff --git a/cpp/ql/lib/semmle/code/cpp/internal/ResolveClass.qll b/cpp/ql/lib/semmle/code/cpp/internal/ResolveClass.qll index 9b2acc05e9e..52c9aba7a86 100644 --- a/cpp/ql/lib/semmle/code/cpp/internal/ResolveClass.qll +++ b/cpp/ql/lib/semmle/code/cpp/internal/ResolveClass.qll @@ -1,59 +1,5 @@ import semmle.code.cpp.Type -/** For upgraded databases without mangled name info. */ -pragma[noinline] -private string getTopLevelClassName(@usertype c) { - not mangled_name(_, _, _) and - isClass(c) and - usertypes(c, result, _) and - not namespacembrs(_, c) and // not in a namespace - not member(_, _, c) and // not in some structure - not class_instantiation(c, _) // not a template instantiation -} - -/** - * For upgraded databases without mangled name info. - * Holds if `d` is a unique complete class named `name`. - */ -pragma[noinline] -private predicate existsCompleteWithName(string name, @usertype d) { - not mangled_name(_, _, _) and - is_complete(d) and - name = getTopLevelClassName(d) and - onlyOneCompleteClassExistsWithName(name) -} - -/** For upgraded databases without mangled name info. */ -pragma[noinline] -private predicate onlyOneCompleteClassExistsWithName(string name) { - not mangled_name(_, _, _) and - strictcount(@usertype c | is_complete(c) and getTopLevelClassName(c) = name) = 1 -} - -/** - * For upgraded databases without mangled name info. - * Holds if `c` is an incomplete class named `name`. - */ -pragma[noinline] -private predicate existsIncompleteWithName(string name, @usertype c) { - not mangled_name(_, _, _) and - not is_complete(c) and - name = getTopLevelClassName(c) -} - -/** - * For upgraded databases without mangled name info. - * Holds if `c` is an incomplete class, and there exists a unique complete class `d` - * with the same name. - */ -private predicate oldHasCompleteTwin(@usertype c, @usertype d) { - not mangled_name(_, _, _) and - exists(string name | - existsIncompleteWithName(name, c) and - existsCompleteWithName(name, d) - ) -} - pragma[noinline] private @mangledname getClassMangledName(@usertype c) { isClass(c) and @@ -103,10 +49,7 @@ private module Cached { @usertype resolveClass(@usertype c) { hasCompleteTwin(c, result) or - oldHasCompleteTwin(c, result) - or not hasCompleteTwin(c, _) and - not oldHasCompleteTwin(c, _) and result = c } From 3aa69823afcdd014650c3329ad76a2bf08e6bc00 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 26 May 2026 15:13:20 +0200 Subject: [PATCH 103/226] Ruby: Skip BodyStmt in ErbDirective.getAChildStmt. --- ruby/ql/lib/codeql/ruby/ast/Erb.qll | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/Erb.qll b/ruby/ql/lib/codeql/ruby/ast/Erb.qll index 4def19f7ceb..93d7d6f5e08 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Erb.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Erb.qll @@ -156,14 +156,23 @@ class ErbDirective extends TDirectiveNode, ErbAstNode { ) } + pragma[nomagic] + private Stmt getAChildStmt0() { + this.containsAstNodeStart(result) and + not this.containsAstNodeStart(result.getParent()) + } + /** * Gets a statement that starts in directive that is not a child of any other * statement starting in this directive. */ cached Stmt getAChildStmt() { + result = this.getAChildStmt0() and + not result instanceof BodyStmt + or this.containsAstNodeStart(result) and - not this.containsAstNodeStart(result.getParent()) + result = this.getAChildStmt0().(BodyStmt).getAStmt() } /** From 780591d42a67f6c30f1882fe36c54a6636dde2b3 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 26 May 2026 15:15:00 +0200 Subject: [PATCH 104/226] Ruby: Remove spurious parent-child edges for Ruby::SimpleSymbol. These treesitter nodes translate to multiple AstNodes, but we only want those that are Stmts. --- ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index 072f453826c..9d2dd16ea63 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -1974,9 +1974,12 @@ private module CallableBodySynthesis { i = 0 and child = SynthChild(BodyStmtKind()) or - parent = TBodyStmtSynth(m, 0) and - i = 0 and - child = childRef(fromGenerated(body)) + exists(Stmt bodyStmt | + parent = TBodyStmtSynth(m, 0) and + i = 0 and + bodyStmt = fromGenerated(body) and + child = childRef(bodyStmt) + ) ) } From 35364a087a6a9ff89319fbe6c2d894837b1e8e5c Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 27 May 2026 10:23:16 +0200 Subject: [PATCH 105/226] C++: Update expected test results after extractor changes --- .../test/library-tests/friends/loop/friends.expected | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/ql/test/library-tests/friends/loop/friends.expected b/cpp/ql/test/library-tests/friends/loop/friends.expected index a59c1f0c65c..50030ed70bc 100644 --- a/cpp/ql/test/library-tests/friends/loop/friends.expected +++ b/cpp/ql/test/library-tests/friends/loop/friends.expected @@ -1,14 +1,14 @@ -| file://:0:0:0:0 | E's friend | loop.cpp:5:26:5:26 | E | | file://:0:0:0:0 | E's friend | loop.cpp:5:26:5:26 | E | -| file://:0:0:0:0 | E's friend | loop.cpp:10:26:10:26 | F | +| file://:0:0:0:0 | E's friend | loop.cpp:5:26:5:29 | E | | file://:0:0:0:0 | E's friend | loop.cpp:10:26:10:26 | F | -| file://:0:0:0:0 | E's friend | loop.cpp:5:26:5:26 | E | +| file://:0:0:0:0 | E's friend | loop.cpp:10:26:10:29 | F | | file://:0:0:0:0 | E's friend | loop.cpp:5:26:5:26 | E | -| file://:0:0:0:0 | E's friend | loop.cpp:10:26:10:26 | F | +| file://:0:0:0:0 | E's friend | loop.cpp:5:26:5:29 | E | | file://:0:0:0:0 | E's friend | loop.cpp:10:26:10:26 | F | -| file://:0:0:0:0 | F's friend | loop.cpp:5:26:5:26 | E | -| file://:0:0:0:0 | F's friend | loop.cpp:5:26:5:26 | E | +| file://:0:0:0:0 | E's friend | loop.cpp:10:26:10:29 | F | | file://:0:0:0:0 | F's friend | loop.cpp:5:26:5:26 | E | +| file://:0:0:0:0 | F's friend | loop.cpp:5:26:5:29 | E | +| file://:0:0:0:0 | F's friend | loop.cpp:5:26:5:29 | E | | loop.cpp:6:5:6:5 | E's friend | loop.cpp:5:26:5:26 | E | | loop.cpp:7:5:7:5 | E's friend | loop.cpp:7:36:7:36 | F | | loop.cpp:11:5:11:5 | F's friend | loop.cpp:11:36:11:36 | E | From 362c48cc6d8e442a147da4680414af12099d15ad Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 27 May 2026 10:44:44 +0200 Subject: [PATCH 106/226] C++: Add change note --- .../change-notes/2026-05-27-deprecated-removal.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md diff --git a/cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md b/cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md new file mode 100644 index 00000000000..65c42916fb2 --- /dev/null +++ b/cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md @@ -0,0 +1,15 @@ +--- +category: breaking +--- +* Removed the deprecated `overrideReturnsNull` predicate from `Options.qll`. Use `CustomOptions.overrideReturnsNull` instead. +* Removed the deprecated `returnsNull` predicate from `Options.qll`. Use `CustomOptions.returnsNull` instead. +* Removed the deprecated `exits` predicate from `Options.qll`. Use `CustomOptions.exist` instead. +* Removed the deprecated `exprExits` predicate from `Options.qll`. Use `CustomOptions.exprExits` instead. +* Removed the deprecated `alwaysCheckReturnValue` predicate from `Options.qll`. Use `CustomOptions.alwaysCheckReturnValue` instead. +* Removed the deprecated `okToIgnoreReturnValue` predicate from `Options.qll`. Use `CustomOptions.okToIgnoreReturnValue` instead. +* Removed the deprecated `semmle.code.cpp.Member`. Import `semmle.code.cpp.Element` and/or `semmle.code.cpp.Type` directly. +* Removed the deprecated `UnknownDefaultLocation` class. Use `UnknownLocation` instead. +* Removed the deprecated `UnknownExprLocation` class. Use `UnknownLocation` instead. +* Removed the deprecated `UnknownStmtLocation` class. Use `UnknownLocation` instead. +* Removed the deprecated `TemplateParameter` class. Use `TypeTemplateParameter` instead. +* Support for class resolution across link targets has been removed for databases which were created with CodeQL versions before 1.23.0. From e66b1e4beb2654770cbec9fa303cec807dd729b2 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <93738568+jketema@users.noreply.github.com> Date: Wed, 27 May 2026 10:58:05 +0200 Subject: [PATCH 107/226] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md b/cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md index 65c42916fb2..33ad83230d4 100644 --- a/cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md +++ b/cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md @@ -3,7 +3,7 @@ category: breaking --- * Removed the deprecated `overrideReturnsNull` predicate from `Options.qll`. Use `CustomOptions.overrideReturnsNull` instead. * Removed the deprecated `returnsNull` predicate from `Options.qll`. Use `CustomOptions.returnsNull` instead. -* Removed the deprecated `exits` predicate from `Options.qll`. Use `CustomOptions.exist` instead. +* Removed the deprecated `exits` predicate from `Options.qll`. Use `CustomOptions.exits` instead. * Removed the deprecated `exprExits` predicate from `Options.qll`. Use `CustomOptions.exprExits` instead. * Removed the deprecated `alwaysCheckReturnValue` predicate from `Options.qll`. Use `CustomOptions.alwaysCheckReturnValue` instead. * Removed the deprecated `okToIgnoreReturnValue` predicate from `Options.qll`. Use `CustomOptions.okToIgnoreReturnValue` instead. From b44bca9ea72456d4883e349d728ba96c6360a3cd Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 19 May 2026 16:50:24 +0100 Subject: [PATCH 108/226] Swift: Add HashFunction protocol and other realism to the CryptoKit test stubs (this is needed for new cases to work as intended). --- .../CWE-328/WeakPasswordHashing.expected | 50 ++---- .../CWE-328/WeakSensitiveDataHashing.expected | 54 ++----- .../Security/CWE-328/testCryptoKit.swift | 147 ++++++++++-------- 3 files changed, 105 insertions(+), 146 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected index f8db62cedbc..9db9a5f4a1c 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected @@ -1,27 +1,10 @@ edges -| testCryptoKit.swift:199:38:199:38 | passwordString | testCryptoKit.swift:199:38:199:53 | .utf8 | provenance | | -| testCryptoKit.swift:199:38:199:53 | .utf8 | testCryptoKit.swift:199:33:199:57 | call to Data.init(_:) | provenance | | nodes -| testCryptoKit.swift:65:47:65:47 | passwd | semmle.label | passwd | -| testCryptoKit.swift:71:36:71:36 | passwd | semmle.label | passwd | -| testCryptoKit.swift:77:44:77:44 | passwd | semmle.label | passwd | -| testCryptoKit.swift:83:37:83:37 | passwd | semmle.label | passwd | -| testCryptoKit.swift:89:37:89:37 | passwd | semmle.label | passwd | -| testCryptoKit.swift:95:37:95:37 | passwd | semmle.label | passwd | -| testCryptoKit.swift:104:23:104:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:113:23:113:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:122:23:122:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:131:23:131:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:140:23:140:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:149:32:149:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:158:32:158:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:167:32:167:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:176:32:176:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:185:32:185:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:195:49:195:49 | passwordData | semmle.label | passwordData | -| testCryptoKit.swift:199:33:199:57 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | -| testCryptoKit.swift:199:38:199:38 | passwordString | semmle.label | passwordString | -| testCryptoKit.swift:199:38:199:53 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:168:32:168:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:177:32:177:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:186:32:186:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:195:32:195:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:204:32:204:32 | passwd | semmle.label | passwd | | testCryptoSwift.swift:154:30:154:30 | passwdArray | semmle.label | passwdArray | | testCryptoSwift.swift:157:31:157:31 | passwdArray | semmle.label | passwdArray | | testCryptoSwift.swift:160:47:160:47 | passwdArray | semmle.label | passwdArray | @@ -48,24 +31,11 @@ nodes | testCryptoSwift.swift:231:9:231:9 | passwd | semmle.label | passwd | subpaths #select -| testCryptoKit.swift:65:47:65:47 | passwd | testCryptoKit.swift:65:47:65:47 | passwd | testCryptoKit.swift:65:47:65:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:65:47:65:47 | passwd | password (passwd) | -| testCryptoKit.swift:71:36:71:36 | passwd | testCryptoKit.swift:71:36:71:36 | passwd | testCryptoKit.swift:71:36:71:36 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:71:36:71:36 | passwd | password (passwd) | -| testCryptoKit.swift:77:44:77:44 | passwd | testCryptoKit.swift:77:44:77:44 | passwd | testCryptoKit.swift:77:44:77:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:77:44:77:44 | passwd | password (passwd) | -| testCryptoKit.swift:83:37:83:37 | passwd | testCryptoKit.swift:83:37:83:37 | passwd | testCryptoKit.swift:83:37:83:37 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:83:37:83:37 | passwd | password (passwd) | -| testCryptoKit.swift:89:37:89:37 | passwd | testCryptoKit.swift:89:37:89:37 | passwd | testCryptoKit.swift:89:37:89:37 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:89:37:89:37 | passwd | password (passwd) | -| testCryptoKit.swift:95:37:95:37 | passwd | testCryptoKit.swift:95:37:95:37 | passwd | testCryptoKit.swift:95:37:95:37 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:95:37:95:37 | passwd | password (passwd) | -| testCryptoKit.swift:104:23:104:23 | passwd | testCryptoKit.swift:104:23:104:23 | passwd | testCryptoKit.swift:104:23:104:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:104:23:104:23 | passwd | password (passwd) | -| testCryptoKit.swift:113:23:113:23 | passwd | testCryptoKit.swift:113:23:113:23 | passwd | testCryptoKit.swift:113:23:113:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:113:23:113:23 | passwd | password (passwd) | -| testCryptoKit.swift:122:23:122:23 | passwd | testCryptoKit.swift:122:23:122:23 | passwd | testCryptoKit.swift:122:23:122:23 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:122:23:122:23 | passwd | password (passwd) | -| testCryptoKit.swift:131:23:131:23 | passwd | testCryptoKit.swift:131:23:131:23 | passwd | testCryptoKit.swift:131:23:131:23 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:131:23:131:23 | passwd | password (passwd) | -| testCryptoKit.swift:140:23:140:23 | passwd | testCryptoKit.swift:140:23:140:23 | passwd | testCryptoKit.swift:140:23:140:23 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:140:23:140:23 | passwd | password (passwd) | -| testCryptoKit.swift:149:32:149:32 | passwd | testCryptoKit.swift:149:32:149:32 | passwd | testCryptoKit.swift:149:32:149:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:149:32:149:32 | passwd | password (passwd) | -| testCryptoKit.swift:158:32:158:32 | passwd | testCryptoKit.swift:158:32:158:32 | passwd | testCryptoKit.swift:158:32:158:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:158:32:158:32 | passwd | password (passwd) | -| testCryptoKit.swift:167:32:167:32 | passwd | testCryptoKit.swift:167:32:167:32 | passwd | testCryptoKit.swift:167:32:167:32 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:167:32:167:32 | passwd | password (passwd) | -| testCryptoKit.swift:176:32:176:32 | passwd | testCryptoKit.swift:176:32:176:32 | passwd | testCryptoKit.swift:176:32:176:32 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:176:32:176:32 | passwd | password (passwd) | -| testCryptoKit.swift:185:32:185:32 | passwd | testCryptoKit.swift:185:32:185:32 | passwd | testCryptoKit.swift:185:32:185:32 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:185:32:185:32 | passwd | password (passwd) | -| testCryptoKit.swift:195:49:195:49 | passwordData | testCryptoKit.swift:195:49:195:49 | passwordData | testCryptoKit.swift:195:49:195:49 | passwordData | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:195:49:195:49 | passwordData | password (passwordData) | -| testCryptoKit.swift:199:33:199:57 | call to Data.init(_:) | testCryptoKit.swift:199:38:199:38 | passwordString | testCryptoKit.swift:199:33:199:57 | call to Data.init(_:) | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:199:38:199:38 | passwordString | password (passwordString) | +| testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:168:32:168:32 | passwd | password (passwd) | +| testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:177:32:177:32 | passwd | password (passwd) | +| testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:186:32:186:32 | passwd | password (passwd) | +| testCryptoKit.swift:195:32:195:32 | passwd | testCryptoKit.swift:195:32:195:32 | passwd | testCryptoKit.swift:195:32:195:32 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:195:32:195:32 | passwd | password (passwd) | +| testCryptoKit.swift:204:32:204:32 | passwd | testCryptoKit.swift:204:32:204:32 | passwd | testCryptoKit.swift:204:32:204:32 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:204:32:204:32 | passwd | password (passwd) | | testCryptoSwift.swift:154:30:154:30 | passwdArray | testCryptoSwift.swift:154:30:154:30 | passwdArray | testCryptoSwift.swift:154:30:154:30 | passwdArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:154:30:154:30 | passwdArray | password (passwdArray) | | testCryptoSwift.swift:157:31:157:31 | passwdArray | testCryptoSwift.swift:157:31:157:31 | passwdArray | testCryptoSwift.swift:157:31:157:31 | passwdArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:157:31:157:31 | passwdArray | password (passwdArray) | | testCryptoSwift.swift:160:47:160:47 | passwdArray | testCryptoSwift.swift:160:47:160:47 | passwdArray | testCryptoSwift.swift:160:47:160:47 | passwdArray | Insecure hashing algorithm (SHA2) depends on $@. | testCryptoSwift.swift:160:47:160:47 | passwdArray | password (passwdArray) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected index 5da99db8068..d48bbbf4dfa 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected @@ -1,26 +1,11 @@ edges nodes -| testCryptoKit.swift:66:43:66:43 | cert | semmle.label | cert | -| testCryptoKit.swift:68:43:68:43 | account_no | semmle.label | account_no | -| testCryptoKit.swift:69:43:69:43 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:72:36:72:36 | cert | semmle.label | cert | -| testCryptoKit.swift:74:36:74:36 | account_no | semmle.label | account_no | -| testCryptoKit.swift:75:36:75:36 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:78:44:78:44 | cert | semmle.label | cert | -| testCryptoKit.swift:80:44:80:44 | account_no | semmle.label | account_no | -| testCryptoKit.swift:81:44:81:44 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:105:23:105:23 | cert | semmle.label | cert | -| testCryptoKit.swift:107:23:107:23 | account_no | semmle.label | account_no | -| testCryptoKit.swift:108:23:108:23 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:114:23:114:23 | cert | semmle.label | cert | -| testCryptoKit.swift:116:23:116:23 | account_no | semmle.label | account_no | -| testCryptoKit.swift:117:23:117:23 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:150:32:150:32 | cert | semmle.label | cert | -| testCryptoKit.swift:152:32:152:32 | account_no | semmle.label | account_no | -| testCryptoKit.swift:153:32:153:32 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:159:32:159:32 | cert | semmle.label | cert | -| testCryptoKit.swift:161:32:161:32 | account_no | semmle.label | account_no | -| testCryptoKit.swift:162:32:162:32 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:169:32:169:32 | cert | semmle.label | cert | +| testCryptoKit.swift:171:32:171:32 | account_no | semmle.label | account_no | +| testCryptoKit.swift:172:32:172:32 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:178:32:178:32 | cert | semmle.label | cert | +| testCryptoKit.swift:180:32:180:32 | account_no | semmle.label | account_no | +| testCryptoKit.swift:181:32:181:32 | credit_card_no | semmle.label | credit_card_no | | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | semmle.label | phoneNumberArray | | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | semmle.label | phoneNumberArray | | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | semmle.label | phoneNumberArray | @@ -33,27 +18,12 @@ nodes | testCryptoSwift.swift:221:9:221:9 | creditCardNumber | semmle.label | creditCardNumber | subpaths #select -| testCryptoKit.swift:66:43:66:43 | cert | testCryptoKit.swift:66:43:66:43 | cert | testCryptoKit.swift:66:43:66:43 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:66:43:66:43 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:68:43:68:43 | account_no | testCryptoKit.swift:68:43:68:43 | account_no | testCryptoKit.swift:68:43:68:43 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:68:43:68:43 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:69:43:69:43 | credit_card_no | testCryptoKit.swift:69:43:69:43 | credit_card_no | testCryptoKit.swift:69:43:69:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:69:43:69:43 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:72:36:72:36 | cert | testCryptoKit.swift:72:36:72:36 | cert | testCryptoKit.swift:72:36:72:36 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:72:36:72:36 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:74:36:74:36 | account_no | testCryptoKit.swift:74:36:74:36 | account_no | testCryptoKit.swift:74:36:74:36 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:74:36:74:36 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:75:36:75:36 | credit_card_no | testCryptoKit.swift:75:36:75:36 | credit_card_no | testCryptoKit.swift:75:36:75:36 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:75:36:75:36 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:78:44:78:44 | cert | testCryptoKit.swift:78:44:78:44 | cert | testCryptoKit.swift:78:44:78:44 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:78:44:78:44 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:80:44:80:44 | account_no | testCryptoKit.swift:80:44:80:44 | account_no | testCryptoKit.swift:80:44:80:44 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:80:44:80:44 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:81:44:81:44 | credit_card_no | testCryptoKit.swift:81:44:81:44 | credit_card_no | testCryptoKit.swift:81:44:81:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:81:44:81:44 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:105:23:105:23 | cert | testCryptoKit.swift:105:23:105:23 | cert | testCryptoKit.swift:105:23:105:23 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:105:23:105:23 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:107:23:107:23 | account_no | testCryptoKit.swift:107:23:107:23 | account_no | testCryptoKit.swift:107:23:107:23 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:107:23:107:23 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:108:23:108:23 | credit_card_no | testCryptoKit.swift:108:23:108:23 | credit_card_no | testCryptoKit.swift:108:23:108:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:108:23:108:23 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:114:23:114:23 | cert | testCryptoKit.swift:114:23:114:23 | cert | testCryptoKit.swift:114:23:114:23 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:114:23:114:23 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:116:23:116:23 | account_no | testCryptoKit.swift:116:23:116:23 | account_no | testCryptoKit.swift:116:23:116:23 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:116:23:116:23 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:117:23:117:23 | credit_card_no | testCryptoKit.swift:117:23:117:23 | credit_card_no | testCryptoKit.swift:117:23:117:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:117:23:117:23 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:150:32:150:32 | cert | testCryptoKit.swift:150:32:150:32 | cert | testCryptoKit.swift:150:32:150:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:150:32:150:32 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:152:32:152:32 | account_no | testCryptoKit.swift:152:32:152:32 | account_no | testCryptoKit.swift:152:32:152:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:152:32:152:32 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:153:32:153:32 | credit_card_no | testCryptoKit.swift:153:32:153:32 | credit_card_no | testCryptoKit.swift:153:32:153:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:153:32:153:32 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:159:32:159:32 | cert | testCryptoKit.swift:159:32:159:32 | cert | testCryptoKit.swift:159:32:159:32 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:159:32:159:32 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:161:32:161:32 | account_no | testCryptoKit.swift:161:32:161:32 | account_no | testCryptoKit.swift:161:32:161:32 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:161:32:161:32 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:162:32:162:32 | credit_card_no | testCryptoKit.swift:162:32:162:32 | credit_card_no | testCryptoKit.swift:162:32:162:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:162:32:162:32 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:169:32:169:32 | cert | testCryptoKit.swift:169:32:169:32 | cert | testCryptoKit.swift:169:32:169:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:169:32:169:32 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:171:32:171:32 | account_no | testCryptoKit.swift:171:32:171:32 | account_no | testCryptoKit.swift:171:32:171:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:171:32:171:32 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:172:32:172:32 | credit_card_no | testCryptoKit.swift:172:32:172:32 | credit_card_no | testCryptoKit.swift:172:32:172:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:172:32:172:32 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:178:32:178:32 | cert | testCryptoKit.swift:178:32:178:32 | cert | testCryptoKit.swift:178:32:178:32 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:178:32:178:32 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:180:32:180:32 | account_no | testCryptoKit.swift:180:32:180:32 | account_no | testCryptoKit.swift:180:32:180:32 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:180:32:180:32 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:181:32:181:32 | credit_card_no | testCryptoKit.swift:181:32:181:32 | credit_card_no | testCryptoKit.swift:181:32:181:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:181:32:181:32 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | sensitive data (private information phoneNumberArray) | | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | sensitive data (private information phoneNumberArray) | | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | sensitive data (private information phoneNumberArray) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index 755bd27e3c7..e3f5ffc702f 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -7,92 +7,111 @@ class Data init(_ elements: S) {} } -struct SHA256 { - static func hash(data: D) -> [UInt8] { - return [] - } +public protocol HashFunction { + associatedtype Digest - func update(data: D) {} - func update(bufferPointer: UnsafeRawBufferPointer) {} - func finalize() -> [UInt8] { return [] } + init() + mutating func update(bufferPointer: UnsafeRawBufferPointer) + func finalize() -> Digest } -struct SHA384 { - static func hash(data: D) -> [UInt8] { - return [] +extension HashFunction { + @inlinable + public static func hash(bufferPointer: UnsafeRawBufferPointer) -> Digest { + var hasher = Self() + hasher.update(bufferPointer: bufferPointer) + return hasher.finalize() } - func update(data: D) {} - func update(bufferPointer: UnsafeRawBufferPointer) {} - func finalize() -> [UInt8] { return [] } -} - -struct SHA512 { - static func hash(data: D) -> [UInt8] { - return [] + @inlinable + public static func hash(data: D) -> Self.Digest { + var hasher = Self() + hasher.update(data: data) + return hasher.finalize() } - func update(data: D) {} - func update(bufferPointer: UnsafeRawBufferPointer) {} - func finalize() -> [UInt8] { return [] } + @inlinable + public mutating func update(data: D) { + // ... + } } +public struct SHA256: HashFunction { + public typealias Digest = [UInt8] + + public init() {} + public mutating func update(bufferPointer: UnsafeRawBufferPointer) {} + public func finalize() -> Digest { return [] } +} + +public struct SHA384: HashFunction { + public typealias Digest = [UInt8] + + public init() {} + public mutating func update(bufferPointer: UnsafeRawBufferPointer) {} + public func finalize() -> Digest { return [] } +} + +public struct SHA512: HashFunction { + public typealias Digest = [UInt8] + + public init() {} + public mutating func update(bufferPointer: UnsafeRawBufferPointer) {} + public func finalize() -> Digest { return [] } +} enum Insecure { - struct MD5 { - static func hash(data: D) -> [UInt8] { - return [] - } + public struct MD5: HashFunction { + public typealias Digest = [UInt8] - func update(data: D) {} - func update(bufferPointer: UnsafeRawBufferPointer) {} - func finalize() -> [UInt8] { return [] } + public init() {} + public mutating func update(bufferPointer: UnsafeRawBufferPointer) {} + public func finalize() -> Digest { return [] } } - struct SHA1 { - static func hash(data: D) -> [UInt8] { - return [] - } - func update(data: D) {} - func update(bufferPointer: UnsafeRawBufferPointer) {} - func finalize() -> [UInt8] { return [] } + public struct SHA1: HashFunction { + public typealias Digest = [UInt8] + + public init() {} + public mutating func update(bufferPointer: UnsafeRawBufferPointer) {} + public func finalize() -> Digest { return [] } } } // --- tests --- func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { - var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD - hash = Crypto.Insecure.MD5.hash(data: cert) // BAD + var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD [NOT DETECTED] + hash = Crypto.Insecure.MD5.hash(data: cert) // BAD [NOT DETECTED] hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD - hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD + hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD [NOT DETECTED] - hash = Insecure.MD5.hash(data: passwd) // BAD - hash = Insecure.MD5.hash(data: cert) // BAD + hash = Insecure.MD5.hash(data: passwd) // BAD [NOT DETECTED] + hash = Insecure.MD5.hash(data: cert) // BAD [NOT DETECTED] hash = Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Insecure.MD5.hash(data: account_no) // BAD - hash = Insecure.MD5.hash(data: credit_card_no) // BAD + hash = Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED] + hash = Insecure.MD5.hash(data: credit_card_no) // BAD [NOT DETECTED] - hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD - hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD + hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD [NOT DETECTED] + hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD [NOT DETECTED] hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD - hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD + hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD [NOT DETECTED] - hash = Crypto.SHA256.hash(data: passwd) // BAD, not a computationally expensive hash + hash = Crypto.SHA256.hash(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash = Crypto.SHA256.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA256.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA256.hash(data: account_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA256.hash(data: credit_card_no) // GOOD, computationally expensive hash not required - hash = Crypto.SHA384.hash(data: passwd) // BAD, not a computationally expensive hash + hash = Crypto.SHA384.hash(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash = Crypto.SHA384.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA384.hash(data: account_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: credit_card_no) // GOOD, computationally expensive hash not required - hash = Crypto.SHA512.hash(data: passwd) // BAD, not a computationally expensive hash + hash = Crypto.SHA512.hash(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash = Crypto.SHA512.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA512.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA512.hash(data: account_no) // GOOD, computationally expensive hash not required @@ -101,25 +120,25 @@ func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_pa func testMD5UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.Insecure.MD5() - hash.update(data: passwd) // BAD - hash.update(data: cert) // BAD + hash.update(data: passwd) // BAD [NOT DETECTED] + hash.update(data: cert) // BAD [NOT DETECTED] hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD - hash.update(data: credit_card_no) // BAD + hash.update(data: account_no) // BAD [NOT DETECTED] + hash.update(data: credit_card_no) // BAD [NOT DETECTED] } func testSHA1UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.Insecure.SHA1() - hash.update(data: passwd) // BAD - hash.update(data: cert) // BAD + hash.update(data: passwd) // BAD [NOT DETECTED] + hash.update(data: cert) // BAD [NOT DETECTED] hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD - hash.update(data: credit_card_no) // BAD + hash.update(data: account_no) // BAD [NOT DETECTED] + hash.update(data: credit_card_no) // BAD [NOT DETECTED] } func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.SHA256() - hash.update(data: passwd) // BAD, not a computationally expensive hash + hash.update(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash.update(data: cert) // GOOD hash.update(data: encrypted_passwd) // GOOD (not sensitive) hash.update(data: account_no) // GOOD @@ -128,7 +147,7 @@ func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd : func testSHA384UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.SHA384() - hash.update(data: passwd) // BAD, not a computationally expensive hash + hash.update(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash.update(data: cert) // GOOD hash.update(data: encrypted_passwd) // GOOD (not sensitive) hash.update(data: account_no) // GOOD @@ -137,7 +156,7 @@ func testSHA384UpdateWithData(passwd : String, cert: String, encrypted_passwd : func testSHA512UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.SHA512() - hash.update(data: passwd) // BAD, not a computationally expensive hash + hash.update(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash.update(data: cert) // GOOD hash.update(data: encrypted_passwd) // GOOD (not sensitive) hash.update(data: account_no) // GOOD @@ -189,14 +208,14 @@ func testSHA512UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, hash.update(bufferPointer: credit_card_no) // GOOD } -func tesBadExample(passwordString: String) { +func testBadExample(passwordString: String) { // this is the "bad" example from the .qhelp let passwordData = Data(passwordString.utf8) - let passwordHash = Crypto.SHA512.hash(data: passwordData) // BAD, not a computationally expensive hash + let passwordHash = Crypto.SHA512.hash(data: passwordData) // BAD, not a computationally expensive hash [NOT DETECTED] // ... - if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // BAD, not a computationally expensive hash + if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // BAD, not a computationally expensive hash [NOT DETECTED] // ... } } From d9c0b9ca31a73e76916820078d45f85e007ce969 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 26 May 2026 17:14:11 +0100 Subject: [PATCH 109/226] Swift: Additional test cases for CryptoKit. --- .../Security/CWE-328/testCryptoKit.swift | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index e3f5ffc702f..06ce0bd42d3 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -219,3 +219,36 @@ func testBadExample(passwordString: String) { // ... } } + +func testWithFlowAndMetatypes(cardNumber: String) { + let value1 = Data(cardNumber.utf8); + let _digest1 = Insecure.MD5.hash(data: value1); // BAD [NOT DETECTED] + + let value2 = Data(cardNumber.utf8); + let hasher2 = Insecure.MD5.self; // metatype + let _digest2 = hasher2.hash(data: value2); // BAD [NOT DETECTED] + + let value3 = Data(cardNumber.utf8); + let _digest3 = (Insecure.MD5.self).hash(data: value3); // BAD [NOT DETECTED] + + let value4 = Data(cardNumber.utf8); + testReceiver1(value: value4); + + let value5 = Data(cardNumber.utf8); + testReceiver2(hasher: Insecure.MD5.self, value: value5); + + let value6 = Data(cardNumber.utf8); + testReceiver3(hasher: Insecure.MD5.self, value: value6); +} + +func testReceiver1(value: Data) { + let _digest = Insecure.MD5.hash(data: value); // BAD [NOT DETECTED] +} + +func testReceiver2(hasher: Insecure.MD5.Type, value: Data) { + let _digest = hasher.hash(data: value); // BAD [NOT DETECTED] +} + +func testReceiver3(hasher: H.Type, value: Data) { + let _digest = hasher.hash(data: value); // BAD [NOT DETECTED] +} From 98b7659cc175f973b06cdf64555081179f79b1b8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 20 May 2026 15:37:41 +0100 Subject: [PATCH 110/226] Swift: Add a special case sink for weak sensitive data hashing sinks that are calls through a metatype. --- .../WeakSensitiveDataHashingExtensions.qll | 18 +++++ .../CWE-328/WeakPasswordHashing.expected | 6 ++ .../CWE-328/WeakSensitiveDataHashing.expected | 66 +++++++++++++++++++ .../Security/CWE-328/testCryptoKit.swift | 34 +++++----- 4 files changed, 107 insertions(+), 17 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll index 5f0cc9d756a..a8c76879cb6 100755 --- a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll @@ -76,3 +76,21 @@ private class DefaultWeakSenitiveDataHashingSink extends WeakSensitiveDataHashin override string getAlgorithm() { result = algorithm } } + +/** + * A sink for weak sensitive data hashing through a call with a metatype qualifier. + */ +private class WeakSenitiveDataHashingMetatypeSink extends WeakSensitiveDataHashingSink { + string algorithm; + + WeakSenitiveDataHashingMetatypeSink() { + exists(CallExpr c | + c.getAnArgument().getExpr() = this.asExpr() and + algorithm = ["MD5", "SHA1"] and + c.getQualifier().getType().getFullName() = "Insecure." + algorithm + ".Type" and + c.getStaticTarget().getName() = ["hash(data:)", "update(data:)", "update(bufferPointer:)"] + ) + } + + override string getAlgorithm() { result = algorithm } +} diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected index 9db9a5f4a1c..be78d099011 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected @@ -1,5 +1,8 @@ edges nodes +| testCryptoKit.swift:84:47:84:47 | passwd | semmle.label | passwd | +| testCryptoKit.swift:90:36:90:36 | passwd | semmle.label | passwd | +| testCryptoKit.swift:96:44:96:44 | passwd | semmle.label | passwd | | testCryptoKit.swift:168:32:168:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:177:32:177:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:186:32:186:32 | passwd | semmle.label | passwd | @@ -31,6 +34,9 @@ nodes | testCryptoSwift.swift:231:9:231:9 | passwd | semmle.label | passwd | subpaths #select +| testCryptoKit.swift:84:47:84:47 | passwd | testCryptoKit.swift:84:47:84:47 | passwd | testCryptoKit.swift:84:47:84:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:84:47:84:47 | passwd | password (passwd) | +| testCryptoKit.swift:90:36:90:36 | passwd | testCryptoKit.swift:90:36:90:36 | passwd | testCryptoKit.swift:90:36:90:36 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:90:36:90:36 | passwd | password (passwd) | +| testCryptoKit.swift:96:44:96:44 | passwd | testCryptoKit.swift:96:44:96:44 | passwd | testCryptoKit.swift:96:44:96:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:96:44:96:44 | passwd | password (passwd) | | testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:168:32:168:32 | passwd | password (passwd) | | testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:177:32:177:32 | passwd | password (passwd) | | testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:186:32:186:32 | passwd | password (passwd) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected index d48bbbf4dfa..819b3e20aea 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected @@ -1,11 +1,63 @@ edges +| testCryptoKit.swift:224:18:224:38 | call to Data.init(_:) | testCryptoKit.swift:225:44:225:44 | value1 | provenance | | +| testCryptoKit.swift:224:23:224:23 | cardNumber | testCryptoKit.swift:224:23:224:34 | .utf8 | provenance | | +| testCryptoKit.swift:224:23:224:34 | .utf8 | testCryptoKit.swift:224:18:224:38 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:227:18:227:38 | call to Data.init(_:) | testCryptoKit.swift:229:39:229:39 | value2 | provenance | | +| testCryptoKit.swift:227:23:227:23 | cardNumber | testCryptoKit.swift:227:23:227:34 | .utf8 | provenance | | +| testCryptoKit.swift:227:23:227:34 | .utf8 | testCryptoKit.swift:227:18:227:38 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:231:18:231:38 | call to Data.init(_:) | testCryptoKit.swift:232:51:232:51 | value3 | provenance | | +| testCryptoKit.swift:231:23:231:23 | cardNumber | testCryptoKit.swift:231:23:231:34 | .utf8 | provenance | | +| testCryptoKit.swift:231:23:231:34 | .utf8 | testCryptoKit.swift:231:18:231:38 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:234:18:234:38 | call to Data.init(_:) | testCryptoKit.swift:235:26:235:26 | value4 | provenance | | +| testCryptoKit.swift:234:23:234:23 | cardNumber | testCryptoKit.swift:234:23:234:34 | .utf8 | provenance | | +| testCryptoKit.swift:234:23:234:34 | .utf8 | testCryptoKit.swift:234:18:234:38 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:235:26:235:26 | value4 | testCryptoKit.swift:244:20:244:27 | value | provenance | | +| testCryptoKit.swift:237:18:237:38 | call to Data.init(_:) | testCryptoKit.swift:238:53:238:53 | value5 | provenance | | +| testCryptoKit.swift:237:23:237:23 | cardNumber | testCryptoKit.swift:237:23:237:34 | .utf8 | provenance | | +| testCryptoKit.swift:237:23:237:34 | .utf8 | testCryptoKit.swift:237:18:237:38 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:238:53:238:53 | value5 | testCryptoKit.swift:248:47:248:54 | value | provenance | | +| testCryptoKit.swift:244:20:244:27 | value | testCryptoKit.swift:245:43:245:43 | value | provenance | | +| testCryptoKit.swift:248:47:248:54 | value | testCryptoKit.swift:249:37:249:37 | value | provenance | | nodes +| testCryptoKit.swift:85:43:85:43 | cert | semmle.label | cert | +| testCryptoKit.swift:87:43:87:43 | account_no | semmle.label | account_no | +| testCryptoKit.swift:88:43:88:43 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:91:36:91:36 | cert | semmle.label | cert | +| testCryptoKit.swift:93:36:93:36 | account_no | semmle.label | account_no | +| testCryptoKit.swift:94:36:94:36 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:97:44:97:44 | cert | semmle.label | cert | +| testCryptoKit.swift:99:44:99:44 | account_no | semmle.label | account_no | +| testCryptoKit.swift:100:44:100:44 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:169:32:169:32 | cert | semmle.label | cert | | testCryptoKit.swift:171:32:171:32 | account_no | semmle.label | account_no | | testCryptoKit.swift:172:32:172:32 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:178:32:178:32 | cert | semmle.label | cert | | testCryptoKit.swift:180:32:180:32 | account_no | semmle.label | account_no | | testCryptoKit.swift:181:32:181:32 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:224:18:224:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:224:23:224:23 | cardNumber | semmle.label | cardNumber | +| testCryptoKit.swift:224:23:224:34 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:225:44:225:44 | value1 | semmle.label | value1 | +| testCryptoKit.swift:227:18:227:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:227:23:227:23 | cardNumber | semmle.label | cardNumber | +| testCryptoKit.swift:227:23:227:34 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:229:39:229:39 | value2 | semmle.label | value2 | +| testCryptoKit.swift:231:18:231:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:231:23:231:23 | cardNumber | semmle.label | cardNumber | +| testCryptoKit.swift:231:23:231:34 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:232:51:232:51 | value3 | semmle.label | value3 | +| testCryptoKit.swift:234:18:234:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:234:23:234:23 | cardNumber | semmle.label | cardNumber | +| testCryptoKit.swift:234:23:234:34 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:235:26:235:26 | value4 | semmle.label | value4 | +| testCryptoKit.swift:237:18:237:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:237:23:237:23 | cardNumber | semmle.label | cardNumber | +| testCryptoKit.swift:237:23:237:34 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:238:53:238:53 | value5 | semmle.label | value5 | +| testCryptoKit.swift:244:20:244:27 | value | semmle.label | value | +| testCryptoKit.swift:245:43:245:43 | value | semmle.label | value | +| testCryptoKit.swift:248:47:248:54 | value | semmle.label | value | +| testCryptoKit.swift:249:37:249:37 | value | semmle.label | value | | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | semmle.label | phoneNumberArray | | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | semmle.label | phoneNumberArray | | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | semmle.label | phoneNumberArray | @@ -18,12 +70,26 @@ nodes | testCryptoSwift.swift:221:9:221:9 | creditCardNumber | semmle.label | creditCardNumber | subpaths #select +| testCryptoKit.swift:85:43:85:43 | cert | testCryptoKit.swift:85:43:85:43 | cert | testCryptoKit.swift:85:43:85:43 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:85:43:85:43 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:87:43:87:43 | account_no | testCryptoKit.swift:87:43:87:43 | account_no | testCryptoKit.swift:87:43:87:43 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:87:43:87:43 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:88:43:88:43 | credit_card_no | testCryptoKit.swift:88:43:88:43 | credit_card_no | testCryptoKit.swift:88:43:88:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:88:43:88:43 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:91:36:91:36 | cert | testCryptoKit.swift:91:36:91:36 | cert | testCryptoKit.swift:91:36:91:36 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:91:36:91:36 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:93:36:93:36 | account_no | testCryptoKit.swift:93:36:93:36 | account_no | testCryptoKit.swift:93:36:93:36 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:93:36:93:36 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:94:36:94:36 | credit_card_no | testCryptoKit.swift:94:36:94:36 | credit_card_no | testCryptoKit.swift:94:36:94:36 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:94:36:94:36 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:97:44:97:44 | cert | testCryptoKit.swift:97:44:97:44 | cert | testCryptoKit.swift:97:44:97:44 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:97:44:97:44 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:99:44:99:44 | account_no | testCryptoKit.swift:99:44:99:44 | account_no | testCryptoKit.swift:99:44:99:44 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:99:44:99:44 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:100:44:100:44 | credit_card_no | testCryptoKit.swift:100:44:100:44 | credit_card_no | testCryptoKit.swift:100:44:100:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:100:44:100:44 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:169:32:169:32 | cert | testCryptoKit.swift:169:32:169:32 | cert | testCryptoKit.swift:169:32:169:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:169:32:169:32 | cert | sensitive data (credential cert) | | testCryptoKit.swift:171:32:171:32 | account_no | testCryptoKit.swift:171:32:171:32 | account_no | testCryptoKit.swift:171:32:171:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:171:32:171:32 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:172:32:172:32 | credit_card_no | testCryptoKit.swift:172:32:172:32 | credit_card_no | testCryptoKit.swift:172:32:172:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:172:32:172:32 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:178:32:178:32 | cert | testCryptoKit.swift:178:32:178:32 | cert | testCryptoKit.swift:178:32:178:32 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:178:32:178:32 | cert | sensitive data (credential cert) | | testCryptoKit.swift:180:32:180:32 | account_no | testCryptoKit.swift:180:32:180:32 | account_no | testCryptoKit.swift:180:32:180:32 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:180:32:180:32 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:181:32:181:32 | credit_card_no | testCryptoKit.swift:181:32:181:32 | credit_card_no | testCryptoKit.swift:181:32:181:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:181:32:181:32 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:225:44:225:44 | value1 | testCryptoKit.swift:224:23:224:23 | cardNumber | testCryptoKit.swift:225:44:225:44 | value1 | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:224:23:224:23 | cardNumber | sensitive data (private information cardNumber) | +| testCryptoKit.swift:229:39:229:39 | value2 | testCryptoKit.swift:227:23:227:23 | cardNumber | testCryptoKit.swift:229:39:229:39 | value2 | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:227:23:227:23 | cardNumber | sensitive data (private information cardNumber) | +| testCryptoKit.swift:232:51:232:51 | value3 | testCryptoKit.swift:231:23:231:23 | cardNumber | testCryptoKit.swift:232:51:232:51 | value3 | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:231:23:231:23 | cardNumber | sensitive data (private information cardNumber) | +| testCryptoKit.swift:245:43:245:43 | value | testCryptoKit.swift:234:23:234:23 | cardNumber | testCryptoKit.swift:245:43:245:43 | value | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:234:23:234:23 | cardNumber | sensitive data (private information cardNumber) | +| testCryptoKit.swift:249:37:249:37 | value | testCryptoKit.swift:237:23:237:23 | cardNumber | testCryptoKit.swift:249:37:249:37 | value | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:237:23:237:23 | cardNumber | sensitive data (private information cardNumber) | | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | sensitive data (private information phoneNumberArray) | | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | sensitive data (private information phoneNumberArray) | | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | sensitive data (private information phoneNumberArray) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index 06ce0bd42d3..faf0f69ab12 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -81,23 +81,23 @@ enum Insecure { // --- tests --- func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { - var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD [NOT DETECTED] - hash = Crypto.Insecure.MD5.hash(data: cert) // BAD [NOT DETECTED] + var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD + hash = Crypto.Insecure.MD5.hash(data: cert) // BAD hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED] - hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD + hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD - hash = Insecure.MD5.hash(data: passwd) // BAD [NOT DETECTED] - hash = Insecure.MD5.hash(data: cert) // BAD [NOT DETECTED] + hash = Insecure.MD5.hash(data: passwd) // BAD + hash = Insecure.MD5.hash(data: cert) // BAD hash = Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED] - hash = Insecure.MD5.hash(data: credit_card_no) // BAD [NOT DETECTED] + hash = Insecure.MD5.hash(data: account_no) // BAD + hash = Insecure.MD5.hash(data: credit_card_no) // BAD - hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD [NOT DETECTED] - hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD [NOT DETECTED] + hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD + hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive) - hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD [NOT DETECTED] - hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD + hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD hash = Crypto.SHA256.hash(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash = Crypto.SHA256.hash(data: cert) // GOOD, computationally expensive hash not required @@ -222,14 +222,14 @@ func testBadExample(passwordString: String) { func testWithFlowAndMetatypes(cardNumber: String) { let value1 = Data(cardNumber.utf8); - let _digest1 = Insecure.MD5.hash(data: value1); // BAD [NOT DETECTED] + let _digest1 = Insecure.MD5.hash(data: value1); // BAD let value2 = Data(cardNumber.utf8); let hasher2 = Insecure.MD5.self; // metatype - let _digest2 = hasher2.hash(data: value2); // BAD [NOT DETECTED] + let _digest2 = hasher2.hash(data: value2); // BAD let value3 = Data(cardNumber.utf8); - let _digest3 = (Insecure.MD5.self).hash(data: value3); // BAD [NOT DETECTED] + let _digest3 = (Insecure.MD5.self).hash(data: value3); // BAD let value4 = Data(cardNumber.utf8); testReceiver1(value: value4); @@ -242,11 +242,11 @@ func testWithFlowAndMetatypes(cardNumber: String) { } func testReceiver1(value: Data) { - let _digest = Insecure.MD5.hash(data: value); // BAD [NOT DETECTED] + let _digest = Insecure.MD5.hash(data: value); // BAD } func testReceiver2(hasher: Insecure.MD5.Type, value: Data) { - let _digest = hasher.hash(data: value); // BAD [NOT DETECTED] + let _digest = hasher.hash(data: value); // BAD } func testReceiver3(hasher: H.Type, value: Data) { From 2b4ea18dfe2118141c000a17bd4cba251c85ffc7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 26 May 2026 17:33:50 +0100 Subject: [PATCH 111/226] Swift: Add a similar sink for password hashing as well. --- .../security/WeakPasswordHashingExtensions.qll | 18 ++++++++++++++++++ .../CWE-328/WeakPasswordHashing.expected | 14 ++++++++++++++ .../Security/CWE-328/testCryptoKit.swift | 10 +++++----- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll index 76ae9c21dab..80ed9774f39 100644 --- a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll @@ -111,6 +111,24 @@ private class DefaultWeakPasswordHashingSink extends WeakPasswordHashingSink { override string getAlgorithm() { result = algorithm } } +/** + * A sink for weak password hashing through a call with a metatype qualifier. + */ +private class WeakPasswordHashingMetatypeSink extends WeakPasswordHashingSink { + string algorithm; + + WeakPasswordHashingMetatypeSink() { + exists(CallExpr c | + c.getAnArgument().getExpr() = this.asExpr() and + algorithm = ["SHA256", "SHA384", "SHA512"] and + c.getQualifier().getType().getFullName() = algorithm + ".Type" and + c.getStaticTarget().getName() = ["hash(data:)", "update(data:)", "update(bufferPointer:)"] + ) + } + + override string getAlgorithm() { result = algorithm } +} + /** * A barrier for weak password hashing, when it occurs inside of * certain cryptographic algorithms as part of their design. diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected index be78d099011..0aa4b617c9c 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected @@ -1,13 +1,22 @@ edges +| testCryptoKit.swift:218:38:218:38 | passwordString | testCryptoKit.swift:218:38:218:53 | .utf8 | provenance | | +| testCryptoKit.swift:218:38:218:53 | .utf8 | testCryptoKit.swift:218:33:218:57 | call to Data.init(_:) | provenance | | nodes | testCryptoKit.swift:84:47:84:47 | passwd | semmle.label | passwd | | testCryptoKit.swift:90:36:90:36 | passwd | semmle.label | passwd | | testCryptoKit.swift:96:44:96:44 | passwd | semmle.label | passwd | +| testCryptoKit.swift:102:37:102:37 | passwd | semmle.label | passwd | +| testCryptoKit.swift:108:37:108:37 | passwd | semmle.label | passwd | +| testCryptoKit.swift:114:37:114:37 | passwd | semmle.label | passwd | | testCryptoKit.swift:168:32:168:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:177:32:177:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:186:32:186:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:195:32:195:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:204:32:204:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:214:49:214:49 | passwordData | semmle.label | passwordData | +| testCryptoKit.swift:218:33:218:57 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:218:38:218:38 | passwordString | semmle.label | passwordString | +| testCryptoKit.swift:218:38:218:53 | .utf8 | semmle.label | .utf8 | | testCryptoSwift.swift:154:30:154:30 | passwdArray | semmle.label | passwdArray | | testCryptoSwift.swift:157:31:157:31 | passwdArray | semmle.label | passwdArray | | testCryptoSwift.swift:160:47:160:47 | passwdArray | semmle.label | passwdArray | @@ -37,11 +46,16 @@ subpaths | testCryptoKit.swift:84:47:84:47 | passwd | testCryptoKit.swift:84:47:84:47 | passwd | testCryptoKit.swift:84:47:84:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:84:47:84:47 | passwd | password (passwd) | | testCryptoKit.swift:90:36:90:36 | passwd | testCryptoKit.swift:90:36:90:36 | passwd | testCryptoKit.swift:90:36:90:36 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:90:36:90:36 | passwd | password (passwd) | | testCryptoKit.swift:96:44:96:44 | passwd | testCryptoKit.swift:96:44:96:44 | passwd | testCryptoKit.swift:96:44:96:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:96:44:96:44 | passwd | password (passwd) | +| testCryptoKit.swift:102:37:102:37 | passwd | testCryptoKit.swift:102:37:102:37 | passwd | testCryptoKit.swift:102:37:102:37 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:102:37:102:37 | passwd | password (passwd) | +| testCryptoKit.swift:108:37:108:37 | passwd | testCryptoKit.swift:108:37:108:37 | passwd | testCryptoKit.swift:108:37:108:37 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:108:37:108:37 | passwd | password (passwd) | +| testCryptoKit.swift:114:37:114:37 | passwd | testCryptoKit.swift:114:37:114:37 | passwd | testCryptoKit.swift:114:37:114:37 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:114:37:114:37 | passwd | password (passwd) | | testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:168:32:168:32 | passwd | password (passwd) | | testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:177:32:177:32 | passwd | password (passwd) | | testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:186:32:186:32 | passwd | password (passwd) | | testCryptoKit.swift:195:32:195:32 | passwd | testCryptoKit.swift:195:32:195:32 | passwd | testCryptoKit.swift:195:32:195:32 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:195:32:195:32 | passwd | password (passwd) | | testCryptoKit.swift:204:32:204:32 | passwd | testCryptoKit.swift:204:32:204:32 | passwd | testCryptoKit.swift:204:32:204:32 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:204:32:204:32 | passwd | password (passwd) | +| testCryptoKit.swift:214:49:214:49 | passwordData | testCryptoKit.swift:214:49:214:49 | passwordData | testCryptoKit.swift:214:49:214:49 | passwordData | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:214:49:214:49 | passwordData | password (passwordData) | +| testCryptoKit.swift:218:33:218:57 | call to Data.init(_:) | testCryptoKit.swift:218:38:218:38 | passwordString | testCryptoKit.swift:218:33:218:57 | call to Data.init(_:) | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:218:38:218:38 | passwordString | password (passwordString) | | testCryptoSwift.swift:154:30:154:30 | passwdArray | testCryptoSwift.swift:154:30:154:30 | passwdArray | testCryptoSwift.swift:154:30:154:30 | passwdArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:154:30:154:30 | passwdArray | password (passwdArray) | | testCryptoSwift.swift:157:31:157:31 | passwdArray | testCryptoSwift.swift:157:31:157:31 | passwdArray | testCryptoSwift.swift:157:31:157:31 | passwdArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:157:31:157:31 | passwdArray | password (passwdArray) | | testCryptoSwift.swift:160:47:160:47 | passwdArray | testCryptoSwift.swift:160:47:160:47 | passwdArray | testCryptoSwift.swift:160:47:160:47 | passwdArray | Insecure hashing algorithm (SHA2) depends on $@. | testCryptoSwift.swift:160:47:160:47 | passwdArray | password (passwdArray) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index faf0f69ab12..d3ffa7282f1 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -99,19 +99,19 @@ func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_pa hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD - hash = Crypto.SHA256.hash(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] + hash = Crypto.SHA256.hash(data: passwd) // BAD, not a computationally expensive hash hash = Crypto.SHA256.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA256.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA256.hash(data: account_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA256.hash(data: credit_card_no) // GOOD, computationally expensive hash not required - hash = Crypto.SHA384.hash(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] + hash = Crypto.SHA384.hash(data: passwd) // BAD, not a computationally expensive hash hash = Crypto.SHA384.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA384.hash(data: account_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: credit_card_no) // GOOD, computationally expensive hash not required - hash = Crypto.SHA512.hash(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] + hash = Crypto.SHA512.hash(data: passwd) // BAD, not a computationally expensive hash hash = Crypto.SHA512.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA512.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA512.hash(data: account_no) // GOOD, computationally expensive hash not required @@ -211,11 +211,11 @@ func testSHA512UpdateWithUnsafeRawBufferPointer(passwd : UnsafeRawBufferPointer, func testBadExample(passwordString: String) { // this is the "bad" example from the .qhelp let passwordData = Data(passwordString.utf8) - let passwordHash = Crypto.SHA512.hash(data: passwordData) // BAD, not a computationally expensive hash [NOT DETECTED] + let passwordHash = Crypto.SHA512.hash(data: passwordData) // BAD, not a computationally expensive hash // ... - if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // BAD, not a computationally expensive hash [NOT DETECTED] + if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash { // BAD, not a computationally expensive hash // ... } } From c902c756512de679885099a09503d526addc3163 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 26 May 2026 14:02:55 +0100 Subject: [PATCH 112/226] Swift: Add change note. --- swift/ql/src/change-notes/2026-05-26-hashing-sinks.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 swift/ql/src/change-notes/2026-05-26-hashing-sinks.md diff --git a/swift/ql/src/change-notes/2026-05-26-hashing-sinks.md b/swift/ql/src/change-notes/2026-05-26-hashing-sinks.md new file mode 100644 index 00000000000..92a2c1c3a06 --- /dev/null +++ b/swift/ql/src/change-notes/2026-05-26-hashing-sinks.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Fixed an issue where common usage patterns for `CryptoKit` weren't being recognized as hashing sinks for the `swift/weak-sensitive-data-hashing` and `swift/weak-password-hashing` queries. These queries may find additional results after this change. From 94e6ec65115bca82d9263ac90d7f474d9d848f99 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 27 May 2026 10:19:06 +0100 Subject: [PATCH 113/226] Swift: Widen the new sinks to cover more cases the MaD sinks are missing. --- .../WeakPasswordHashingExtensions.qll | 2 +- .../WeakSensitiveDataHashingExtensions.qll | 2 +- .../CWE-328/WeakPasswordHashing.expected | 10 +++++++++ .../CWE-328/WeakSensitiveDataHashing.expected | 12 ++++++++++ .../Security/CWE-328/testCryptoKit.swift | 22 +++++++++---------- 5 files changed, 35 insertions(+), 13 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll index 80ed9774f39..77487610276 100644 --- a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll @@ -121,7 +121,7 @@ private class WeakPasswordHashingMetatypeSink extends WeakPasswordHashingSink { exists(CallExpr c | c.getAnArgument().getExpr() = this.asExpr() and algorithm = ["SHA256", "SHA384", "SHA512"] and - c.getQualifier().getType().getFullName() = algorithm + ".Type" and + c.getQualifier().getType().getFullName() = algorithm + ["", ".Type"] and c.getStaticTarget().getName() = ["hash(data:)", "update(data:)", "update(bufferPointer:)"] ) } diff --git a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll index a8c76879cb6..a1fcb409269 100755 --- a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll @@ -87,7 +87,7 @@ private class WeakSenitiveDataHashingMetatypeSink extends WeakSensitiveDataHashi exists(CallExpr c | c.getAnArgument().getExpr() = this.asExpr() and algorithm = ["MD5", "SHA1"] and - c.getQualifier().getType().getFullName() = "Insecure." + algorithm + ".Type" and + c.getQualifier().getType().getFullName() = "Insecure." + algorithm + ["", ".Type"] and c.getStaticTarget().getName() = ["hash(data:)", "update(data:)", "update(bufferPointer:)"] ) } diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected index 0aa4b617c9c..295467e78ab 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected @@ -8,6 +8,11 @@ nodes | testCryptoKit.swift:102:37:102:37 | passwd | semmle.label | passwd | | testCryptoKit.swift:108:37:108:37 | passwd | semmle.label | passwd | | testCryptoKit.swift:114:37:114:37 | passwd | semmle.label | passwd | +| testCryptoKit.swift:123:23:123:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:132:23:132:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:141:23:141:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:150:23:150:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:159:23:159:23 | passwd | semmle.label | passwd | | testCryptoKit.swift:168:32:168:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:177:32:177:32 | passwd | semmle.label | passwd | | testCryptoKit.swift:186:32:186:32 | passwd | semmle.label | passwd | @@ -49,6 +54,11 @@ subpaths | testCryptoKit.swift:102:37:102:37 | passwd | testCryptoKit.swift:102:37:102:37 | passwd | testCryptoKit.swift:102:37:102:37 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:102:37:102:37 | passwd | password (passwd) | | testCryptoKit.swift:108:37:108:37 | passwd | testCryptoKit.swift:108:37:108:37 | passwd | testCryptoKit.swift:108:37:108:37 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:108:37:108:37 | passwd | password (passwd) | | testCryptoKit.swift:114:37:114:37 | passwd | testCryptoKit.swift:114:37:114:37 | passwd | testCryptoKit.swift:114:37:114:37 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:114:37:114:37 | passwd | password (passwd) | +| testCryptoKit.swift:123:23:123:23 | passwd | testCryptoKit.swift:123:23:123:23 | passwd | testCryptoKit.swift:123:23:123:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:123:23:123:23 | passwd | password (passwd) | +| testCryptoKit.swift:132:23:132:23 | passwd | testCryptoKit.swift:132:23:132:23 | passwd | testCryptoKit.swift:132:23:132:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:132:23:132:23 | passwd | password (passwd) | +| testCryptoKit.swift:141:23:141:23 | passwd | testCryptoKit.swift:141:23:141:23 | passwd | testCryptoKit.swift:141:23:141:23 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:141:23:141:23 | passwd | password (passwd) | +| testCryptoKit.swift:150:23:150:23 | passwd | testCryptoKit.swift:150:23:150:23 | passwd | testCryptoKit.swift:150:23:150:23 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:150:23:150:23 | passwd | password (passwd) | +| testCryptoKit.swift:159:23:159:23 | passwd | testCryptoKit.swift:159:23:159:23 | passwd | testCryptoKit.swift:159:23:159:23 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:159:23:159:23 | passwd | password (passwd) | | testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:168:32:168:32 | passwd | password (passwd) | | testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:177:32:177:32 | passwd | password (passwd) | | testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:186:32:186:32 | passwd | password (passwd) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected index 819b3e20aea..95908a442f1 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected @@ -28,6 +28,12 @@ nodes | testCryptoKit.swift:97:44:97:44 | cert | semmle.label | cert | | testCryptoKit.swift:99:44:99:44 | account_no | semmle.label | account_no | | testCryptoKit.swift:100:44:100:44 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:124:23:124:23 | cert | semmle.label | cert | +| testCryptoKit.swift:126:23:126:23 | account_no | semmle.label | account_no | +| testCryptoKit.swift:127:23:127:23 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:133:23:133:23 | cert | semmle.label | cert | +| testCryptoKit.swift:135:23:135:23 | account_no | semmle.label | account_no | +| testCryptoKit.swift:136:23:136:23 | credit_card_no | semmle.label | credit_card_no | | testCryptoKit.swift:169:32:169:32 | cert | semmle.label | cert | | testCryptoKit.swift:171:32:171:32 | account_no | semmle.label | account_no | | testCryptoKit.swift:172:32:172:32 | credit_card_no | semmle.label | credit_card_no | @@ -79,6 +85,12 @@ subpaths | testCryptoKit.swift:97:44:97:44 | cert | testCryptoKit.swift:97:44:97:44 | cert | testCryptoKit.swift:97:44:97:44 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:97:44:97:44 | cert | sensitive data (credential cert) | | testCryptoKit.swift:99:44:99:44 | account_no | testCryptoKit.swift:99:44:99:44 | account_no | testCryptoKit.swift:99:44:99:44 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:99:44:99:44 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:100:44:100:44 | credit_card_no | testCryptoKit.swift:100:44:100:44 | credit_card_no | testCryptoKit.swift:100:44:100:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:100:44:100:44 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:124:23:124:23 | cert | testCryptoKit.swift:124:23:124:23 | cert | testCryptoKit.swift:124:23:124:23 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:124:23:124:23 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:126:23:126:23 | account_no | testCryptoKit.swift:126:23:126:23 | account_no | testCryptoKit.swift:126:23:126:23 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:126:23:126:23 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:127:23:127:23 | credit_card_no | testCryptoKit.swift:127:23:127:23 | credit_card_no | testCryptoKit.swift:127:23:127:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:127:23:127:23 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:133:23:133:23 | cert | testCryptoKit.swift:133:23:133:23 | cert | testCryptoKit.swift:133:23:133:23 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:133:23:133:23 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:135:23:135:23 | account_no | testCryptoKit.swift:135:23:135:23 | account_no | testCryptoKit.swift:135:23:135:23 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:135:23:135:23 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:136:23:136:23 | credit_card_no | testCryptoKit.swift:136:23:136:23 | credit_card_no | testCryptoKit.swift:136:23:136:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:136:23:136:23 | credit_card_no | sensitive data (private information credit_card_no) | | testCryptoKit.swift:169:32:169:32 | cert | testCryptoKit.swift:169:32:169:32 | cert | testCryptoKit.swift:169:32:169:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:169:32:169:32 | cert | sensitive data (credential cert) | | testCryptoKit.swift:171:32:171:32 | account_no | testCryptoKit.swift:171:32:171:32 | account_no | testCryptoKit.swift:171:32:171:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:171:32:171:32 | account_no | sensitive data (private information account_no) | | testCryptoKit.swift:172:32:172:32 | credit_card_no | testCryptoKit.swift:172:32:172:32 | credit_card_no | testCryptoKit.swift:172:32:172:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:172:32:172:32 | credit_card_no | sensitive data (private information credit_card_no) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index d3ffa7282f1..11dd55a9d83 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -120,25 +120,25 @@ func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_pa func testMD5UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.Insecure.MD5() - hash.update(data: passwd) // BAD [NOT DETECTED] - hash.update(data: cert) // BAD [NOT DETECTED] + hash.update(data: passwd) // BAD + hash.update(data: cert) // BAD hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD [NOT DETECTED] - hash.update(data: credit_card_no) // BAD [NOT DETECTED] + hash.update(data: account_no) // BAD + hash.update(data: credit_card_no) // BAD } func testSHA1UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.Insecure.SHA1() - hash.update(data: passwd) // BAD [NOT DETECTED] - hash.update(data: cert) // BAD [NOT DETECTED] + hash.update(data: passwd) // BAD + hash.update(data: cert) // BAD hash.update(data: encrypted_passwd) // GOOD (not sensitive) - hash.update(data: account_no) // BAD [NOT DETECTED] - hash.update(data: credit_card_no) // BAD [NOT DETECTED] + hash.update(data: account_no) // BAD + hash.update(data: credit_card_no) // BAD } func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.SHA256() - hash.update(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] + hash.update(data: passwd) // BAD, not a computationally expensive hash hash.update(data: cert) // GOOD hash.update(data: encrypted_passwd) // GOOD (not sensitive) hash.update(data: account_no) // GOOD @@ -147,7 +147,7 @@ func testSHA256UpdateWithData(passwd : String, cert: String, encrypted_passwd : func testSHA384UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.SHA384() - hash.update(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] + hash.update(data: passwd) // BAD, not a computationally expensive hash hash.update(data: cert) // GOOD hash.update(data: encrypted_passwd) // GOOD (not sensitive) hash.update(data: account_no) // GOOD @@ -156,7 +156,7 @@ func testSHA384UpdateWithData(passwd : String, cert: String, encrypted_passwd : func testSHA512UpdateWithData(passwd : String, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.SHA512() - hash.update(data: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] + hash.update(data: passwd) // BAD, not a computationally expensive hash hash.update(data: cert) // GOOD hash.update(data: encrypted_passwd) // GOOD (not sensitive) hash.update(data: account_no) // GOOD From c6c3e1474cb37291e66b1bee431086fda805ffcd Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 27 May 2026 11:15:28 +0100 Subject: [PATCH 114/226] Swift: Add a few more test cases for simple missing models. --- .../CWE-328/WeakPasswordHashing.expected | 76 ++++---- .../CWE-328/WeakSensitiveDataHashing.expected | 170 +++++++++--------- .../Security/CWE-328/testCryptoKit.swift | 6 + 3 files changed, 129 insertions(+), 123 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected index 295467e78ab..7d99c97bd4d 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected @@ -1,27 +1,27 @@ edges -| testCryptoKit.swift:218:38:218:38 | passwordString | testCryptoKit.swift:218:38:218:53 | .utf8 | provenance | | -| testCryptoKit.swift:218:38:218:53 | .utf8 | testCryptoKit.swift:218:33:218:57 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:224:38:224:38 | passwordString | testCryptoKit.swift:224:38:224:53 | .utf8 | provenance | | +| testCryptoKit.swift:224:38:224:53 | .utf8 | testCryptoKit.swift:224:33:224:57 | call to Data.init(_:) | provenance | | nodes | testCryptoKit.swift:84:47:84:47 | passwd | semmle.label | passwd | -| testCryptoKit.swift:90:36:90:36 | passwd | semmle.label | passwd | -| testCryptoKit.swift:96:44:96:44 | passwd | semmle.label | passwd | -| testCryptoKit.swift:102:37:102:37 | passwd | semmle.label | passwd | -| testCryptoKit.swift:108:37:108:37 | passwd | semmle.label | passwd | -| testCryptoKit.swift:114:37:114:37 | passwd | semmle.label | passwd | -| testCryptoKit.swift:123:23:123:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:132:23:132:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:141:23:141:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:150:23:150:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:159:23:159:23 | passwd | semmle.label | passwd | -| testCryptoKit.swift:168:32:168:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:177:32:177:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:186:32:186:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:195:32:195:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:204:32:204:32 | passwd | semmle.label | passwd | -| testCryptoKit.swift:214:49:214:49 | passwordData | semmle.label | passwordData | -| testCryptoKit.swift:218:33:218:57 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | -| testCryptoKit.swift:218:38:218:38 | passwordString | semmle.label | passwordString | -| testCryptoKit.swift:218:38:218:53 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:91:36:91:36 | passwd | semmle.label | passwd | +| testCryptoKit.swift:98:44:98:44 | passwd | semmle.label | passwd | +| testCryptoKit.swift:105:37:105:37 | passwd | semmle.label | passwd | +| testCryptoKit.swift:112:37:112:37 | passwd | semmle.label | passwd | +| testCryptoKit.swift:119:37:119:37 | passwd | semmle.label | passwd | +| testCryptoKit.swift:129:23:129:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:138:23:138:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:147:23:147:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:156:23:156:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:165:23:165:23 | passwd | semmle.label | passwd | +| testCryptoKit.swift:174:32:174:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:183:32:183:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:192:32:192:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:201:32:201:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:210:32:210:32 | passwd | semmle.label | passwd | +| testCryptoKit.swift:220:49:220:49 | passwordData | semmle.label | passwordData | +| testCryptoKit.swift:224:33:224:57 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:224:38:224:38 | passwordString | semmle.label | passwordString | +| testCryptoKit.swift:224:38:224:53 | .utf8 | semmle.label | .utf8 | | testCryptoSwift.swift:154:30:154:30 | passwdArray | semmle.label | passwdArray | | testCryptoSwift.swift:157:31:157:31 | passwdArray | semmle.label | passwdArray | | testCryptoSwift.swift:160:47:160:47 | passwdArray | semmle.label | passwdArray | @@ -49,23 +49,23 @@ nodes subpaths #select | testCryptoKit.swift:84:47:84:47 | passwd | testCryptoKit.swift:84:47:84:47 | passwd | testCryptoKit.swift:84:47:84:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:84:47:84:47 | passwd | password (passwd) | -| testCryptoKit.swift:90:36:90:36 | passwd | testCryptoKit.swift:90:36:90:36 | passwd | testCryptoKit.swift:90:36:90:36 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:90:36:90:36 | passwd | password (passwd) | -| testCryptoKit.swift:96:44:96:44 | passwd | testCryptoKit.swift:96:44:96:44 | passwd | testCryptoKit.swift:96:44:96:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:96:44:96:44 | passwd | password (passwd) | -| testCryptoKit.swift:102:37:102:37 | passwd | testCryptoKit.swift:102:37:102:37 | passwd | testCryptoKit.swift:102:37:102:37 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:102:37:102:37 | passwd | password (passwd) | -| testCryptoKit.swift:108:37:108:37 | passwd | testCryptoKit.swift:108:37:108:37 | passwd | testCryptoKit.swift:108:37:108:37 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:108:37:108:37 | passwd | password (passwd) | -| testCryptoKit.swift:114:37:114:37 | passwd | testCryptoKit.swift:114:37:114:37 | passwd | testCryptoKit.swift:114:37:114:37 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:114:37:114:37 | passwd | password (passwd) | -| testCryptoKit.swift:123:23:123:23 | passwd | testCryptoKit.swift:123:23:123:23 | passwd | testCryptoKit.swift:123:23:123:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:123:23:123:23 | passwd | password (passwd) | -| testCryptoKit.swift:132:23:132:23 | passwd | testCryptoKit.swift:132:23:132:23 | passwd | testCryptoKit.swift:132:23:132:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:132:23:132:23 | passwd | password (passwd) | -| testCryptoKit.swift:141:23:141:23 | passwd | testCryptoKit.swift:141:23:141:23 | passwd | testCryptoKit.swift:141:23:141:23 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:141:23:141:23 | passwd | password (passwd) | -| testCryptoKit.swift:150:23:150:23 | passwd | testCryptoKit.swift:150:23:150:23 | passwd | testCryptoKit.swift:150:23:150:23 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:150:23:150:23 | passwd | password (passwd) | -| testCryptoKit.swift:159:23:159:23 | passwd | testCryptoKit.swift:159:23:159:23 | passwd | testCryptoKit.swift:159:23:159:23 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:159:23:159:23 | passwd | password (passwd) | -| testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | testCryptoKit.swift:168:32:168:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:168:32:168:32 | passwd | password (passwd) | -| testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | testCryptoKit.swift:177:32:177:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:177:32:177:32 | passwd | password (passwd) | -| testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | testCryptoKit.swift:186:32:186:32 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:186:32:186:32 | passwd | password (passwd) | -| testCryptoKit.swift:195:32:195:32 | passwd | testCryptoKit.swift:195:32:195:32 | passwd | testCryptoKit.swift:195:32:195:32 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:195:32:195:32 | passwd | password (passwd) | -| testCryptoKit.swift:204:32:204:32 | passwd | testCryptoKit.swift:204:32:204:32 | passwd | testCryptoKit.swift:204:32:204:32 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:204:32:204:32 | passwd | password (passwd) | -| testCryptoKit.swift:214:49:214:49 | passwordData | testCryptoKit.swift:214:49:214:49 | passwordData | testCryptoKit.swift:214:49:214:49 | passwordData | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:214:49:214:49 | passwordData | password (passwordData) | -| testCryptoKit.swift:218:33:218:57 | call to Data.init(_:) | testCryptoKit.swift:218:38:218:38 | passwordString | testCryptoKit.swift:218:33:218:57 | call to Data.init(_:) | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:218:38:218:38 | passwordString | password (passwordString) | +| testCryptoKit.swift:91:36:91:36 | passwd | testCryptoKit.swift:91:36:91:36 | passwd | testCryptoKit.swift:91:36:91:36 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:91:36:91:36 | passwd | password (passwd) | +| testCryptoKit.swift:98:44:98:44 | passwd | testCryptoKit.swift:98:44:98:44 | passwd | testCryptoKit.swift:98:44:98:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:98:44:98:44 | passwd | password (passwd) | +| testCryptoKit.swift:105:37:105:37 | passwd | testCryptoKit.swift:105:37:105:37 | passwd | testCryptoKit.swift:105:37:105:37 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:105:37:105:37 | passwd | password (passwd) | +| testCryptoKit.swift:112:37:112:37 | passwd | testCryptoKit.swift:112:37:112:37 | passwd | testCryptoKit.swift:112:37:112:37 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:112:37:112:37 | passwd | password (passwd) | +| testCryptoKit.swift:119:37:119:37 | passwd | testCryptoKit.swift:119:37:119:37 | passwd | testCryptoKit.swift:119:37:119:37 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:119:37:119:37 | passwd | password (passwd) | +| testCryptoKit.swift:129:23:129:23 | passwd | testCryptoKit.swift:129:23:129:23 | passwd | testCryptoKit.swift:129:23:129:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:129:23:129:23 | passwd | password (passwd) | +| testCryptoKit.swift:138:23:138:23 | passwd | testCryptoKit.swift:138:23:138:23 | passwd | testCryptoKit.swift:138:23:138:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:138:23:138:23 | passwd | password (passwd) | +| testCryptoKit.swift:147:23:147:23 | passwd | testCryptoKit.swift:147:23:147:23 | passwd | testCryptoKit.swift:147:23:147:23 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:147:23:147:23 | passwd | password (passwd) | +| testCryptoKit.swift:156:23:156:23 | passwd | testCryptoKit.swift:156:23:156:23 | passwd | testCryptoKit.swift:156:23:156:23 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:156:23:156:23 | passwd | password (passwd) | +| testCryptoKit.swift:165:23:165:23 | passwd | testCryptoKit.swift:165:23:165:23 | passwd | testCryptoKit.swift:165:23:165:23 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:165:23:165:23 | passwd | password (passwd) | +| testCryptoKit.swift:174:32:174:32 | passwd | testCryptoKit.swift:174:32:174:32 | passwd | testCryptoKit.swift:174:32:174:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:174:32:174:32 | passwd | password (passwd) | +| testCryptoKit.swift:183:32:183:32 | passwd | testCryptoKit.swift:183:32:183:32 | passwd | testCryptoKit.swift:183:32:183:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:183:32:183:32 | passwd | password (passwd) | +| testCryptoKit.swift:192:32:192:32 | passwd | testCryptoKit.swift:192:32:192:32 | passwd | testCryptoKit.swift:192:32:192:32 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:192:32:192:32 | passwd | password (passwd) | +| testCryptoKit.swift:201:32:201:32 | passwd | testCryptoKit.swift:201:32:201:32 | passwd | testCryptoKit.swift:201:32:201:32 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:201:32:201:32 | passwd | password (passwd) | +| testCryptoKit.swift:210:32:210:32 | passwd | testCryptoKit.swift:210:32:210:32 | passwd | testCryptoKit.swift:210:32:210:32 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:210:32:210:32 | passwd | password (passwd) | +| testCryptoKit.swift:220:49:220:49 | passwordData | testCryptoKit.swift:220:49:220:49 | passwordData | testCryptoKit.swift:220:49:220:49 | passwordData | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:220:49:220:49 | passwordData | password (passwordData) | +| testCryptoKit.swift:224:33:224:57 | call to Data.init(_:) | testCryptoKit.swift:224:38:224:38 | passwordString | testCryptoKit.swift:224:33:224:57 | call to Data.init(_:) | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:224:38:224:38 | passwordString | password (passwordString) | | testCryptoSwift.swift:154:30:154:30 | passwdArray | testCryptoSwift.swift:154:30:154:30 | passwdArray | testCryptoSwift.swift:154:30:154:30 | passwdArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:154:30:154:30 | passwdArray | password (passwdArray) | | testCryptoSwift.swift:157:31:157:31 | passwdArray | testCryptoSwift.swift:157:31:157:31 | passwdArray | testCryptoSwift.swift:157:31:157:31 | passwdArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:157:31:157:31 | passwdArray | password (passwdArray) | | testCryptoSwift.swift:160:47:160:47 | passwdArray | testCryptoSwift.swift:160:47:160:47 | passwdArray | testCryptoSwift.swift:160:47:160:47 | passwdArray | Insecure hashing algorithm (SHA2) depends on $@. | testCryptoSwift.swift:160:47:160:47 | passwdArray | password (passwdArray) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected index 95908a442f1..ebb8154b0f8 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected @@ -1,69 +1,69 @@ edges -| testCryptoKit.swift:224:18:224:38 | call to Data.init(_:) | testCryptoKit.swift:225:44:225:44 | value1 | provenance | | -| testCryptoKit.swift:224:23:224:23 | cardNumber | testCryptoKit.swift:224:23:224:34 | .utf8 | provenance | | -| testCryptoKit.swift:224:23:224:34 | .utf8 | testCryptoKit.swift:224:18:224:38 | call to Data.init(_:) | provenance | | -| testCryptoKit.swift:227:18:227:38 | call to Data.init(_:) | testCryptoKit.swift:229:39:229:39 | value2 | provenance | | -| testCryptoKit.swift:227:23:227:23 | cardNumber | testCryptoKit.swift:227:23:227:34 | .utf8 | provenance | | -| testCryptoKit.swift:227:23:227:34 | .utf8 | testCryptoKit.swift:227:18:227:38 | call to Data.init(_:) | provenance | | -| testCryptoKit.swift:231:18:231:38 | call to Data.init(_:) | testCryptoKit.swift:232:51:232:51 | value3 | provenance | | -| testCryptoKit.swift:231:23:231:23 | cardNumber | testCryptoKit.swift:231:23:231:34 | .utf8 | provenance | | -| testCryptoKit.swift:231:23:231:34 | .utf8 | testCryptoKit.swift:231:18:231:38 | call to Data.init(_:) | provenance | | -| testCryptoKit.swift:234:18:234:38 | call to Data.init(_:) | testCryptoKit.swift:235:26:235:26 | value4 | provenance | | -| testCryptoKit.swift:234:23:234:23 | cardNumber | testCryptoKit.swift:234:23:234:34 | .utf8 | provenance | | -| testCryptoKit.swift:234:23:234:34 | .utf8 | testCryptoKit.swift:234:18:234:38 | call to Data.init(_:) | provenance | | -| testCryptoKit.swift:235:26:235:26 | value4 | testCryptoKit.swift:244:20:244:27 | value | provenance | | -| testCryptoKit.swift:237:18:237:38 | call to Data.init(_:) | testCryptoKit.swift:238:53:238:53 | value5 | provenance | | +| testCryptoKit.swift:230:18:230:38 | call to Data.init(_:) | testCryptoKit.swift:231:44:231:44 | value1 | provenance | | +| testCryptoKit.swift:230:23:230:23 | cardNumber | testCryptoKit.swift:230:23:230:34 | .utf8 | provenance | | +| testCryptoKit.swift:230:23:230:34 | .utf8 | testCryptoKit.swift:230:18:230:38 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:233:18:233:38 | call to Data.init(_:) | testCryptoKit.swift:235:39:235:39 | value2 | provenance | | +| testCryptoKit.swift:233:23:233:23 | cardNumber | testCryptoKit.swift:233:23:233:34 | .utf8 | provenance | | +| testCryptoKit.swift:233:23:233:34 | .utf8 | testCryptoKit.swift:233:18:233:38 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:237:18:237:38 | call to Data.init(_:) | testCryptoKit.swift:238:51:238:51 | value3 | provenance | | | testCryptoKit.swift:237:23:237:23 | cardNumber | testCryptoKit.swift:237:23:237:34 | .utf8 | provenance | | | testCryptoKit.swift:237:23:237:34 | .utf8 | testCryptoKit.swift:237:18:237:38 | call to Data.init(_:) | provenance | | -| testCryptoKit.swift:238:53:238:53 | value5 | testCryptoKit.swift:248:47:248:54 | value | provenance | | -| testCryptoKit.swift:244:20:244:27 | value | testCryptoKit.swift:245:43:245:43 | value | provenance | | -| testCryptoKit.swift:248:47:248:54 | value | testCryptoKit.swift:249:37:249:37 | value | provenance | | +| testCryptoKit.swift:240:18:240:38 | call to Data.init(_:) | testCryptoKit.swift:241:26:241:26 | value4 | provenance | | +| testCryptoKit.swift:240:23:240:23 | cardNumber | testCryptoKit.swift:240:23:240:34 | .utf8 | provenance | | +| testCryptoKit.swift:240:23:240:34 | .utf8 | testCryptoKit.swift:240:18:240:38 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:241:26:241:26 | value4 | testCryptoKit.swift:250:20:250:27 | value | provenance | | +| testCryptoKit.swift:243:18:243:38 | call to Data.init(_:) | testCryptoKit.swift:244:53:244:53 | value5 | provenance | | +| testCryptoKit.swift:243:23:243:23 | cardNumber | testCryptoKit.swift:243:23:243:34 | .utf8 | provenance | | +| testCryptoKit.swift:243:23:243:34 | .utf8 | testCryptoKit.swift:243:18:243:38 | call to Data.init(_:) | provenance | | +| testCryptoKit.swift:244:53:244:53 | value5 | testCryptoKit.swift:254:47:254:54 | value | provenance | | +| testCryptoKit.swift:250:20:250:27 | value | testCryptoKit.swift:251:43:251:43 | value | provenance | | +| testCryptoKit.swift:254:47:254:54 | value | testCryptoKit.swift:255:37:255:37 | value | provenance | | nodes -| testCryptoKit.swift:85:43:85:43 | cert | semmle.label | cert | -| testCryptoKit.swift:87:43:87:43 | account_no | semmle.label | account_no | -| testCryptoKit.swift:88:43:88:43 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:91:36:91:36 | cert | semmle.label | cert | -| testCryptoKit.swift:93:36:93:36 | account_no | semmle.label | account_no | -| testCryptoKit.swift:94:36:94:36 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:97:44:97:44 | cert | semmle.label | cert | -| testCryptoKit.swift:99:44:99:44 | account_no | semmle.label | account_no | -| testCryptoKit.swift:100:44:100:44 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:124:23:124:23 | cert | semmle.label | cert | -| testCryptoKit.swift:126:23:126:23 | account_no | semmle.label | account_no | -| testCryptoKit.swift:127:23:127:23 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:133:23:133:23 | cert | semmle.label | cert | -| testCryptoKit.swift:135:23:135:23 | account_no | semmle.label | account_no | -| testCryptoKit.swift:136:23:136:23 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:169:32:169:32 | cert | semmle.label | cert | -| testCryptoKit.swift:171:32:171:32 | account_no | semmle.label | account_no | -| testCryptoKit.swift:172:32:172:32 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:178:32:178:32 | cert | semmle.label | cert | -| testCryptoKit.swift:180:32:180:32 | account_no | semmle.label | account_no | -| testCryptoKit.swift:181:32:181:32 | credit_card_no | semmle.label | credit_card_no | -| testCryptoKit.swift:224:18:224:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | -| testCryptoKit.swift:224:23:224:23 | cardNumber | semmle.label | cardNumber | -| testCryptoKit.swift:224:23:224:34 | .utf8 | semmle.label | .utf8 | -| testCryptoKit.swift:225:44:225:44 | value1 | semmle.label | value1 | -| testCryptoKit.swift:227:18:227:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | -| testCryptoKit.swift:227:23:227:23 | cardNumber | semmle.label | cardNumber | -| testCryptoKit.swift:227:23:227:34 | .utf8 | semmle.label | .utf8 | -| testCryptoKit.swift:229:39:229:39 | value2 | semmle.label | value2 | -| testCryptoKit.swift:231:18:231:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | -| testCryptoKit.swift:231:23:231:23 | cardNumber | semmle.label | cardNumber | -| testCryptoKit.swift:231:23:231:34 | .utf8 | semmle.label | .utf8 | -| testCryptoKit.swift:232:51:232:51 | value3 | semmle.label | value3 | -| testCryptoKit.swift:234:18:234:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | -| testCryptoKit.swift:234:23:234:23 | cardNumber | semmle.label | cardNumber | -| testCryptoKit.swift:234:23:234:34 | .utf8 | semmle.label | .utf8 | -| testCryptoKit.swift:235:26:235:26 | value4 | semmle.label | value4 | +| testCryptoKit.swift:86:43:86:43 | cert | semmle.label | cert | +| testCryptoKit.swift:88:43:88:43 | account_no | semmle.label | account_no | +| testCryptoKit.swift:89:43:89:43 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:93:36:93:36 | cert | semmle.label | cert | +| testCryptoKit.swift:95:36:95:36 | account_no | semmle.label | account_no | +| testCryptoKit.swift:96:36:96:36 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:100:44:100:44 | cert | semmle.label | cert | +| testCryptoKit.swift:102:44:102:44 | account_no | semmle.label | account_no | +| testCryptoKit.swift:103:44:103:44 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:130:23:130:23 | cert | semmle.label | cert | +| testCryptoKit.swift:132:23:132:23 | account_no | semmle.label | account_no | +| testCryptoKit.swift:133:23:133:23 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:139:23:139:23 | cert | semmle.label | cert | +| testCryptoKit.swift:141:23:141:23 | account_no | semmle.label | account_no | +| testCryptoKit.swift:142:23:142:23 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:175:32:175:32 | cert | semmle.label | cert | +| testCryptoKit.swift:177:32:177:32 | account_no | semmle.label | account_no | +| testCryptoKit.swift:178:32:178:32 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:184:32:184:32 | cert | semmle.label | cert | +| testCryptoKit.swift:186:32:186:32 | account_no | semmle.label | account_no | +| testCryptoKit.swift:187:32:187:32 | credit_card_no | semmle.label | credit_card_no | +| testCryptoKit.swift:230:18:230:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:230:23:230:23 | cardNumber | semmle.label | cardNumber | +| testCryptoKit.swift:230:23:230:34 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:231:44:231:44 | value1 | semmle.label | value1 | +| testCryptoKit.swift:233:18:233:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:233:23:233:23 | cardNumber | semmle.label | cardNumber | +| testCryptoKit.swift:233:23:233:34 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:235:39:235:39 | value2 | semmle.label | value2 | | testCryptoKit.swift:237:18:237:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | | testCryptoKit.swift:237:23:237:23 | cardNumber | semmle.label | cardNumber | | testCryptoKit.swift:237:23:237:34 | .utf8 | semmle.label | .utf8 | -| testCryptoKit.swift:238:53:238:53 | value5 | semmle.label | value5 | -| testCryptoKit.swift:244:20:244:27 | value | semmle.label | value | -| testCryptoKit.swift:245:43:245:43 | value | semmle.label | value | -| testCryptoKit.swift:248:47:248:54 | value | semmle.label | value | -| testCryptoKit.swift:249:37:249:37 | value | semmle.label | value | +| testCryptoKit.swift:238:51:238:51 | value3 | semmle.label | value3 | +| testCryptoKit.swift:240:18:240:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:240:23:240:23 | cardNumber | semmle.label | cardNumber | +| testCryptoKit.swift:240:23:240:34 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:241:26:241:26 | value4 | semmle.label | value4 | +| testCryptoKit.swift:243:18:243:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | +| testCryptoKit.swift:243:23:243:23 | cardNumber | semmle.label | cardNumber | +| testCryptoKit.swift:243:23:243:34 | .utf8 | semmle.label | .utf8 | +| testCryptoKit.swift:244:53:244:53 | value5 | semmle.label | value5 | +| testCryptoKit.swift:250:20:250:27 | value | semmle.label | value | +| testCryptoKit.swift:251:43:251:43 | value | semmle.label | value | +| testCryptoKit.swift:254:47:254:54 | value | semmle.label | value | +| testCryptoKit.swift:255:37:255:37 | value | semmle.label | value | | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | semmle.label | phoneNumberArray | | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | semmle.label | phoneNumberArray | | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | semmle.label | phoneNumberArray | @@ -76,32 +76,32 @@ nodes | testCryptoSwift.swift:221:9:221:9 | creditCardNumber | semmle.label | creditCardNumber | subpaths #select -| testCryptoKit.swift:85:43:85:43 | cert | testCryptoKit.swift:85:43:85:43 | cert | testCryptoKit.swift:85:43:85:43 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:85:43:85:43 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:87:43:87:43 | account_no | testCryptoKit.swift:87:43:87:43 | account_no | testCryptoKit.swift:87:43:87:43 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:87:43:87:43 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:88:43:88:43 | credit_card_no | testCryptoKit.swift:88:43:88:43 | credit_card_no | testCryptoKit.swift:88:43:88:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:88:43:88:43 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:91:36:91:36 | cert | testCryptoKit.swift:91:36:91:36 | cert | testCryptoKit.swift:91:36:91:36 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:91:36:91:36 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:93:36:93:36 | account_no | testCryptoKit.swift:93:36:93:36 | account_no | testCryptoKit.swift:93:36:93:36 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:93:36:93:36 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:94:36:94:36 | credit_card_no | testCryptoKit.swift:94:36:94:36 | credit_card_no | testCryptoKit.swift:94:36:94:36 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:94:36:94:36 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:97:44:97:44 | cert | testCryptoKit.swift:97:44:97:44 | cert | testCryptoKit.swift:97:44:97:44 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:97:44:97:44 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:99:44:99:44 | account_no | testCryptoKit.swift:99:44:99:44 | account_no | testCryptoKit.swift:99:44:99:44 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:99:44:99:44 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:100:44:100:44 | credit_card_no | testCryptoKit.swift:100:44:100:44 | credit_card_no | testCryptoKit.swift:100:44:100:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:100:44:100:44 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:124:23:124:23 | cert | testCryptoKit.swift:124:23:124:23 | cert | testCryptoKit.swift:124:23:124:23 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:124:23:124:23 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:126:23:126:23 | account_no | testCryptoKit.swift:126:23:126:23 | account_no | testCryptoKit.swift:126:23:126:23 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:126:23:126:23 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:127:23:127:23 | credit_card_no | testCryptoKit.swift:127:23:127:23 | credit_card_no | testCryptoKit.swift:127:23:127:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:127:23:127:23 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:133:23:133:23 | cert | testCryptoKit.swift:133:23:133:23 | cert | testCryptoKit.swift:133:23:133:23 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:133:23:133:23 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:135:23:135:23 | account_no | testCryptoKit.swift:135:23:135:23 | account_no | testCryptoKit.swift:135:23:135:23 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:135:23:135:23 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:136:23:136:23 | credit_card_no | testCryptoKit.swift:136:23:136:23 | credit_card_no | testCryptoKit.swift:136:23:136:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:136:23:136:23 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:169:32:169:32 | cert | testCryptoKit.swift:169:32:169:32 | cert | testCryptoKit.swift:169:32:169:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:169:32:169:32 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:171:32:171:32 | account_no | testCryptoKit.swift:171:32:171:32 | account_no | testCryptoKit.swift:171:32:171:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:171:32:171:32 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:172:32:172:32 | credit_card_no | testCryptoKit.swift:172:32:172:32 | credit_card_no | testCryptoKit.swift:172:32:172:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:172:32:172:32 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:178:32:178:32 | cert | testCryptoKit.swift:178:32:178:32 | cert | testCryptoKit.swift:178:32:178:32 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:178:32:178:32 | cert | sensitive data (credential cert) | -| testCryptoKit.swift:180:32:180:32 | account_no | testCryptoKit.swift:180:32:180:32 | account_no | testCryptoKit.swift:180:32:180:32 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:180:32:180:32 | account_no | sensitive data (private information account_no) | -| testCryptoKit.swift:181:32:181:32 | credit_card_no | testCryptoKit.swift:181:32:181:32 | credit_card_no | testCryptoKit.swift:181:32:181:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:181:32:181:32 | credit_card_no | sensitive data (private information credit_card_no) | -| testCryptoKit.swift:225:44:225:44 | value1 | testCryptoKit.swift:224:23:224:23 | cardNumber | testCryptoKit.swift:225:44:225:44 | value1 | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:224:23:224:23 | cardNumber | sensitive data (private information cardNumber) | -| testCryptoKit.swift:229:39:229:39 | value2 | testCryptoKit.swift:227:23:227:23 | cardNumber | testCryptoKit.swift:229:39:229:39 | value2 | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:227:23:227:23 | cardNumber | sensitive data (private information cardNumber) | -| testCryptoKit.swift:232:51:232:51 | value3 | testCryptoKit.swift:231:23:231:23 | cardNumber | testCryptoKit.swift:232:51:232:51 | value3 | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:231:23:231:23 | cardNumber | sensitive data (private information cardNumber) | -| testCryptoKit.swift:245:43:245:43 | value | testCryptoKit.swift:234:23:234:23 | cardNumber | testCryptoKit.swift:245:43:245:43 | value | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:234:23:234:23 | cardNumber | sensitive data (private information cardNumber) | -| testCryptoKit.swift:249:37:249:37 | value | testCryptoKit.swift:237:23:237:23 | cardNumber | testCryptoKit.swift:249:37:249:37 | value | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:237:23:237:23 | cardNumber | sensitive data (private information cardNumber) | +| testCryptoKit.swift:86:43:86:43 | cert | testCryptoKit.swift:86:43:86:43 | cert | testCryptoKit.swift:86:43:86:43 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:86:43:86:43 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:88:43:88:43 | account_no | testCryptoKit.swift:88:43:88:43 | account_no | testCryptoKit.swift:88:43:88:43 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:88:43:88:43 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:89:43:89:43 | credit_card_no | testCryptoKit.swift:89:43:89:43 | credit_card_no | testCryptoKit.swift:89:43:89:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:89:43:89:43 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:93:36:93:36 | cert | testCryptoKit.swift:93:36:93:36 | cert | testCryptoKit.swift:93:36:93:36 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:93:36:93:36 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:95:36:95:36 | account_no | testCryptoKit.swift:95:36:95:36 | account_no | testCryptoKit.swift:95:36:95:36 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:95:36:95:36 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:96:36:96:36 | credit_card_no | testCryptoKit.swift:96:36:96:36 | credit_card_no | testCryptoKit.swift:96:36:96:36 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:96:36:96:36 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:100:44:100:44 | cert | testCryptoKit.swift:100:44:100:44 | cert | testCryptoKit.swift:100:44:100:44 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:100:44:100:44 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:102:44:102:44 | account_no | testCryptoKit.swift:102:44:102:44 | account_no | testCryptoKit.swift:102:44:102:44 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:102:44:102:44 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:103:44:103:44 | credit_card_no | testCryptoKit.swift:103:44:103:44 | credit_card_no | testCryptoKit.swift:103:44:103:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:103:44:103:44 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:130:23:130:23 | cert | testCryptoKit.swift:130:23:130:23 | cert | testCryptoKit.swift:130:23:130:23 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:130:23:130:23 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:132:23:132:23 | account_no | testCryptoKit.swift:132:23:132:23 | account_no | testCryptoKit.swift:132:23:132:23 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:132:23:132:23 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:133:23:133:23 | credit_card_no | testCryptoKit.swift:133:23:133:23 | credit_card_no | testCryptoKit.swift:133:23:133:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:133:23:133:23 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:139:23:139:23 | cert | testCryptoKit.swift:139:23:139:23 | cert | testCryptoKit.swift:139:23:139:23 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:139:23:139:23 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:141:23:141:23 | account_no | testCryptoKit.swift:141:23:141:23 | account_no | testCryptoKit.swift:141:23:141:23 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:141:23:141:23 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:142:23:142:23 | credit_card_no | testCryptoKit.swift:142:23:142:23 | credit_card_no | testCryptoKit.swift:142:23:142:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:142:23:142:23 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:175:32:175:32 | cert | testCryptoKit.swift:175:32:175:32 | cert | testCryptoKit.swift:175:32:175:32 | cert | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:175:32:175:32 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:177:32:177:32 | account_no | testCryptoKit.swift:177:32:177:32 | account_no | testCryptoKit.swift:177:32:177:32 | account_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:177:32:177:32 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:178:32:178:32 | credit_card_no | testCryptoKit.swift:178:32:178:32 | credit_card_no | testCryptoKit.swift:178:32:178:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:178:32:178:32 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:184:32:184:32 | cert | testCryptoKit.swift:184:32:184:32 | cert | testCryptoKit.swift:184:32:184:32 | cert | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:184:32:184:32 | cert | sensitive data (credential cert) | +| testCryptoKit.swift:186:32:186:32 | account_no | testCryptoKit.swift:186:32:186:32 | account_no | testCryptoKit.swift:186:32:186:32 | account_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:186:32:186:32 | account_no | sensitive data (private information account_no) | +| testCryptoKit.swift:187:32:187:32 | credit_card_no | testCryptoKit.swift:187:32:187:32 | credit_card_no | testCryptoKit.swift:187:32:187:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:187:32:187:32 | credit_card_no | sensitive data (private information credit_card_no) | +| testCryptoKit.swift:231:44:231:44 | value1 | testCryptoKit.swift:230:23:230:23 | cardNumber | testCryptoKit.swift:231:44:231:44 | value1 | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:230:23:230:23 | cardNumber | sensitive data (private information cardNumber) | +| testCryptoKit.swift:235:39:235:39 | value2 | testCryptoKit.swift:233:23:233:23 | cardNumber | testCryptoKit.swift:235:39:235:39 | value2 | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:233:23:233:23 | cardNumber | sensitive data (private information cardNumber) | +| testCryptoKit.swift:238:51:238:51 | value3 | testCryptoKit.swift:237:23:237:23 | cardNumber | testCryptoKit.swift:238:51:238:51 | value3 | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:237:23:237:23 | cardNumber | sensitive data (private information cardNumber) | +| testCryptoKit.swift:251:43:251:43 | value | testCryptoKit.swift:240:23:240:23 | cardNumber | testCryptoKit.swift:251:43:251:43 | value | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:240:23:240:23 | cardNumber | sensitive data (private information cardNumber) | +| testCryptoKit.swift:255:37:255:37 | value | testCryptoKit.swift:243:23:243:23 | cardNumber | testCryptoKit.swift:255:37:255:37 | value | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:243:23:243:23 | cardNumber | sensitive data (private information cardNumber) | | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:153:30:153:30 | phoneNumberArray | sensitive data (private information phoneNumberArray) | | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoSwift.swift:156:31:156:31 | phoneNumberArray | sensitive data (private information phoneNumberArray) | | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | Insecure hashing algorithm (MD5) depends on $@. | testCryptoSwift.swift:166:20:166:20 | phoneNumberArray | sensitive data (private information phoneNumberArray) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index 11dd55a9d83..32a5dfa1f34 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -82,36 +82,42 @@ enum Insecure { func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD + hash = Crypto.Insecure.MD5.hash(bufferPointer: passwd) // BAD [NOT DETECTED] hash = Crypto.Insecure.MD5.hash(data: cert) // BAD hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD hash = Insecure.MD5.hash(data: passwd) // BAD + hash = Insecure.MD5.hash(bufferPointer: passwd) // BAD [NOT DETECTED] hash = Insecure.MD5.hash(data: cert) // BAD hash = Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) hash = Insecure.MD5.hash(data: account_no) // BAD hash = Insecure.MD5.hash(data: credit_card_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD + hash = Crypto.Insecure.SHA1.hash(bufferPointer: passwd) // BAD [NOT DETECTED] hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive) hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD hash = Crypto.SHA256.hash(data: passwd) // BAD, not a computationally expensive hash + hash = Crypto.SHA256.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash = Crypto.SHA256.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA256.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA256.hash(data: account_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA256.hash(data: credit_card_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: passwd) // BAD, not a computationally expensive hash + hash = Crypto.SHA384.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash = Crypto.SHA384.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA384.hash(data: account_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: credit_card_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA512.hash(data: passwd) // BAD, not a computationally expensive hash + hash = Crypto.SHA512.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] hash = Crypto.SHA512.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA512.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA512.hash(data: account_no) // GOOD, computationally expensive hash not required From f962eac9145e345a34b8064a6a4ce16fd093d53a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 26 May 2026 17:54:51 +0100 Subject: [PATCH 115/226] Swift: Fill the simple gaps in modelling. --- .../swift/security/WeakPasswordHashingExtensions.qll | 5 ++++- .../security/WeakSensitiveDataHashingExtensions.qll | 4 +++- .../Security/CWE-328/WeakPasswordHashing.expected | 12 ++++++++++++ .../query-tests/Security/CWE-328/testCryptoKit.swift | 12 ++++++------ 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll index 77487610276..8718e031e71 100644 --- a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll @@ -54,12 +54,15 @@ private class WeakSensitiveDataHashingSinks extends SinkModelCsv { // CryptoKit // (SHA-256, SHA-384 and SHA-512 are all variants of the SHA-2 algorithm) ";SHA256;true;hash(data:);;;Argument[0];weak-password-hash-input-SHA256", + ";SHA256;true;hash(bufferPointer:);;;Argument[0];weak-password-hash-input-SHA256", ";SHA256;true;update(data:);;;Argument[0];weak-password-hash-input-SHA256", ";SHA256;true;update(bufferPointer:);;;Argument[0];weak-password-hash-input-SHA256", ";SHA384;true;hash(data:);;;Argument[0];weak-password-hash-input-SHA384", + ";SHA384;true;hash(bufferPointer:);;;Argument[0];weak-password-hash-input-SHA384", ";SHA384;true;update(data:);;;Argument[0];weak-password-hash-input-SHA384", ";SHA384;true;update(bufferPointer:);;;Argument[0];weak-password-hash-input-SHA384", ";SHA512;true;hash(data:);;;Argument[0];weak-password-hash-input-SHA512", + ";SHA512;true;hash(bufferPointer:);;;Argument[0];weak-password-hash-input-SHA512", ";SHA512;true;update(data:);;;Argument[0];weak-password-hash-input-SHA512", ";SHA512;true;update(bufferPointer:);;;Argument[0];weak-password-hash-input-SHA512", // CryptoSwift @@ -122,7 +125,7 @@ private class WeakPasswordHashingMetatypeSink extends WeakPasswordHashingSink { c.getAnArgument().getExpr() = this.asExpr() and algorithm = ["SHA256", "SHA384", "SHA512"] and c.getQualifier().getType().getFullName() = algorithm + ["", ".Type"] and - c.getStaticTarget().getName() = ["hash(data:)", "update(data:)", "update(bufferPointer:)"] + c.getStaticTarget().getName() = ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] ) } diff --git a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll index a1fcb409269..dcb32995747 100755 --- a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll @@ -40,9 +40,11 @@ private class WeakSensitiveDataHashingSinks extends SinkModelCsv { [ // CryptoKit ";Insecure.MD5;true;hash(data:);;;Argument[0];weak-hash-input-MD5", + ";Insecure.MD5;true;hash(bufferPointer:);;;Argument[0];weak-hash-input-MD5", ";Insecure.MD5;true;update(data:);;;Argument[0];weak-hash-input-MD5", ";Insecure.MD5;true;update(bufferPointer:);;;Argument[0];weak-hash-input-MD5", ";Insecure.SHA1;true;hash(data:);;;Argument[0];weak-hash-input-SHA1", + ";Insecure.SHA1;true;hash(bufferPointer:);;;Argument[0];weak-hash-input-SHA1", ";Insecure.SHA1;true;update(data:);;;Argument[0];weak-hash-input-SHA1", ";Insecure.SHA1;true;update(bufferPointer:);;;Argument[0];weak-hash-input-SHA1", // CryptoSwift @@ -88,7 +90,7 @@ private class WeakSenitiveDataHashingMetatypeSink extends WeakSensitiveDataHashi c.getAnArgument().getExpr() = this.asExpr() and algorithm = ["MD5", "SHA1"] and c.getQualifier().getType().getFullName() = "Insecure." + algorithm + ["", ".Type"] and - c.getStaticTarget().getName() = ["hash(data:)", "update(data:)", "update(bufferPointer:)"] + c.getStaticTarget().getName() = ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] ) } diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected index 7d99c97bd4d..273f26164fd 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakPasswordHashing.expected @@ -3,11 +3,17 @@ edges | testCryptoKit.swift:224:38:224:53 | .utf8 | testCryptoKit.swift:224:33:224:57 | call to Data.init(_:) | provenance | | nodes | testCryptoKit.swift:84:47:84:47 | passwd | semmle.label | passwd | +| testCryptoKit.swift:85:52:85:52 | passwd | semmle.label | passwd | | testCryptoKit.swift:91:36:91:36 | passwd | semmle.label | passwd | +| testCryptoKit.swift:92:45:92:45 | passwd | semmle.label | passwd | | testCryptoKit.swift:98:44:98:44 | passwd | semmle.label | passwd | +| testCryptoKit.swift:99:53:99:53 | passwd | semmle.label | passwd | | testCryptoKit.swift:105:37:105:37 | passwd | semmle.label | passwd | +| testCryptoKit.swift:106:46:106:46 | passwd | semmle.label | passwd | | testCryptoKit.swift:112:37:112:37 | passwd | semmle.label | passwd | +| testCryptoKit.swift:113:46:113:46 | passwd | semmle.label | passwd | | testCryptoKit.swift:119:37:119:37 | passwd | semmle.label | passwd | +| testCryptoKit.swift:120:46:120:46 | passwd | semmle.label | passwd | | testCryptoKit.swift:129:23:129:23 | passwd | semmle.label | passwd | | testCryptoKit.swift:138:23:138:23 | passwd | semmle.label | passwd | | testCryptoKit.swift:147:23:147:23 | passwd | semmle.label | passwd | @@ -49,11 +55,17 @@ nodes subpaths #select | testCryptoKit.swift:84:47:84:47 | passwd | testCryptoKit.swift:84:47:84:47 | passwd | testCryptoKit.swift:84:47:84:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:84:47:84:47 | passwd | password (passwd) | +| testCryptoKit.swift:85:52:85:52 | passwd | testCryptoKit.swift:85:52:85:52 | passwd | testCryptoKit.swift:85:52:85:52 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:85:52:85:52 | passwd | password (passwd) | | testCryptoKit.swift:91:36:91:36 | passwd | testCryptoKit.swift:91:36:91:36 | passwd | testCryptoKit.swift:91:36:91:36 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:91:36:91:36 | passwd | password (passwd) | +| testCryptoKit.swift:92:45:92:45 | passwd | testCryptoKit.swift:92:45:92:45 | passwd | testCryptoKit.swift:92:45:92:45 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:92:45:92:45 | passwd | password (passwd) | | testCryptoKit.swift:98:44:98:44 | passwd | testCryptoKit.swift:98:44:98:44 | passwd | testCryptoKit.swift:98:44:98:44 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:98:44:98:44 | passwd | password (passwd) | +| testCryptoKit.swift:99:53:99:53 | passwd | testCryptoKit.swift:99:53:99:53 | passwd | testCryptoKit.swift:99:53:99:53 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:99:53:99:53 | passwd | password (passwd) | | testCryptoKit.swift:105:37:105:37 | passwd | testCryptoKit.swift:105:37:105:37 | passwd | testCryptoKit.swift:105:37:105:37 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:105:37:105:37 | passwd | password (passwd) | +| testCryptoKit.swift:106:46:106:46 | passwd | testCryptoKit.swift:106:46:106:46 | passwd | testCryptoKit.swift:106:46:106:46 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:106:46:106:46 | passwd | password (passwd) | | testCryptoKit.swift:112:37:112:37 | passwd | testCryptoKit.swift:112:37:112:37 | passwd | testCryptoKit.swift:112:37:112:37 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:112:37:112:37 | passwd | password (passwd) | +| testCryptoKit.swift:113:46:113:46 | passwd | testCryptoKit.swift:113:46:113:46 | passwd | testCryptoKit.swift:113:46:113:46 | passwd | Insecure hashing algorithm (SHA384) depends on $@. | testCryptoKit.swift:113:46:113:46 | passwd | password (passwd) | | testCryptoKit.swift:119:37:119:37 | passwd | testCryptoKit.swift:119:37:119:37 | passwd | testCryptoKit.swift:119:37:119:37 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:119:37:119:37 | passwd | password (passwd) | +| testCryptoKit.swift:120:46:120:46 | passwd | testCryptoKit.swift:120:46:120:46 | passwd | testCryptoKit.swift:120:46:120:46 | passwd | Insecure hashing algorithm (SHA512) depends on $@. | testCryptoKit.swift:120:46:120:46 | passwd | password (passwd) | | testCryptoKit.swift:129:23:129:23 | passwd | testCryptoKit.swift:129:23:129:23 | passwd | testCryptoKit.swift:129:23:129:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCryptoKit.swift:129:23:129:23 | passwd | password (passwd) | | testCryptoKit.swift:138:23:138:23 | passwd | testCryptoKit.swift:138:23:138:23 | passwd | testCryptoKit.swift:138:23:138:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCryptoKit.swift:138:23:138:23 | passwd | password (passwd) | | testCryptoKit.swift:147:23:147:23 | passwd | testCryptoKit.swift:147:23:147:23 | passwd | testCryptoKit.swift:147:23:147:23 | passwd | Insecure hashing algorithm (SHA256) depends on $@. | testCryptoKit.swift:147:23:147:23 | passwd | password (passwd) | diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift index 32a5dfa1f34..6869805e65a 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift +++ b/swift/ql/test/query-tests/Security/CWE-328/testCryptoKit.swift @@ -82,42 +82,42 @@ enum Insecure { func testHashMethods(passwd : UnsafeRawBufferPointer, cert: String, encrypted_passwd : String, account_no : String, credit_card_no : String) { var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD - hash = Crypto.Insecure.MD5.hash(bufferPointer: passwd) // BAD [NOT DETECTED] + hash = Crypto.Insecure.MD5.hash(bufferPointer: passwd) // BAD hash = Crypto.Insecure.MD5.hash(data: cert) // BAD hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD hash = Insecure.MD5.hash(data: passwd) // BAD - hash = Insecure.MD5.hash(bufferPointer: passwd) // BAD [NOT DETECTED] + hash = Insecure.MD5.hash(bufferPointer: passwd) // BAD hash = Insecure.MD5.hash(data: cert) // BAD hash = Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) hash = Insecure.MD5.hash(data: account_no) // BAD hash = Insecure.MD5.hash(data: credit_card_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD - hash = Crypto.Insecure.SHA1.hash(bufferPointer: passwd) // BAD [NOT DETECTED] + hash = Crypto.Insecure.SHA1.hash(bufferPointer: passwd) // BAD hash = Crypto.Insecure.SHA1.hash(data: cert) // BAD hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive) hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD hash = Crypto.SHA256.hash(data: passwd) // BAD, not a computationally expensive hash - hash = Crypto.SHA256.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] + hash = Crypto.SHA256.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash hash = Crypto.SHA256.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA256.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA256.hash(data: account_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA256.hash(data: credit_card_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: passwd) // BAD, not a computationally expensive hash - hash = Crypto.SHA384.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] + hash = Crypto.SHA384.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash hash = Crypto.SHA384.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA384.hash(data: account_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA384.hash(data: credit_card_no) // GOOD, computationally expensive hash not required hash = Crypto.SHA512.hash(data: passwd) // BAD, not a computationally expensive hash - hash = Crypto.SHA512.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash [NOT DETECTED] + hash = Crypto.SHA512.hash(bufferPointer: passwd) // BAD, not a computationally expensive hash hash = Crypto.SHA512.hash(data: cert) // GOOD, computationally expensive hash not required hash = Crypto.SHA512.hash(data: encrypted_passwd) // GOOD, not sensitive hash = Crypto.SHA512.hash(data: account_no) // GOOD, computationally expensive hash not required From 6b55f865cdf234f8e6733434cc5fb70f5d8addf5 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 27 May 2026 13:24:45 +0200 Subject: [PATCH 116/226] C#: Update integration test expected output. --- .../Assemblies.expected | 1 - 1 file changed, 1 deletion(-) diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected index 2be1117efc0..6b32d2248c5 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected @@ -22,7 +22,6 @@ | [...]/csharp/tools/[...]/Microsoft.Win32.Primitives.dll | | [...]/csharp/tools/[...]/Microsoft.Win32.Registry.dll | | [...]/csharp/tools/[...]/Mono.Posix.NETStandard.dll | -| [...]/csharp/tools/[...]/NaturalSort.Extension.dll | | [...]/csharp/tools/[...]/Newtonsoft.Json.dll | | [...]/csharp/tools/[...]/NuGet.Versioning.dll | | [...]/csharp/tools/[...]/StructuredLogger.dll | From d4c7b5b6feb26d055025790e53747c602258e2dd Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 27 May 2026 14:01:34 +0200 Subject: [PATCH 117/226] C#: Update encoding of SBCS to UTF8 with BOM. --- csharp/ql/test/library-tests/encoding/SBCS.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/library-tests/encoding/SBCS.cs b/csharp/ql/test/library-tests/encoding/SBCS.cs index 46d3af48696..9a2d677ba16 100644 --- a/csharp/ql/test/library-tests/encoding/SBCS.cs +++ b/csharp/ql/test/library-tests/encoding/SBCS.cs @@ -1,4 +1,4 @@ -class SBCS +class SBCS { - string sbcs = "’"; + string sbcs = "�"; } From ec13e1bcd3f3f0c41484d976ef1fc913fed1e109 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 27 May 2026 15:28:07 +0100 Subject: [PATCH 118/226] Add wildcard `ContentSet`s to avoid performance problems --- .../dataflow/new/internal/DataFlowPrivate.qll | 118 +++++++++--------- .../dataflow/new/internal/DataFlowPublic.qll | 54 +++++++- .../dataflow/new/internal/FlowSummaryImpl.qll | 44 ++++--- .../new/internal/TaintTrackingPrivate.qll | 15 +-- .../new/internal/TypeTrackingImpl.qll | 7 +- .../LoopVariableCaptureQuery.qll | 11 +- .../frameworks/stdlib/test_re.py | 18 +-- 7 files changed, 162 insertions(+), 105 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index aa4130fb6a8..1c9ec5dff17 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -753,7 +753,7 @@ predicate jumpStepNotSharedWithTypeTracker(Node nodeFrom, Node nodeTo) { * As of 2024-04-02 the type-tracking library only supports precise content, so there is * no reason to include steps for list content right now. */ -predicate storeStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) { +predicate storeStepCommon(Node nodeFrom, Content c, Node nodeTo) { tupleStoreStep(nodeFrom, c, nodeTo) or dictStoreStep(nodeFrom, c, nodeTo) @@ -767,29 +767,31 @@ predicate storeStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) { * Holds if data can flow from `nodeFrom` to `nodeTo` via an assignment to * content `c`. */ -predicate storeStep(Node nodeFrom, ContentSet c, Node nodeTo) { - storeStepCommon(nodeFrom, c, nodeTo) +predicate storeStep(Node nodeFrom, ContentSet cs, Node nodeTo) { + exists(Content c | cs = singleton(c) | + storeStepCommon(nodeFrom, c, nodeTo) + or + listStoreStep(nodeFrom, c, nodeTo) + or + setStoreStep(nodeFrom, c, nodeTo) + or + attributeStoreStep(nodeFrom, c, nodeTo) + or + matchStoreStep(nodeFrom, c, nodeTo) + or + any(Orm::AdditionalOrmSteps es).storeStep(nodeFrom, c, nodeTo) + or + synthStarArgsElementParameterNodeStoreStep(nodeFrom, c, nodeTo) + or + synthDictSplatArgumentNodeStoreStep(nodeFrom, c, nodeTo) + or + yieldStoreStep(nodeFrom, c, nodeTo) + or + VariableCapture::storeStep(nodeFrom, c, nodeTo) + ) or - listStoreStep(nodeFrom, c, nodeTo) - or - setStoreStep(nodeFrom, c, nodeTo) - or - attributeStoreStep(nodeFrom, c, nodeTo) - or - matchStoreStep(nodeFrom, c, nodeTo) - or - any(Orm::AdditionalOrmSteps es).storeStep(nodeFrom, c, nodeTo) - or - FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c, + FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), cs, nodeTo.(FlowSummaryNode).getSummaryNode()) - or - synthStarArgsElementParameterNodeStoreStep(nodeFrom, c, nodeTo) - or - synthDictSplatArgumentNodeStoreStep(nodeFrom, c, nodeTo) - or - yieldStoreStep(nodeFrom, c, nodeTo) - or - VariableCapture::storeStep(nodeFrom, c, nodeTo) } /** @@ -985,7 +987,7 @@ predicate attributeStoreStep(Node nodeFrom, AttributeContent c, Node nodeTo) { /** * Subset of `readStep` that should be shared with type-tracking. */ -predicate readStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) { +predicate readStepCommon(Node nodeFrom, Content c, Node nodeTo) { subscriptReadStep(nodeFrom, c, nodeTo) or iterableUnpackingReadStep(nodeFrom, c, nodeTo) @@ -994,23 +996,25 @@ predicate readStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) { /** * Holds if data can flow from `nodeFrom` to `nodeTo` via a read of content `c`. */ -predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) { - readStepCommon(nodeFrom, c, nodeTo) +predicate readStep(Node nodeFrom, ContentSet cs, Node nodeTo) { + exists(Content c | cs = singleton(c) | + readStepCommon(nodeFrom, c, nodeTo) + or + matchReadStep(nodeFrom, c, nodeTo) + or + forReadStep(nodeFrom, c, nodeTo) + or + attributeReadStep(nodeFrom, c, nodeTo) + or + synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo) + or + VariableCapture::readStep(nodeFrom, c, nodeTo) + ) or - matchReadStep(nodeFrom, c, nodeTo) - or - forReadStep(nodeFrom, c, nodeTo) - or - attributeReadStep(nodeFrom, c, nodeTo) - or - FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c, + FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), cs, nodeTo.(FlowSummaryNode).getSummaryNode()) or - synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo) - or - VariableCapture::readStep(nodeFrom, c, nodeTo) - or - Conversions::readStep(nodeFrom, c, nodeTo) + Conversions::readStep(nodeFrom, cs, nodeTo) } /** Data flows from a sequence to a subscript of the sequence. */ @@ -1074,11 +1078,7 @@ module Conversions { nodeFrom = decoding.getAnInput() and nodeTo = decoding.getOutput() ) and - ( - c instanceof TupleElementContent - or - c instanceof DictionaryElementContent - ) + (c.isAnyTupleElement() or c.isAnyDictionaryElement()) } predicate encoderReadStep(Node nodeFrom, ContentSet c, Node nodeTo) { @@ -1086,11 +1086,7 @@ module Conversions { nodeFrom = encoding.getAnInput() and nodeTo = encoding.getOutput() ) and - ( - c instanceof TupleElementContent - or - c instanceof DictionaryElementContent - ) + (c.isAnyTupleElement() or c.isAnyDictionaryElement()) } predicate formatReadStep(Node nodeFrom, ContentSet c, Node nodeTo) { @@ -1099,13 +1095,13 @@ module Conversions { fmt.getOp() instanceof Mod and fmt.getRight() = nodeFrom.asCfgNode() ) and - c instanceof TupleElementContent + c.isAnyTupleElement() or // format_map // see https://docs.python.org/3/library/stdtypes.html#str.format_map nodeTo.(MethodCallNode).calls(_, "format_map") and nodeTo.(MethodCallNode).getArg(0) = nodeFrom and - c instanceof DictionaryElementContent + c.isAnyDictionaryElement() } predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) { @@ -1122,18 +1118,20 @@ module Conversions { * any value stored inside `f` is cleared at the pre-update node associated with `x` * in `x.f = newValue`. */ -predicate clearsContent(Node n, ContentSet c) { - matchClearStep(n, c) +predicate clearsContent(Node n, ContentSet cs) { + exists(Content c | cs = singleton(c) | + matchClearStep(n, c) + or + attributeClearStep(n, c) + or + dictClearStep(n, c) + or + dictSplatParameterNodeClearStep(n, c) + or + VariableCapture::clearsContent(n, c) + ) or - attributeClearStep(n, c) - or - dictClearStep(n, c) - or - FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) - or - dictSplatParameterNodeClearStep(n, c) - or - VariableCapture::clearsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), cs) } /** diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 8612d4a253e..173a5598149 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -898,19 +898,65 @@ class CapturedVariableContent extends Content, TCapturedVariableContent { override string getMaDRepresentation() { none() } } +/** + * An entity that represents a set of `Content`s. + * + * Most `ContentSet`s are singletons (i.e. they consist of a single `Content`), + * but `AnyDictionaryElement` and `AnyTupleElement` act as wildcards on the + * read side: a read at such a `ContentSet` matches any specific dictionary + * key / tuple index store, as well as (for dictionaries) the + * "unknown-bucket" Content `DictionaryElementAnyContent`. + * + * Keeping these as wildcard `ContentSet`s (rather than enumerating one + * `ContentSet` per key/index) keeps the dataflow `readSetEx` relation small + * when implicit reads are used (e.g. at sinks via `defaultImplicitTaintRead`). + */ +private newtype TContentSet = + TSingletonContent(Content c) or + TAnyTupleElement() or + TAnyDictionaryElement() + /** * An entity that represents a set of `Content`s. * * The set may be interpreted differently depending on whether it is * stored into (`getAStoreContent`) or read from (`getAReadContent`). */ -class ContentSet instanceof Content { +class ContentSet extends TContentSet { + /** Holds if this content set is the singleton `{c}`. */ + predicate isSingleton(Content c) { this = TSingletonContent(c) } + + /** Holds if this content set is the wildcard for all tuple elements. */ + predicate isAnyTupleElement() { this = TAnyTupleElement() } + + /** Holds if this content set is the wildcard for all dictionary elements. */ + predicate isAnyDictionaryElement() { this = TAnyDictionaryElement() } + /** Gets a content that may be stored into when storing into this set. */ - Content getAStoreContent() { result = this } + Content getAStoreContent() { this = TSingletonContent(result) } /** Gets a content that may be read from when reading from this set. */ - Content getAReadContent() { result = this } + Content getAReadContent() { + this = TSingletonContent(result) + or + // Wildcard expansion: a read at "any tuple element" matches a store at any + // specific tuple index. (Stores always target a specific index, so we don't + // need a `TupleElementAnyContent` Content kind here.) + this = TAnyTupleElement() and result instanceof TupleElementContent + or + this = TAnyDictionaryElement() and + (result instanceof DictionaryElementContent or result instanceof DictionaryElementAnyContent) + } /** Gets a textual representation of this content set. */ - string toString() { result = super.toString() } + string toString() { + exists(Content c | this = TSingletonContent(c) | result = c.toString()) + or + this = TAnyTupleElement() and result = "Any tuple element" + or + this = TAnyDictionaryElement() and result = "Any dictionary element" + } } + +/** Gets the singleton `ContentSet` wrapping the `Content` `c`. */ +ContentSet singleton(Content c) { result = TSingletonContent(c) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index 41cb0368b50..1e9ffcf463c 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -66,21 +66,27 @@ module Input implements InputSig } string encodeContent(ContentSet cs, string arg) { - cs = TListElementContent() and result = "ListElement" and arg = "" - or - cs = TSetElementContent() and result = "SetElement" and arg = "" - or - exists(int index | - cs = TTupleElementContent(index) and result = "TupleElement" and arg = index.toString() + exists(Content c | cs.isSingleton(c) | + c = TListElementContent() and result = "ListElement" and arg = "" + or + c = TSetElementContent() and result = "SetElement" and arg = "" + or + exists(int index | + c = TTupleElementContent(index) and result = "TupleElement" and arg = index.toString() + ) + or + exists(string key | + c = TDictionaryElementContent(key) and result = "DictionaryElement" and arg = key + ) + or + c = TDictionaryElementAnyContent() and result = "DictionaryElementAny" and arg = "" + or + exists(string attr | c = TAttributeContent(attr) and result = "Attribute" and arg = attr) ) or - exists(string key | - cs = TDictionaryElementContent(key) and result = "DictionaryElement" and arg = key - ) + cs.isAnyTupleElement() and result = "AnyTupleElement" and arg = "" or - cs = TDictionaryElementAnyContent() and result = "DictionaryElementAny" and arg = "" - or - exists(string attr | cs = TAttributeContent(attr) and result = "Attribute" and arg = attr) + cs.isAnyDictionaryElement() and result = "AnyDictionaryElement" and arg = "" } bindingset[token] @@ -139,27 +145,29 @@ module Private { predicate withContent = SC::withContent/1; /** Gets a summary component that represents a list element. */ - SummaryComponent listElement() { result = content(any(ListElementContent c)) } + SummaryComponent listElement() { result = content(singleton(any(ListElementContent c))) } /** Gets a summary component that represents a set element. */ - SummaryComponent setElement() { result = content(any(SetElementContent c)) } + SummaryComponent setElement() { result = content(singleton(any(SetElementContent c))) } /** Gets a summary component that represents a tuple element. */ SummaryComponent tupleElement(int index) { - exists(TupleElementContent c | c.getIndex() = index and result = content(c)) + exists(TupleElementContent c | c.getIndex() = index and result = content(singleton(c))) } /** Gets a summary component that represents a dictionary element. */ SummaryComponent dictionaryElement(string key) { - exists(DictionaryElementContent c | c.getKey() = key and result = content(c)) + exists(DictionaryElementContent c | c.getKey() = key and result = content(singleton(c))) } /** Gets a summary component that represents a dictionary element at any key. */ - SummaryComponent dictionaryElementAny() { result = content(any(DictionaryElementAnyContent c)) } + SummaryComponent dictionaryElementAny() { + result = content(singleton(any(DictionaryElementAnyContent c))) + } /** Gets a summary component that represents an attribute element. */ SummaryComponent attribute(string attr) { - exists(AttributeContent c | c.getAttribute() = attr and result = content(c)) + exists(AttributeContent c | c.getAttribute() = attr and result = content(singleton(c))) } /** Gets a summary component that represents the return value of a call. */ diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 6959ceabe70..2d2cceb73c1 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -17,14 +17,15 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { none() } */ bindingset[node] predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { - // We allow implicit reads of precise content - // imprecise content has already bubled up. + // We allow implicit reads of precise content; imprecise content has already + // bubbled up. We use the wildcard content sets here rather than the + // per-key/per-index ones to avoid blowing up the size of `Stage1::readSetEx` + // (otherwise this predicate would expand to one row per (node, distinct key + // or index) and the framework's read-set relation grows quadratically). + // `ContentSet.getAReadContent` expands these wildcards back to the specific + // contents when matching against stores. exists(node) and - ( - c instanceof DataFlow::TupleElementContent - or - c instanceof DataFlow::DictionaryElementContent - ) + (c.isAnyTupleElement() or c.isAnyDictionaryElement()) } private module Cached { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackingImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackingImpl.qll index 95434b05451..215c7906e65 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackingImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackingImpl.qll @@ -241,7 +241,7 @@ module TypeTrackingInput implements Shared::TypeTrackingInput { // is only fed set/list content) not nodeFrom instanceof DataFlowPublic::IterableElementNode or - TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, content) + TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, DataFlowPublic::singleton(content)) } /** @@ -272,14 +272,15 @@ module TypeTrackingInput implements Shared::TypeTrackingInput { nodeFrom.asCfgNode() instanceof SequenceNode ) or - TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, content) + TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, DataFlowPublic::singleton(content)) } /** * Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`. */ predicate loadStoreStep(Node nodeFrom, Node nodeTo, Content loadContent, Content storeContent) { - TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo, loadContent, storeContent) + TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo, + DataFlowPublic::singleton(loadContent), DataFlowPublic::singleton(storeContent)) } /** diff --git a/python/ql/src/Variables/LoopVariableCapture/LoopVariableCaptureQuery.qll b/python/ql/src/Variables/LoopVariableCapture/LoopVariableCaptureQuery.qll index 987740236f2..6b3e428b995 100644 --- a/python/ql/src/Variables/LoopVariableCapture/LoopVariableCaptureQuery.qll +++ b/python/ql/src/Variables/LoopVariableCapture/LoopVariableCaptureQuery.qll @@ -61,10 +61,13 @@ module EscapingCaptureFlowConfig implements DataFlow::ConfigSig { predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet cs) { isSink(node) and ( - cs.(DataFlow::TupleElementContent).getIndex() in [0 .. 10] or - cs instanceof DataFlow::ListElementContent or - cs instanceof DataFlow::SetElementContent or - cs instanceof DataFlow::DictionaryElementAnyContent + cs.isAnyTupleElement() + or + cs.isAnyDictionaryElement() + or + cs.getAStoreContent() instanceof DataFlow::ListElementContent + or + cs.getAStoreContent() instanceof DataFlow::SetElementContent ) } } diff --git a/python/ql/test/library-tests/frameworks/stdlib/test_re.py b/python/ql/test/library-tests/frameworks/stdlib/test_re.py index 8ed6f620bfa..8107b7dd988 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/test_re.py +++ b/python/ql/test/library-tests/frameworks/stdlib/test_re.py @@ -6,16 +6,16 @@ pat = ... # some pattern compiled_pat = re.compile(pat) # see https://docs.python.org/3/library/re.html#functions -ensure_not_tainted( - # returns Match object, which is tested properly below. (note: with the flow summary - # modeling, objects containing tainted values are not themselves tainted). - re.search(pat, ts), - re.match(pat, ts), - re.fullmatch(pat, ts), +ensure_tainted( + # returns Match object, which is tested properly below. (note: the match objects contain + # tainted values but are not themselves tainted - this test relies on implicit reads at sinks). + re.search(pat, ts), # $ tainted + re.match(pat, ts), # $ tainted + re.fullmatch(pat, ts), # $ tainted - compiled_pat.search(ts), - compiled_pat.match(ts), - compiled_pat.fullmatch(ts), + compiled_pat.search(ts), # $ tainted + compiled_pat.match(ts), # $ tainted + compiled_pat.fullmatch(ts), # $ tainted ) # Match object From 41fd59c1c1a5927d945718afaf63aee1a9819db9 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 27 May 2026 15:02:28 +0000 Subject: [PATCH 119/226] Unified: regenerate Ast.qll and dbscheme --- unified/ql/lib/codeql/unified/Ast.qll | 3544 ++----------------------- unified/ql/lib/unified.dbscheme | 2425 +---------------- 2 files changed, 318 insertions(+), 5651 deletions(-) diff --git a/unified/ql/lib/codeql/unified/Ast.qll b/unified/ql/lib/codeql/unified/Ast.qll index 1835f2c449a..d9060c26f0f 100644 --- a/unified/ql/lib/codeql/unified/Ast.qll +++ b/unified/ql/lib/codeql/unified/Ast.qll @@ -1,5 +1,5 @@ /** - * CodeQL library for Swift + * CodeQL library for Unified * Automatically generated from the tree-sitter grammar; do not edit */ @@ -24,20 +24,20 @@ private predicate discardLocation(@location_default loc) { } overlay[local] -module Swift { +module Unified { /** The base class for all AST nodes */ - class AstNode extends @swift_ast_node { + class AstNode extends @unified_ast_node { /** Gets a string representation of this element. */ string toString() { result = this.getAPrimaryQlClass() } /** Gets the location of this element. */ - final L::Location getLocation() { swift_ast_node_location(this, result) } + final L::Location getLocation() { unified_ast_node_location(this, result) } /** Gets the parent of this element. */ - final AstNode getParent() { swift_ast_node_parent(this, result, _) } + final AstNode getParent() { unified_ast_node_parent(this, result, _) } /** Gets the index of this node among the children of its parent. */ - final int getParentIndex() { swift_ast_node_parent(this, _, result) } + final int getParentIndex() { unified_ast_node_parent(this, _, result) } /** Gets a field or child node of this node. */ AstNode getAFieldOrChild() { none() } @@ -50,9 +50,9 @@ module Swift { } /** A token. */ - class Token extends @swift_token, AstNode { + class Token extends @unified_token, AstNode { /** Gets the value of this token. */ - final string getValue() { swift_tokeninfo(this, _, result) } + final string getValue() { unified_tokeninfo(this, _, result) } /** Gets a string representation of this element. */ final override string toString() { result = this.getValue() } @@ -61,3548 +61,386 @@ module Swift { override string getAPrimaryQlClass() { result = "Token" } } - /** A reserved word. */ - class ReservedWord extends @swift_reserved_word, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ReservedWord" } - } - /** Gets the file containing the given `node`. */ - private @file getNodeFile(@swift_ast_node node) { - exists(@location_default loc | swift_ast_node_location(node, loc) | + private @file getNodeFile(@unified_ast_node node) { + exists(@location_default loc | unified_ast_node_location(node, loc) | locations_default(loc, result, _, _, _, _) ) } /** Holds if `node` is in the `file` and is part of the overlay base database. */ - private predicate discardableAstNode(@file file, @swift_ast_node node) { + private predicate discardableAstNode(@file file, @unified_ast_node node) { not isOverlay() and file = getNodeFile(node) } /** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */ overlay[discard_entity] - private predicate discardAstNode(@swift_ast_node node) { + private predicate discardAstNode(@unified_ast_node node) { exists(@file file, string path | files(file, path) | discardableAstNode(file, node) and overlayChangedFiles(path) ) } - /** A class representing `additive_expression` nodes. */ - class AdditiveExpression extends @swift_additive_expression, AstNode { + /** A class representing `apply_pattern` nodes. */ + class ApplyPattern extends @unified_apply_pattern, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AdditiveExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_additive_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_additive_expression_def(this, _, value, _) | - result = "+" and value = 0 - or - result = "-" and value = 1 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_additive_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_additive_expression_def(this, result, _, _) or - swift_additive_expression_def(this, _, _, result) - } - } - - /** A class representing `array_literal` nodes. */ - class ArrayLiteral extends @swift_array_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ArrayLiteral" } - - /** Gets the node corresponding to the field `element`. */ - final Expression getElement(int i) { swift_array_literal_element(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_array_literal_element(this, _, result) } - } - - /** A class representing `array_type` nodes. */ - class ArrayType extends @swift_array_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ArrayType" } - - /** Gets the node corresponding to the field `element`. */ - final Type getElement() { swift_array_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_array_type_def(this, result) } - } - - /** A class representing `as_expression` nodes. */ - class AsExpression extends @swift_as_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AsExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_as_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `operator`. */ - final AsOperator getOperator() { swift_as_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_as_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_as_expression_def(this, result, _, _) or - swift_as_expression_def(this, _, result, _) or - swift_as_expression_def(this, _, _, result) - } - } - - /** A class representing `as_operator` tokens. */ - class AsOperator extends @swift_token_as_operator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AsOperator" } - } - - /** A class representing `assignment` nodes. */ - class Assignment extends @swift_assignment, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Assignment" } - - /** Gets the node corresponding to the field `operator`. */ - final string getOperator() { - exists(int value | swift_assignment_def(this, value, _, _) | - result = "%=" and value = 0 - or - result = "*=" and value = 1 - or - result = "+=" and value = 2 - or - result = "-=" and value = 3 - or - result = "/=" and value = 4 - or - result = "=" and value = 5 - ) - } - - /** Gets the node corresponding to the field `result`. */ - final Expression getResult() { swift_assignment_def(this, _, result, _) } - - /** Gets the node corresponding to the field `target`. */ - final DirectlyAssignableExpression getTarget() { swift_assignment_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_assignment_def(this, _, result, _) or swift_assignment_def(this, _, _, result) - } - } - - /** A class representing `associatedtype_declaration` nodes. */ - class AssociatedtypeDeclaration extends @swift_associatedtype_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AssociatedtypeDeclaration" } - - /** Gets the node corresponding to the field `default_value`. */ - final Type getDefaultValue() { swift_associatedtype_declaration_default_value(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_associatedtype_declaration_modifiers(this, result) } - - /** Gets the node corresponding to the field `must_inherit`. */ - final Type getMustInherit() { swift_associatedtype_declaration_must_inherit(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_associatedtype_declaration_def(this, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_associatedtype_declaration_type_constraints(this, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_associatedtype_declaration_default_value(this, result) or - swift_associatedtype_declaration_modifiers(this, result) or - swift_associatedtype_declaration_must_inherit(this, result) or - swift_associatedtype_declaration_def(this, result) or - swift_associatedtype_declaration_type_constraints(this, result) - } - } - - /** A class representing `async_keyword` tokens. */ - class AsyncKeyword extends @swift_token_async_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AsyncKeyword" } - } - - /** A class representing `attribute` nodes. */ - class Attribute extends @swift_attribute, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Attribute" } + final override string getAPrimaryQlClass() { result = "ApplyPattern" } /** Gets the node corresponding to the field `argument`. */ - final Expression getArgument(int i) { swift_attribute_argument(this, i, result) } + final Pattern getArgument(int i) { unified_apply_pattern_argument(this, i, result) } - /** Gets the node corresponding to the field `argument_name`. */ - final SimpleIdentifier getArgumentName(int i) { swift_attribute_argument_name(this, i, result) } - - /** Gets the node corresponding to the field `name`. */ - final UserType getName() { swift_attribute_def(this, result) } - - /** Gets the node corresponding to the field `param_ref`. */ - final SimpleIdentifier getParamRef(int i) { swift_attribute_param_ref(this, i, result) } - - /** Gets the node corresponding to the field `platform`. */ - final SimpleIdentifier getPlatform(int i) { swift_attribute_platform(this, i, result) } - - /** Gets the node corresponding to the field `version`. */ - final IntegerLiteral getVersion(int i) { swift_attribute_version(this, i, result) } + /** Gets the node corresponding to the field `constructor`. */ + final Expr getConstructor() { unified_apply_pattern_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_attribute_argument(this, _, result) or - swift_attribute_argument_name(this, _, result) or - swift_attribute_def(this, result) or - swift_attribute_param_ref(this, _, result) or - swift_attribute_platform(this, _, result) or - swift_attribute_version(this, _, result) + unified_apply_pattern_argument(this, _, result) or unified_apply_pattern_def(this, result) } } - /** A class representing `availability_condition` nodes. */ - class AvailabilityCondition extends @swift_availability_condition, AstNode { + /** A class representing `binary_expr` nodes. */ + class BinaryExpr extends @unified_binary_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AvailabilityCondition" } + final override string getAPrimaryQlClass() { result = "BinaryExpr" } - /** Gets the node corresponding to the field `platform`. */ - final Identifier getPlatform(int i) { swift_availability_condition_platform(this, i, result) } + /** Gets the node corresponding to the field `left`. */ + final Expr getLeft() { unified_binary_expr_def(this, result, _, _) } - /** Gets the node corresponding to the field `version`. */ - final IntegerLiteral getVersion(int i) { swift_availability_condition_version(this, i, result) } + /** Gets the node corresponding to the field `operator`. */ + final Operator getOperator() { unified_binary_expr_def(this, _, result, _) } + + /** Gets the node corresponding to the field `right`. */ + final Expr getRight() { unified_binary_expr_def(this, _, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_availability_condition_platform(this, _, result) or - swift_availability_condition_version(this, _, result) + unified_binary_expr_def(this, result, _, _) or + unified_binary_expr_def(this, _, result, _) or + unified_binary_expr_def(this, _, _, result) } } - /** A class representing `await_expression` nodes. */ - class AwaitExpression extends @swift_await_expression, AstNode { + /** A class representing `block_stmt` nodes. */ + class BlockStmt extends @unified_block_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "AwaitExpression" } + final override string getAPrimaryQlClass() { result = "BlockStmt" } - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_await_expression_def(this, result) } + /** Gets the node corresponding to the field `body`. */ + final Stmt getBody(int i) { unified_block_stmt_body(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_await_expression_def(this, result) } + final override AstNode getAFieldOrChild() { unified_block_stmt_body(this, _, result) } } - /** A class representing `bang` tokens. */ - class Bang extends @swift_token_bang, Token { + /** A class representing `call_expr` nodes. */ + class CallExpr extends @unified_call_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Bang" } - } + final override string getAPrimaryQlClass() { result = "CallExpr" } - /** A class representing `bin_literal` tokens. */ - class BinLiteral extends @swift_token_bin_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BinLiteral" } - } - - /** A class representing `binding_pattern` nodes. */ - class BindingPattern extends @swift_binding_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BindingPattern" } - - /** Gets the node corresponding to the field `binding`. */ - final ValueBindingPattern getBinding() { swift_binding_pattern_def(this, result, _) } - - /** Gets the node corresponding to the field `pattern`. */ - final Pattern getPattern() { swift_binding_pattern_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_binding_pattern_def(this, result, _) or swift_binding_pattern_def(this, _, result) - } - } - - /** A class representing `bitwise_operation` nodes. */ - class BitwiseOperation extends @swift_bitwise_operation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BitwiseOperation" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_bitwise_operation_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_bitwise_operation_def(this, _, value, _) | - result = "&" and value = 0 - or - result = "<<" and value = 1 - or - result = ">>" and value = 2 - or - result = "^" and value = 3 - or - result = "|" and value = 4 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_bitwise_operation_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_bitwise_operation_def(this, result, _, _) or - swift_bitwise_operation_def(this, _, _, result) - } - } - - /** A class representing `block` nodes. */ - class Block extends @swift_block, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Block" } - - /** Gets the node corresponding to the field `statement`. */ - final AstNode getStatement(int i) { swift_block_statement(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_block_statement(this, _, result) } - } - - /** A class representing `boolean_literal` tokens. */ - class BooleanLiteral extends @swift_token_boolean_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "BooleanLiteral" } - } - - /** A class representing `call_expression` nodes. */ - class CallExpression extends @swift_call_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CallExpression" } + /** Gets the node corresponding to the field `argument`. */ + final Expr getArgument(int i) { unified_call_expr_argument(this, i, result) } /** Gets the node corresponding to the field `function`. */ - final Expression getFunction() { swift_call_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `suffix`. */ - final CallSuffix getSuffix() { swift_call_expression_def(this, _, result) } + final Expr getFunction() { unified_call_expr_def(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_call_expression_def(this, result, _) or swift_call_expression_def(this, _, result) + unified_call_expr_argument(this, _, result) or unified_call_expr_def(this, result) } } - /** A class representing `call_suffix` nodes. */ - class CallSuffix extends @swift_call_suffix, AstNode { + class Condition extends @unified_condition, AstNode { } + + /** A class representing `empty_stmt` tokens. */ + class EmptyStmt extends @unified_token_empty_stmt, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CallSuffix" } - - /** Gets the node corresponding to the field `arguments`. */ - final ValueArguments getArguments() { swift_call_suffix_arguments(this, result) } - - /** Gets the node corresponding to the field `lambda`. */ - final LambdaLiteral getLambda(int i) { swift_call_suffix_lambda(this, i, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_call_suffix_name(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_call_suffix_arguments(this, result) or - swift_call_suffix_lambda(this, _, result) or - swift_call_suffix_name(this, _, result) - } + final override string getAPrimaryQlClass() { result = "EmptyStmt" } } - /** A class representing `capture_list` nodes. */ - class CaptureList extends @swift_capture_list, AstNode { + class Expr extends @unified_expr, AstNode { } + + /** A class representing `expr_condition` nodes. */ + class ExprCondition extends @unified_expr_condition, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CaptureList" } - - /** Gets the node corresponding to the field `item`. */ - final CaptureListItem getItem(int i) { swift_capture_list_item(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_capture_list_item(this, _, result) } - } - - /** A class representing `capture_list_item` nodes. */ - class CaptureListItem extends @swift_capture_list_item, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CaptureListItem" } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_capture_list_item_def(this, result) } - - /** Gets the node corresponding to the field `ownership`. */ - final OwnershipModifier getOwnership() { swift_capture_list_item_ownership(this, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_capture_list_item_value(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_capture_list_item_def(this, result) or - swift_capture_list_item_ownership(this, result) or - swift_capture_list_item_value(this, result) - } - } - - /** A class representing `case_pattern` nodes. */ - class CasePattern extends @swift_case_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CasePattern" } - - /** Gets the node corresponding to the field `arguments`. */ - final TuplePattern getArguments() { swift_case_pattern_arguments(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_case_pattern_def(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final UserType getType() { swift_case_pattern_type(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_case_pattern_arguments(this, result) or - swift_case_pattern_def(this, result) or - swift_case_pattern_type(this, result) - } - } - - /** A class representing `catch_block` nodes. */ - class CatchBlock extends @swift_catch_block, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CatchBlock" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_catch_block_def(this, result, _) } - - /** Gets the node corresponding to the field `error`. */ - final Pattern getError() { swift_catch_block_error(this, result) } - - /** Gets the node corresponding to the field `keyword`. */ - final CatchKeyword getKeyword() { swift_catch_block_def(this, _, result) } - - /** Gets the node corresponding to the field `where`. */ - final WhereClause getWhere() { swift_catch_block_where(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_catch_block_def(this, result, _) or - swift_catch_block_error(this, result) or - swift_catch_block_def(this, _, result) or - swift_catch_block_where(this, result) - } - } - - /** A class representing `catch_keyword` tokens. */ - class CatchKeyword extends @swift_token_catch_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CatchKeyword" } - } - - /** A class representing `check_expression` nodes. */ - class CheckExpression extends @swift_check_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CheckExpression" } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_check_expression_def(this, value, _, _) | - (result = "is" and value = 0) - ) - } - - /** Gets the node corresponding to the field `target`. */ - final Expression getTarget() { swift_check_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_check_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_check_expression_def(this, _, result, _) or - swift_check_expression_def(this, _, _, result) - } - } - - /** A class representing `class_body` nodes. */ - class ClassBody extends @swift_class_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ClassBody" } - - /** Gets the node corresponding to the field `member`. */ - final TypeLevelDeclaration getMember(int i) { swift_class_body_member(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_class_body_member(this, _, result) } - } - - /** A class representing `class_declaration` nodes. */ - class ClassDeclaration extends @swift_class_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ClassDeclaration" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_class_declaration_attribute(this, i, result) } - - /** Gets the node corresponding to the field `body`. */ - final AstNode getBody() { swift_class_declaration_def(this, result, _, _) } - - /** Gets the node corresponding to the field `declaration_kind`. */ - final string getDeclarationKind() { - exists(int value | swift_class_declaration_def(this, _, value, _) | - result = "actor" and value = 0 - or - result = "class" and value = 1 - or - result = "enum" and value = 2 - or - result = "extension" and value = 3 - or - result = "struct" and value = 4 - ) - } - - /** Gets the node corresponding to the field `inherits`. */ - final InheritanceSpecifier getInherits(int i) { - swift_class_declaration_inherits(this, i, result) - } - - /** Gets the node corresponding to the field `modifiers`. */ - final AstNode getModifiers(int i) { swift_class_declaration_modifiers(this, i, result) } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_class_declaration_def(this, _, _, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_class_declaration_type_constraints(this, result) - } - - /** Gets the node corresponding to the field `type_parameters`. */ - final TypeParameters getTypeParameters() { - swift_class_declaration_type_parameters(this, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_class_declaration_attribute(this, _, result) or - swift_class_declaration_def(this, result, _, _) or - swift_class_declaration_inherits(this, _, result) or - swift_class_declaration_modifiers(this, _, result) or - swift_class_declaration_def(this, _, _, result) or - swift_class_declaration_type_constraints(this, result) or - swift_class_declaration_type_parameters(this, result) - } - } - - /** A class representing `comment` tokens. */ - class Comment extends @swift_token_comment, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Comment" } - } - - /** A class representing `comparison_expression` nodes. */ - class ComparisonExpression extends @swift_comparison_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComparisonExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_comparison_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_comparison_expression_def(this, _, value, _) | - result = "<" and value = 0 - or - result = "<=" and value = 1 - or - result = ">" and value = 2 - or - result = ">=" and value = 3 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_comparison_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_comparison_expression_def(this, result, _, _) or - swift_comparison_expression_def(this, _, _, result) - } - } - - /** A class representing `compilation_condition` nodes. */ - class CompilationCondition extends @swift_compilation_condition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CompilationCondition" } - - /** Gets the node corresponding to the field `inner`. */ - final CompilationCondition getInner() { swift_compilation_condition_inner(this, result) } - - /** Gets the node corresponding to the field `lhs`. */ - final CompilationCondition getLhs() { swift_compilation_condition_lhs(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_compilation_condition_name(this, i, result) } - - /** Gets the node corresponding to the field `operand`. */ - final CompilationCondition getOperand() { swift_compilation_condition_operand(this, result) } - - /** Gets the node corresponding to the field `rhs`. */ - final CompilationCondition getRhs() { swift_compilation_condition_rhs(this, result) } - - /** Gets the node corresponding to the field `value`. */ - final BooleanLiteral getValue() { swift_compilation_condition_value(this, result) } - - /** Gets the node corresponding to the field `version`. */ - final IntegerLiteral getVersion(int i) { swift_compilation_condition_version(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_compilation_condition_inner(this, result) or - swift_compilation_condition_lhs(this, result) or - swift_compilation_condition_name(this, _, result) or - swift_compilation_condition_operand(this, result) or - swift_compilation_condition_rhs(this, result) or - swift_compilation_condition_value(this, result) or - swift_compilation_condition_version(this, _, result) - } - } - - /** A class representing `computed_getter` nodes. */ - class ComputedGetter extends @swift_computed_getter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedGetter" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_computed_getter_attribute(this, i, result) } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_computed_getter_body(this, result) } - - /** Gets the node corresponding to the field `specifier`. */ - final GetterSpecifier getSpecifier() { swift_computed_getter_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_computed_getter_attribute(this, _, result) or - swift_computed_getter_body(this, result) or - swift_computed_getter_def(this, result) - } - } - - /** A class representing `computed_modify` nodes. */ - class ComputedModify extends @swift_computed_modify, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedModify" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_computed_modify_attribute(this, i, result) } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_computed_modify_body(this, result) } - - /** Gets the node corresponding to the field `specifier`. */ - final ModifySpecifier getSpecifier() { swift_computed_modify_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_computed_modify_attribute(this, _, result) or - swift_computed_modify_body(this, result) or - swift_computed_modify_def(this, result) - } - } - - /** A class representing `computed_property` nodes. */ - class ComputedProperty extends @swift_computed_property, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedProperty" } - - /** Gets the node corresponding to the field `accessor`. */ - final AstNode getAccessor(int i) { swift_computed_property_accessor(this, i, result) } - - /** Gets the node corresponding to the field `statement`. */ - final AstNode getStatement(int i) { swift_computed_property_statement(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_computed_property_accessor(this, _, result) or - swift_computed_property_statement(this, _, result) - } - } - - /** A class representing `computed_setter` nodes. */ - class ComputedSetter extends @swift_computed_setter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ComputedSetter" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_computed_setter_attribute(this, i, result) } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_computed_setter_body(this, result) } - - /** Gets the node corresponding to the field `parameter`. */ - final SimpleIdentifier getParameter() { swift_computed_setter_parameter(this, result) } - - /** Gets the node corresponding to the field `specifier`. */ - final SetterSpecifier getSpecifier() { swift_computed_setter_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_computed_setter_attribute(this, _, result) or - swift_computed_setter_body(this, result) or - swift_computed_setter_parameter(this, result) or - swift_computed_setter_def(this, result) - } - } - - /** A class representing `conjunction_expression` nodes. */ - class ConjunctionExpression extends @swift_conjunction_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ConjunctionExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_conjunction_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_conjunction_expression_def(this, _, value, _) | - (result = "&&" and value = 0) - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_conjunction_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_conjunction_expression_def(this, result, _, _) or - swift_conjunction_expression_def(this, _, _, result) - } - } - - /** A class representing `constructor_expression` nodes. */ - class ConstructorExpression extends @swift_constructor_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ConstructorExpression" } - - /** Gets the node corresponding to the field `constructed_type`. */ - final AstNode getConstructedType() { swift_constructor_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `suffix`. */ - final ConstructorSuffix getSuffix() { swift_constructor_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_constructor_expression_def(this, result, _) or - swift_constructor_expression_def(this, _, result) - } - } - - /** A class representing `constructor_suffix` nodes. */ - class ConstructorSuffix extends @swift_constructor_suffix, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ConstructorSuffix" } - - /** Gets the node corresponding to the field `arguments`. */ - final ValueArguments getArguments() { swift_constructor_suffix_arguments(this, result) } - - /** Gets the node corresponding to the field `lambda`. */ - final LambdaLiteral getLambda(int i) { swift_constructor_suffix_lambda(this, i, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName(int i) { swift_constructor_suffix_name(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_constructor_suffix_arguments(this, result) or - swift_constructor_suffix_lambda(this, _, result) or - swift_constructor_suffix_name(this, _, result) - } - } - - /** A class representing `control_transfer_statement` nodes. */ - class ControlTransferStatement extends @swift_control_transfer_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ControlTransferStatement" } - - /** Gets the node corresponding to the field `kind`. */ - final AstNode getKind() { swift_control_transfer_statement_def(this, result) } - - /** Gets the node corresponding to the field `result`. */ - final Expression getResult() { swift_control_transfer_statement_result(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_control_transfer_statement_def(this, result) or - swift_control_transfer_statement_result(this, result) - } - } - - /** A class representing `custom_operator` tokens. */ - class CustomOperator extends @swift_token_custom_operator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "CustomOperator" } - } - - /** A class representing `default_keyword` tokens. */ - class DefaultKeyword extends @swift_token_default_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DefaultKeyword" } - } - - /** A class representing `deinit_declaration` nodes. */ - class DeinitDeclaration extends @swift_deinit_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DeinitDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_deinit_declaration_def(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_deinit_declaration_modifiers(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_deinit_declaration_def(this, result) or swift_deinit_declaration_modifiers(this, result) - } - } - - /** A class representing `deprecated_operator_declaration_body` nodes. */ - class DeprecatedOperatorDeclarationBody extends @swift_deprecated_operator_declaration_body, - AstNode - { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DeprecatedOperatorDeclarationBody" } - - /** Gets the node corresponding to the field `entry`. */ - final AstNode getEntry(int i) { - swift_deprecated_operator_declaration_body_entry(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_deprecated_operator_declaration_body_entry(this, _, result) - } - } - - /** A class representing `diagnostic` tokens. */ - class Diagnostic extends @swift_token_diagnostic, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Diagnostic" } - } - - /** A class representing `dictionary_literal` nodes. */ - class DictionaryLiteral extends @swift_dictionary_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DictionaryLiteral" } - - /** Gets the node corresponding to the field `element`. */ - final DictionaryLiteralItem getElement(int i) { - swift_dictionary_literal_element(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_dictionary_literal_element(this, _, result) } - } - - /** A class representing `dictionary_literal_item` nodes. */ - class DictionaryLiteralItem extends @swift_dictionary_literal_item, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DictionaryLiteralItem" } - - /** Gets the node corresponding to the field `key`. */ - final Expression getKey() { swift_dictionary_literal_item_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_dictionary_literal_item_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_dictionary_literal_item_def(this, result, _) or - swift_dictionary_literal_item_def(this, _, result) - } - } - - /** A class representing `dictionary_type` nodes. */ - class DictionaryType extends @swift_dictionary_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DictionaryType" } - - /** Gets the node corresponding to the field `key`. */ - final Type getKey() { swift_dictionary_type_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Type getValue() { swift_dictionary_type_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_dictionary_type_def(this, result, _) or swift_dictionary_type_def(this, _, result) - } - } - - /** A class representing `didset_clause` nodes. */ - class DidsetClause extends @swift_didset_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DidsetClause" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_didset_clause_def(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_didset_clause_modifiers(this, result) } - - /** Gets the node corresponding to the field `parameter`. */ - final SimpleIdentifier getParameter() { swift_didset_clause_parameter(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_didset_clause_def(this, result) or - swift_didset_clause_modifiers(this, result) or - swift_didset_clause_parameter(this, result) - } - } - - /** A class representing `directive` nodes. */ - class Directive extends @swift_directive, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Directive" } - - /** Gets the node corresponding to the field `condition`. */ - final CompilationCondition getCondition() { swift_directive_condition(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_directive_condition(this, result) } - } - - /** A class representing `directly_assignable_expression` nodes. */ - class DirectlyAssignableExpression extends @swift_directly_assignable_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DirectlyAssignableExpression" } + final override string getAPrimaryQlClass() { result = "ExprCondition" } /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_directly_assignable_expression_def(this, result) } + final Expr getExpr() { unified_expr_condition_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_directly_assignable_expression_def(this, result) - } + final override AstNode getAFieldOrChild() { unified_expr_condition_def(this, result) } } - /** A class representing `disjunction_expression` nodes. */ - class DisjunctionExpression extends @swift_disjunction_expression, AstNode { + /** A class representing `expr_stmt` nodes. */ + class ExprStmt extends @unified_expr_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DisjunctionExpression" } + final override string getAPrimaryQlClass() { result = "ExprStmt" } - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_disjunction_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_disjunction_expression_def(this, _, value, _) | - (result = "||" and value = 0) - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_disjunction_expression_def(this, _, _, result) } + /** Gets the node corresponding to the field `expr`. */ + final Expr getExpr() { unified_expr_stmt_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_disjunction_expression_def(this, result, _, _) or - swift_disjunction_expression_def(this, _, _, result) - } + final override AstNode getAFieldOrChild() { unified_expr_stmt_def(this, result) } } - /** A class representing `do_statement` nodes. */ - class DoStatement extends @swift_do_statement, AstNode { + /** A class representing `guard_if_stmt` nodes. */ + class GuardIfStmt extends @unified_guard_if_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "DoStatement" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_do_statement_def(this, result) } - - /** Gets the node corresponding to the field `catch`. */ - final CatchBlock getCatch(int i) { swift_do_statement_catch(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_do_statement_def(this, result) or swift_do_statement_catch(this, _, result) - } - } - - /** A class representing `enum_case_entry` nodes. */ - class EnumCaseEntry extends @swift_enum_case_entry, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumCaseEntry" } - - /** Gets the node corresponding to the field `data_contents`. */ - final EnumTypeParameters getDataContents() { swift_enum_case_entry_data_contents(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_enum_case_entry_def(this, result) } - - /** Gets the node corresponding to the field `raw_value`. */ - final Expression getRawValue() { swift_enum_case_entry_raw_value(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_enum_case_entry_data_contents(this, result) or - swift_enum_case_entry_def(this, result) or - swift_enum_case_entry_raw_value(this, result) - } - } - - /** A class representing `enum_class_body` nodes. */ - class EnumClassBody extends @swift_enum_class_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumClassBody" } - - /** Gets the node corresponding to the field `member`. */ - final AstNode getMember(int i) { swift_enum_class_body_member(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_enum_class_body_member(this, _, result) } - } - - /** A class representing `enum_entry` nodes. */ - class EnumEntry extends @swift_enum_entry, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumEntry" } - - /** Gets the node corresponding to the field `case`. */ - final EnumCaseEntry getCase(int i) { swift_enum_entry_case(this, i, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_enum_entry_modifiers(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_enum_entry_case(this, _, result) or swift_enum_entry_modifiers(this, result) - } - } - - /** A class representing `enum_type_parameter` nodes. */ - class EnumTypeParameter extends @swift_enum_type_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumTypeParameter" } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue() { swift_enum_type_parameter_default_value(this, result) } - - /** Gets the node corresponding to the field `external_name`. */ - final WildcardPattern getExternalName() { - swift_enum_type_parameter_external_name(this, result) - } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_enum_type_parameter_name(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_enum_type_parameter_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_enum_type_parameter_default_value(this, result) or - swift_enum_type_parameter_external_name(this, result) or - swift_enum_type_parameter_name(this, result) or - swift_enum_type_parameter_def(this, result) - } - } - - /** A class representing `enum_type_parameters` nodes. */ - class EnumTypeParameters extends @swift_enum_type_parameters, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EnumTypeParameters" } - - /** Gets the node corresponding to the field `parameter`. */ - final EnumTypeParameter getParameter(int i) { - swift_enum_type_parameters_parameter(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_enum_type_parameters_parameter(this, _, result) - } - } - - /** A class representing `equality_constraint` nodes. */ - class EqualityConstraint extends @swift_equality_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EqualityConstraint" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_equality_constraint_attribute(this, i, result) } - - /** Gets the node corresponding to the field `constrained_type`. */ - final AstNode getConstrainedType() { swift_equality_constraint_def(this, result, _) } - - /** Gets the node corresponding to the field `must_equal`. */ - final Type getMustEqual() { swift_equality_constraint_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_equality_constraint_attribute(this, _, result) or - swift_equality_constraint_def(this, result, _) or - swift_equality_constraint_def(this, _, result) - } - } - - /** A class representing `equality_expression` nodes. */ - class EqualityExpression extends @swift_equality_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "EqualityExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_equality_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_equality_expression_def(this, _, value, _) | - result = "!=" and value = 0 - or - result = "!==" and value = 1 - or - result = "==" and value = 2 - or - result = "===" and value = 3 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_equality_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_equality_expression_def(this, result, _, _) or - swift_equality_expression_def(this, _, _, result) - } - } - - /** A class representing `existential_type` nodes. */ - class ExistentialType extends @swift_existential_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ExistentialType" } - - /** Gets the node corresponding to the field `name`. */ - final UnannotatedType getName() { swift_existential_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_existential_type_def(this, result) } - } - - class Expression extends @swift_expression, AstNode { } - - /** A class representing `external_macro_definition` nodes. */ - class ExternalMacroDefinition extends @swift_external_macro_definition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ExternalMacroDefinition" } - - /** Gets the node corresponding to the field `arguments`. */ - final ValueArguments getArguments() { swift_external_macro_definition_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_external_macro_definition_def(this, result) } - } - - /** A class representing `for_statement` nodes. */ - class ForStatement extends @swift_for_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ForStatement" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_for_statement_def(this, result, _, _) } - - /** Gets the node corresponding to the field `collection`. */ - final Expression getCollection() { swift_for_statement_def(this, _, result, _) } - - /** Gets the node corresponding to the field `item`. */ - final Pattern getItem() { swift_for_statement_def(this, _, _, result) } - - /** Gets the node corresponding to the field `try`. */ - final TryOperator getTry() { swift_for_statement_try(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final TypeAnnotation getType() { swift_for_statement_type(this, result) } - - /** Gets the node corresponding to the field `where`. */ - final WhereClause getWhere() { swift_for_statement_where(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_for_statement_def(this, result, _, _) or - swift_for_statement_def(this, _, result, _) or - swift_for_statement_def(this, _, _, result) or - swift_for_statement_try(this, result) or - swift_for_statement_type(this, result) or - swift_for_statement_where(this, result) - } - } - - /** A class representing `fully_open_range` tokens. */ - class FullyOpenRange extends @swift_token_fully_open_range, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FullyOpenRange" } - } - - /** A class representing `function_declaration` nodes. */ - class FunctionDeclaration extends @swift_function_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionDeclaration" } - - /** Gets the node corresponding to the field `async`. */ - final ReservedWord getAsync() { swift_function_declaration_async(this, result) } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_function_declaration_def(this, result, _) } - - /** Gets the node corresponding to the field `modifiers`. */ - final AstNode getModifiers(int i) { swift_function_declaration_modifiers(this, i, result) } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_function_declaration_def(this, _, result) } - - /** Gets the node corresponding to the field `parameter`. */ - final FunctionParameter getParameter(int i) { - swift_function_declaration_parameter(this, i, result) - } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_function_declaration_return_type(this, result) } - - /** Gets the node corresponding to the field `throws`. */ - final AstNode getThrows() { swift_function_declaration_throws(this, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_function_declaration_type_constraints(this, result) - } - - /** Gets the node corresponding to the field `type_parameters`. */ - final TypeParameters getTypeParameters() { - swift_function_declaration_type_parameters(this, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_function_declaration_async(this, result) or - swift_function_declaration_def(this, result, _) or - swift_function_declaration_modifiers(this, _, result) or - swift_function_declaration_def(this, _, result) or - swift_function_declaration_parameter(this, _, result) or - swift_function_declaration_return_type(this, result) or - swift_function_declaration_throws(this, result) or - swift_function_declaration_type_constraints(this, result) or - swift_function_declaration_type_parameters(this, result) - } - } - - /** A class representing `function_modifier` tokens. */ - class FunctionModifier extends @swift_token_function_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionModifier" } - } - - /** A class representing `function_parameter` nodes. */ - class FunctionParameter extends @swift_function_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionParameter" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute() { swift_function_parameter_attribute(this, result) } - - /** Gets the node corresponding to the field `default_value`. */ - final Expression getDefaultValue() { swift_function_parameter_default_value(this, result) } - - /** Gets the node corresponding to the field `parameter`. */ - final Parameter getParameter() { swift_function_parameter_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_function_parameter_attribute(this, result) or - swift_function_parameter_default_value(this, result) or - swift_function_parameter_def(this, result) - } - } - - /** A class representing `function_type` nodes. */ - class FunctionType extends @swift_function_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "FunctionType" } - - /** Gets the node corresponding to the field `async`. */ - final ReservedWord getAsync() { swift_function_type_async(this, result) } - - /** Gets the node corresponding to the field `params`. */ - final UnannotatedType getParams() { swift_function_type_def(this, result, _) } - - /** Gets the node corresponding to the field `return_type`. */ - final Type getReturnType() { swift_function_type_def(this, _, result) } - - /** Gets the node corresponding to the field `throws`. */ - final AstNode getThrows() { swift_function_type_throws(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_function_type_async(this, result) or - swift_function_type_def(this, result, _) or - swift_function_type_def(this, _, result) or - swift_function_type_throws(this, result) - } - } - - /** A class representing `getter_specifier` nodes. */ - class GetterSpecifier extends @swift_getter_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "GetterSpecifier" } - - /** Gets the node corresponding to the field `effect`. */ - final AstNode getEffect(int i) { swift_getter_specifier_effect(this, i, result) } - - /** Gets the node corresponding to the field `mutation`. */ - final MutationModifier getMutation() { swift_getter_specifier_mutation(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_getter_specifier_effect(this, _, result) or - swift_getter_specifier_mutation(this, result) - } - } - - class GlobalDeclaration extends @swift_global_declaration, AstNode { } - - /** A class representing `guard_statement` nodes. */ - class GuardStatement extends @swift_guard_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "GuardStatement" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_guard_statement_def(this, result) } + final override string getAPrimaryQlClass() { result = "GuardIfStmt" } /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { swift_guard_statement_condition(this, i, result) } + final Condition getCondition() { unified_guard_if_stmt_def(this, result, _) } + + /** Gets the node corresponding to the field `else`. */ + final Stmt getElse() { unified_guard_if_stmt_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_guard_statement_def(this, result) or swift_guard_statement_condition(this, _, result) + unified_guard_if_stmt_def(this, result, _) or unified_guard_if_stmt_def(this, _, result) } } - /** A class representing `hex_literal` tokens. */ - class HexLiteral extends @swift_token_hex_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "HexLiteral" } - } - - /** A class representing `identifier` nodes. */ - class Identifier extends @swift_identifier, AstNode { + /** A class representing `identifier` tokens. */ + class Identifier extends @unified_token_identifier, Token { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Identifier" } - - /** Gets the node corresponding to the field `part`. */ - final SimpleIdentifier getPart(int i) { swift_identifier_part(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_identifier_part(this, _, result) } } - /** A class representing `if_condition` nodes. */ - class IfCondition extends @swift_if_condition, AstNode { + /** A class representing `if_stmt` nodes. */ + class IfStmt extends @unified_if_stmt, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IfCondition" } - - /** Gets the node corresponding to the field `kind`. */ - final AstNode getKind() { swift_if_condition_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_if_condition_def(this, result) } - } - - /** A class representing `if_let_binding` nodes. */ - class IfLetBinding extends @swift_if_let_binding, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IfLetBinding" } - - /** Gets the node corresponding to the field `pattern`. */ - final Pattern getPattern() { swift_if_let_binding_def(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final TypeAnnotation getType() { swift_if_let_binding_type(this, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_if_let_binding_value(this, result) } - - /** Gets the node corresponding to the field `where`. */ - final WhereClause getWhere() { swift_if_let_binding_where(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_if_let_binding_def(this, result) or - swift_if_let_binding_type(this, result) or - swift_if_let_binding_value(this, result) or - swift_if_let_binding_where(this, result) - } - } - - /** A class representing `if_statement` nodes. */ - class IfStatement extends @swift_if_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IfStatement" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_if_statement_def(this, result) } + final override string getAPrimaryQlClass() { result = "IfStmt" } /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { swift_if_statement_condition(this, i, result) } + final Condition getCondition() { unified_if_stmt_def(this, result) } - /** Gets the node corresponding to the field `else_branch`. */ - final AstNode getElseBranch() { swift_if_statement_else_branch(this, result) } + /** Gets the node corresponding to the field `else`. */ + final Stmt getElse() { unified_if_stmt_else(this, result) } + + /** Gets the node corresponding to the field `then`. */ + final Stmt getThen() { unified_if_stmt_then(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_if_statement_def(this, result) or - swift_if_statement_condition(this, _, result) or - swift_if_statement_else_branch(this, result) + unified_if_stmt_def(this, result) or + unified_if_stmt_else(this, result) or + unified_if_stmt_then(this, result) } } - /** A class representing `implicitly_unwrapped_type` nodes. */ - class ImplicitlyUnwrappedType extends @swift_implicitly_unwrapped_type, AstNode { + /** A class representing `ignore_pattern` tokens. */ + class IgnorePattern extends @unified_token_ignore_pattern, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ImplicitlyUnwrappedType" } - - /** Gets the node corresponding to the field `name`. */ - final Type getName() { swift_implicitly_unwrapped_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_implicitly_unwrapped_type_def(this, result) } + final override string getAPrimaryQlClass() { result = "IgnorePattern" } } - /** A class representing `import_declaration` nodes. */ - class ImportDeclaration extends @swift_import_declaration, AstNode { + /** A class representing `int_literal` tokens. */ + class IntLiteral extends @unified_token_int_literal, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ImportDeclaration" } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_import_declaration_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final Identifier getName() { swift_import_declaration_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_import_declaration_modifiers(this, result) or swift_import_declaration_def(this, result) - } + final override string getAPrimaryQlClass() { result = "IntLiteral" } } - /** A class representing `infix_expression` nodes. */ - class InfixExpression extends @swift_infix_expression, AstNode { + /** A class representing `lambda_expr` nodes. */ + class LambdaExpr extends @unified_lambda_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InfixExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_infix_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final CustomOperator getOp() { swift_infix_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_infix_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_infix_expression_def(this, result, _, _) or - swift_infix_expression_def(this, _, result, _) or - swift_infix_expression_def(this, _, _, result) - } - } - - /** A class representing `inheritance_constraint` nodes. */ - class InheritanceConstraint extends @swift_inheritance_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InheritanceConstraint" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_inheritance_constraint_attribute(this, i, result) } - - /** Gets the node corresponding to the field `constrained_type`. */ - final AstNode getConstrainedType() { swift_inheritance_constraint_def(this, result, _) } - - /** Gets the node corresponding to the field `inherits_from`. */ - final AstNode getInheritsFrom() { swift_inheritance_constraint_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_inheritance_constraint_attribute(this, _, result) or - swift_inheritance_constraint_def(this, result, _) or - swift_inheritance_constraint_def(this, _, result) - } - } - - /** A class representing `inheritance_modifier` tokens. */ - class InheritanceModifier extends @swift_token_inheritance_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InheritanceModifier" } - } - - /** A class representing `inheritance_specifier` nodes. */ - class InheritanceSpecifier extends @swift_inheritance_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InheritanceSpecifier" } - - /** Gets the node corresponding to the field `inherits_from`. */ - final AstNode getInheritsFrom() { swift_inheritance_specifier_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_inheritance_specifier_def(this, result) } - } - - /** A class representing `init_declaration` nodes. */ - class InitDeclaration extends @swift_init_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InitDeclaration" } - - /** Gets the node corresponding to the field `async`. */ - final ReservedWord getAsync() { swift_init_declaration_async(this, result) } - - /** Gets the node corresponding to the field `bang`. */ - final Bang getBang() { swift_init_declaration_bang(this, result) } + final override string getAPrimaryQlClass() { result = "LambdaExpr" } /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_init_declaration_body(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_init_declaration_modifiers(this, result) } + final AstNode getBody() { unified_lambda_expr_def(this, result) } /** Gets the node corresponding to the field `parameter`. */ - final FunctionParameter getParameter(int i) { - swift_init_declaration_parameter(this, i, result) - } - - /** Gets the node corresponding to the field `throws`. */ - final AstNode getThrows() { swift_init_declaration_throws(this, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_init_declaration_type_constraints(this, result) - } - - /** Gets the node corresponding to the field `type_parameters`. */ - final TypeParameters getTypeParameters() { - swift_init_declaration_type_parameters(this, result) - } + final Parameter getParameter(int i) { unified_lambda_expr_parameter(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_init_declaration_async(this, result) or - swift_init_declaration_bang(this, result) or - swift_init_declaration_body(this, result) or - swift_init_declaration_modifiers(this, result) or - swift_init_declaration_parameter(this, _, result) or - swift_init_declaration_throws(this, result) or - swift_init_declaration_type_constraints(this, result) or - swift_init_declaration_type_parameters(this, result) + unified_lambda_expr_def(this, result) or unified_lambda_expr_parameter(this, _, result) } } - /** A class representing `integer_literal` tokens. */ - class IntegerLiteral extends @swift_token_integer_literal, Token { + /** A class representing `let_pattern_condition` nodes. */ + class LetPatternCondition extends @unified_let_pattern_condition, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "IntegerLiteral" } - } + final override string getAPrimaryQlClass() { result = "LetPatternCondition" } - /** A class representing `interpolated_expression` nodes. */ - class InterpolatedExpression extends @swift_interpolated_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "InterpolatedExpression" } - - /** Gets the node corresponding to the field `name`. */ - final ValueArgumentLabel getName() { swift_interpolated_expression_name(this, result) } - - /** Gets the node corresponding to the field `reference_specifier`. */ - final ValueArgumentLabel getReferenceSpecifier(int i) { - swift_interpolated_expression_reference_specifier(this, i, result) - } - - /** Gets the node corresponding to the field `type_modifiers`. */ - final TypeModifiers getTypeModifiers() { - swift_interpolated_expression_type_modifiers(this, result) - } + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { unified_let_pattern_condition_def(this, result, _) } /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_interpolated_expression_value(this, result) } + final Expr getValue() { unified_let_pattern_condition_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_interpolated_expression_name(this, result) or - swift_interpolated_expression_reference_specifier(this, _, result) or - swift_interpolated_expression_type_modifiers(this, result) or - swift_interpolated_expression_value(this, result) + unified_let_pattern_condition_def(this, result, _) or + unified_let_pattern_condition_def(this, _, result) } } - /** A class representing `key_path_component` nodes. */ - class KeyPathComponent extends @swift_key_path_component, AstNode { + /** A class representing `member_access_expr` nodes. */ + class MemberAccessExpr extends @unified_member_access_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "KeyPathComponent" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_key_path_component_name(this, result) } - - /** Gets the node corresponding to the field `postfix`. */ - final KeyPathPostfix getPostfix(int i) { swift_key_path_component_postfix(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_key_path_component_name(this, result) or - swift_key_path_component_postfix(this, _, result) - } - } - - /** A class representing `key_path_expression` nodes. */ - class KeyPathExpression extends @swift_key_path_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "KeyPathExpression" } - - /** Gets the node corresponding to the field `component`. */ - final KeyPathComponent getComponent(int i) { - swift_key_path_expression_component(this, i, result) - } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_key_path_expression_type(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_key_path_expression_component(this, _, result) or - swift_key_path_expression_type(this, result) - } - } - - /** A class representing `key_path_postfix` nodes. */ - class KeyPathPostfix extends @swift_key_path_postfix, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "KeyPathPostfix" } - - /** Gets the node corresponding to the field `argument`. */ - final ValueArgument getArgument(int i) { swift_key_path_postfix_argument(this, i, result) } - - /** Gets the node corresponding to the field `force_unwrap`. */ - final Bang getForceUnwrap() { swift_key_path_postfix_force_unwrap(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_key_path_postfix_argument(this, _, result) or - swift_key_path_postfix_force_unwrap(this, result) - } - } - - /** A class representing `key_path_string_expression` nodes. */ - class KeyPathStringExpression extends @swift_key_path_string_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "KeyPathStringExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_key_path_string_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_key_path_string_expression_def(this, result) } - } - - /** A class representing `lambda_function_type` nodes. */ - class LambdaFunctionType extends @swift_lambda_function_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaFunctionType" } - - /** Gets the node corresponding to the field `async`. */ - final ReservedWord getAsync() { swift_lambda_function_type_async(this, result) } - - /** Gets the node corresponding to the field `params`. */ - final LambdaFunctionTypeParameters getParams() { - swift_lambda_function_type_params(this, result) - } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_lambda_function_type_return_type(this, result) } - - /** Gets the node corresponding to the field `throws`. */ - final AstNode getThrows() { swift_lambda_function_type_throws(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_function_type_async(this, result) or - swift_lambda_function_type_params(this, result) or - swift_lambda_function_type_return_type(this, result) or - swift_lambda_function_type_throws(this, result) - } - } - - /** A class representing `lambda_function_type_parameters` nodes. */ - class LambdaFunctionTypeParameters extends @swift_lambda_function_type_parameters, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaFunctionTypeParameters" } - - /** Gets the node corresponding to the field `parameter`. */ - final LambdaParameter getParameter(int i) { - swift_lambda_function_type_parameters_parameter(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_function_type_parameters_parameter(this, _, result) - } - } - - /** A class representing `lambda_literal` nodes. */ - class LambdaLiteral extends @swift_lambda_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaLiteral" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_lambda_literal_attribute(this, i, result) } - - /** Gets the node corresponding to the field `captures`. */ - final CaptureList getCaptures() { swift_lambda_literal_captures(this, result) } - - /** Gets the node corresponding to the field `statement`. */ - final AstNode getStatement(int i) { swift_lambda_literal_statement(this, i, result) } - - /** Gets the node corresponding to the field `type`. */ - final LambdaFunctionType getType() { swift_lambda_literal_type(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_literal_attribute(this, _, result) or - swift_lambda_literal_captures(this, result) or - swift_lambda_literal_statement(this, _, result) or - swift_lambda_literal_type(this, result) - } - } - - /** A class representing `lambda_parameter` nodes. */ - class LambdaParameter extends @swift_lambda_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LambdaParameter" } - - /** Gets the node corresponding to the field `external_name`. */ - final SimpleIdentifier getExternalName() { swift_lambda_parameter_external_name(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final ParameterModifiers getModifiers() { swift_lambda_parameter_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_lambda_parameter_def(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_lambda_parameter_type(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_lambda_parameter_external_name(this, result) or - swift_lambda_parameter_modifiers(this, result) or - swift_lambda_parameter_def(this, result) or - swift_lambda_parameter_type(this, result) - } - } - - /** A class representing `line_str_text` tokens. */ - class LineStrText extends @swift_token_line_str_text, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LineStrText" } - } - - /** A class representing `line_string_literal` nodes. */ - class LineStringLiteral extends @swift_line_string_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "LineStringLiteral" } - - /** Gets the node corresponding to the field `interpolation`. */ - final InterpolatedExpression getInterpolation(int i) { - swift_line_string_literal_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `text`. */ - final AstNode getText(int i) { swift_line_string_literal_text(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_line_string_literal_interpolation(this, _, result) or - swift_line_string_literal_text(this, _, result) - } - } - - class LocalDeclaration extends @swift_local_declaration, AstNode { } - - /** A class representing `macro_declaration` nodes. */ - class MacroDeclaration extends @swift_macro_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MacroDeclaration" } - - /** Gets the node corresponding to the field `definition`. */ - final MacroDefinition getDefinition() { swift_macro_declaration_definition(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_macro_declaration_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_macro_declaration_def(this, result) } - - /** Gets the node corresponding to the field `parameter`. */ - final FunctionParameter getParameter(int i) { - swift_macro_declaration_parameter(this, i, result) - } - - /** Gets the node corresponding to the field `return_type`. */ - final UnannotatedType getReturnType() { swift_macro_declaration_return_type(this, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_macro_declaration_type_constraints(this, result) - } - - /** Gets the node corresponding to the field `type_parameters`. */ - final TypeParameters getTypeParameters() { - swift_macro_declaration_type_parameters(this, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_macro_declaration_definition(this, result) or - swift_macro_declaration_modifiers(this, result) or - swift_macro_declaration_def(this, result) or - swift_macro_declaration_parameter(this, _, result) or - swift_macro_declaration_return_type(this, result) or - swift_macro_declaration_type_constraints(this, result) or - swift_macro_declaration_type_parameters(this, result) - } - } - - /** A class representing `macro_definition` nodes. */ - class MacroDefinition extends @swift_macro_definition, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MacroDefinition" } - - /** Gets the node corresponding to the field `body`. */ - final AstNode getBody() { swift_macro_definition_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_macro_definition_def(this, result) } - } - - /** A class representing `macro_invocation` nodes. */ - class MacroInvocation extends @swift_macro_invocation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MacroInvocation" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_macro_invocation_def(this, result, _) } - - /** Gets the node corresponding to the field `suffix`. */ - final CallSuffix getSuffix() { swift_macro_invocation_def(this, _, result) } - - /** Gets the node corresponding to the field `type_parameters`. */ - final TypeParameters getTypeParameters() { - swift_macro_invocation_type_parameters(this, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_macro_invocation_def(this, result, _) or - swift_macro_invocation_def(this, _, result) or - swift_macro_invocation_type_parameters(this, result) - } - } - - /** A class representing `member_modifier` tokens. */ - class MemberModifier extends @swift_token_member_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MemberModifier" } - } - - /** A class representing `metatype` nodes. */ - class Metatype extends @swift_metatype, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Metatype" } - - /** Gets the node corresponding to the field `name`. */ - final UnannotatedType getName() { swift_metatype_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_metatype_def(this, result) } - } - - /** A class representing `modifiers` nodes. */ - class Modifiers extends @swift_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Modifiers" } - - /** Gets the node corresponding to the field `modifier`. */ - final AstNode getModifier(int i) { swift_modifiers_modifier(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_modifiers_modifier(this, _, result) } - } - - /** A class representing `modify_specifier` nodes. */ - class ModifySpecifier extends @swift_modify_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ModifySpecifier" } - - /** Gets the node corresponding to the field `mutation`. */ - final MutationModifier getMutation() { swift_modify_specifier_mutation(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_modify_specifier_mutation(this, result) } - } - - /** A class representing `multi_line_str_text` tokens. */ - class MultiLineStrText extends @swift_token_multi_line_str_text, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultiLineStrText" } - } - - /** A class representing `multi_line_string_literal` nodes. */ - class MultiLineStringLiteral extends @swift_multi_line_string_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultiLineStringLiteral" } - - /** Gets the node corresponding to the field `interpolation`. */ - final InterpolatedExpression getInterpolation(int i) { - swift_multi_line_string_literal_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `text`. */ - final AstNode getText(int i) { swift_multi_line_string_literal_text(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_multi_line_string_literal_interpolation(this, _, result) or - swift_multi_line_string_literal_text(this, _, result) - } - } - - /** A class representing `multiline_comment` tokens. */ - class MultilineComment extends @swift_token_multiline_comment, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultilineComment" } - } - - /** A class representing `multiplicative_expression` nodes. */ - class MultiplicativeExpression extends @swift_multiplicative_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MultiplicativeExpression" } - - /** Gets the node corresponding to the field `lhs`. */ - final Expression getLhs() { swift_multiplicative_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_multiplicative_expression_def(this, _, value, _) | - result = "%" and value = 0 - or - result = "*" and value = 1 - or - result = "/" and value = 2 - ) - } - - /** Gets the node corresponding to the field `rhs`. */ - final Expression getRhs() { swift_multiplicative_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_multiplicative_expression_def(this, result, _, _) or - swift_multiplicative_expression_def(this, _, _, result) - } - } - - /** A class representing `mutation_modifier` tokens. */ - class MutationModifier extends @swift_token_mutation_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "MutationModifier" } - } - - /** A class representing `navigation_expression` nodes. */ - class NavigationExpression extends @swift_navigation_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NavigationExpression" } - - /** Gets the node corresponding to the field `suffix`. */ - final NavigationSuffix getSuffix() { swift_navigation_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `target`. */ - final AstNode getTarget() { swift_navigation_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_navigation_expression_def(this, result, _) or - swift_navigation_expression_def(this, _, result) - } - } - - /** A class representing `navigation_suffix` nodes. */ - class NavigationSuffix extends @swift_navigation_suffix, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NavigationSuffix" } - - /** Gets the node corresponding to the field `suffix`. */ - final AstNode getSuffix() { swift_navigation_suffix_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_navigation_suffix_def(this, result) } - } - - /** A class representing `nested_type_identifier` nodes. */ - class NestedTypeIdentifier extends @swift_nested_type_identifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NestedTypeIdentifier" } - - /** Gets the node corresponding to the field `base`. */ - final UnannotatedType getBase() { swift_nested_type_identifier_def(this, result) } + final override string getAPrimaryQlClass() { result = "MemberAccessExpr" } /** Gets the node corresponding to the field `member`. */ - final SimpleIdentifier getMember(int i) { swift_nested_type_identifier_member(this, i, result) } + final Identifier getMember() { unified_member_access_expr_def(this, result, _) } + + /** Gets the node corresponding to the field `target`. */ + final Expr getTarget() { unified_member_access_expr_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_nested_type_identifier_def(this, result) or - swift_nested_type_identifier_member(this, _, result) + unified_member_access_expr_def(this, result, _) or + unified_member_access_expr_def(this, _, result) } } - /** A class representing `nil_coalescing_expression` nodes. */ - class NilCoalescingExpression extends @swift_nil_coalescing_expression, AstNode { + /** A class representing `name_expr` nodes. */ + class NameExpr extends @unified_name_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "NilCoalescingExpression" } + final override string getAPrimaryQlClass() { result = "NameExpr" } - /** Gets the node corresponding to the field `if_nil`. */ - final Expression getIfNil() { swift_nil_coalescing_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_nil_coalescing_expression_def(this, _, result) } + /** Gets the node corresponding to the field `identifier`. */ + final Identifier getIdentifier() { unified_name_expr_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_nil_coalescing_expression_def(this, result, _) or - swift_nil_coalescing_expression_def(this, _, result) - } + final override AstNode getAFieldOrChild() { unified_name_expr_def(this, result) } } - /** A class representing `oct_literal` tokens. */ - class OctLiteral extends @swift_token_oct_literal, Token { + /** A class representing `operator` tokens. */ + class Operator extends @unified_token_operator, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OctLiteral" } - } - - /** A class representing `opaque_type` nodes. */ - class OpaqueType extends @swift_opaque_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OpaqueType" } - - /** Gets the node corresponding to the field `name`. */ - final UnannotatedType getName() { swift_opaque_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_opaque_type_def(this, result) } - } - - /** A class representing `open_end_range_expression` nodes. */ - class OpenEndRangeExpression extends @swift_open_end_range_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OpenEndRangeExpression" } - - /** Gets the node corresponding to the field `start`. */ - final Expression getStart() { swift_open_end_range_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_open_end_range_expression_def(this, result) } - } - - /** A class representing `open_start_range_expression` nodes. */ - class OpenStartRangeExpression extends @swift_open_start_range_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OpenStartRangeExpression" } - - /** Gets the node corresponding to the field `end`. */ - final Expression getEnd() { swift_open_start_range_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_open_start_range_expression_def(this, result) - } - } - - /** A class representing `operator_declaration` nodes. */ - class OperatorDeclaration extends @swift_operator_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OperatorDeclaration" } - - /** Gets the node corresponding to the field `body`. */ - final DeprecatedOperatorDeclarationBody getBody() { - swift_operator_declaration_body(this, result) - } - - /** Gets the node corresponding to the field `kind`. */ - final string getKind() { - exists(int value | swift_operator_declaration_def(this, value, _) | - result = "infix" and value = 0 - or - result = "postfix" and value = 1 - or - result = "prefix" and value = 2 - ) - } - - /** Gets the node corresponding to the field `name`. */ - final ReferenceableOperator getName() { swift_operator_declaration_def(this, _, result) } - - /** Gets the node corresponding to the field `precedence_group`. */ - final SimpleIdentifier getPrecedenceGroup() { - swift_operator_declaration_precedence_group(this, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_operator_declaration_body(this, result) or - swift_operator_declaration_def(this, _, result) or - swift_operator_declaration_precedence_group(this, result) - } - } - - /** A class representing `optional_chain_marker` nodes. */ - class OptionalChainMarker extends @swift_optional_chain_marker, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OptionalChainMarker" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_optional_chain_marker_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_optional_chain_marker_def(this, result) } - } - - /** A class representing `optional_type` nodes. */ - class OptionalType extends @swift_optional_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OptionalType" } - - /** Gets the node corresponding to the field `wrapped`. */ - final AstNode getWrapped() { swift_optional_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_optional_type_def(this, result) } - } - - /** A class representing `ownership_modifier` tokens. */ - class OwnershipModifier extends @swift_token_ownership_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "OwnershipModifier" } + final override string getAPrimaryQlClass() { result = "Operator" } } /** A class representing `parameter` nodes. */ - class Parameter extends @swift_parameter, AstNode { + class Parameter extends @unified_parameter, AstNode { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Parameter" } - /** Gets the node corresponding to the field `external_name`. */ - final SimpleIdentifier getExternalName() { swift_parameter_external_name(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final ParameterModifiers getModifiers() { swift_parameter_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_parameter_def(this, result, _) } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_parameter_def(this, _, result) } + /** Gets the node corresponding to the field `pattern`. */ + final Pattern getPattern() { unified_parameter_def(this, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_parameter_external_name(this, result) or - swift_parameter_modifiers(this, result) or - swift_parameter_def(this, result, _) or - swift_parameter_def(this, _, result) - } + final override AstNode getAFieldOrChild() { unified_parameter_def(this, result) } } - /** A class representing `parameter_modifier` tokens. */ - class ParameterModifier extends @swift_token_parameter_modifier, Token { + class Pattern extends @unified_pattern, AstNode { } + + /** A class representing `sequence_condition` nodes. */ + class SequenceCondition extends @unified_sequence_condition, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ParameterModifier" } - } - - /** A class representing `parameter_modifiers` nodes. */ - class ParameterModifiers extends @swift_parameter_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ParameterModifiers" } - - /** Gets the node corresponding to the field `modifier`. */ - final ParameterModifier getModifier(int i) { - swift_parameter_modifiers_modifier(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_parameter_modifiers_modifier(this, _, result) - } - } - - /** A class representing `parenthesized_type` nodes. */ - class ParenthesizedType extends @swift_parenthesized_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ParenthesizedType" } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_parenthesized_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_parenthesized_type_def(this, result) } - } - - /** A class representing `pattern` nodes. */ - class Pattern extends @swift_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Pattern" } - - /** Gets the node corresponding to the field `binding`. */ - final ValueBindingPattern getBinding() { swift_pattern_binding(this, result) } - - /** Gets the node corresponding to the field `bound_identifier`. */ - final SimpleIdentifier getBoundIdentifier() { swift_pattern_bound_identifier(this, result) } - - /** Gets the node corresponding to the field `kind`. */ - final AstNode getKind() { swift_pattern_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_pattern_binding(this, result) or - swift_pattern_bound_identifier(this, result) or - swift_pattern_def(this, result) - } - } - - /** A class representing `playground_literal` nodes. */ - class PlaygroundLiteral extends @swift_playground_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PlaygroundLiteral" } - - /** Gets the node corresponding to the field `argument`. */ - final PlaygroundLiteralArgument getArgument(int i) { - swift_playground_literal_argument(this, i, result) - } - - /** Gets the node corresponding to the field `kind`. */ - final string getKind() { - exists(int value | swift_playground_literal_def(this, value) | - result = "colorLiteral" and value = 0 - or - result = "fileLiteral" and value = 1 - or - result = "imageLiteral" and value = 2 - ) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_playground_literal_argument(this, _, result) } - } - - /** A class representing `playground_literal_argument` nodes. */ - class PlaygroundLiteralArgument extends @swift_playground_literal_argument, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PlaygroundLiteralArgument" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_playground_literal_argument_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_playground_literal_argument_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_playground_literal_argument_def(this, result, _) or - swift_playground_literal_argument_def(this, _, result) - } - } - - /** A class representing `postfix_expression` nodes. */ - class PostfixExpression extends @swift_postfix_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PostfixExpression" } - - /** Gets the node corresponding to the field `operation`. */ - final AstNode getOperation() { swift_postfix_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `target`. */ - final Expression getTarget() { swift_postfix_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_postfix_expression_def(this, result, _) or swift_postfix_expression_def(this, _, result) - } - } - - /** A class representing `precedence_group_attribute` nodes. */ - class PrecedenceGroupAttribute extends @swift_precedence_group_attribute, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrecedenceGroupAttribute" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_precedence_group_attribute_def(this, result, _) } - - /** Gets the node corresponding to the field `value`. */ - final AstNode getValue() { swift_precedence_group_attribute_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_precedence_group_attribute_def(this, result, _) or - swift_precedence_group_attribute_def(this, _, result) - } - } - - /** A class representing `precedence_group_attributes` nodes. */ - class PrecedenceGroupAttributes extends @swift_precedence_group_attributes, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrecedenceGroupAttributes" } - - /** Gets the node corresponding to the field `attribute`. */ - final PrecedenceGroupAttribute getAttribute(int i) { - swift_precedence_group_attributes_attribute(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_precedence_group_attributes_attribute(this, _, result) - } - } - - /** A class representing `precedence_group_declaration` nodes. */ - class PrecedenceGroupDeclaration extends @swift_precedence_group_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrecedenceGroupDeclaration" } - - /** Gets the node corresponding to the field `attributes`. */ - final PrecedenceGroupAttributes getAttributes() { - swift_precedence_group_declaration_attributes(this, result) - } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_precedence_group_declaration_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_precedence_group_declaration_attributes(this, result) or - swift_precedence_group_declaration_def(this, result) - } - } - - /** A class representing `prefix_expression` nodes. */ - class PrefixExpression extends @swift_prefix_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PrefixExpression" } - - /** Gets the node corresponding to the field `operation`. */ - final AstNode getOperation() { swift_prefix_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `target`. */ - final Expression getTarget() { swift_prefix_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_prefix_expression_def(this, result, _) or swift_prefix_expression_def(this, _, result) - } - } - - /** A class representing `property_behavior_modifier` tokens. */ - class PropertyBehaviorModifier extends @swift_token_property_behavior_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyBehaviorModifier" } - } - - /** A class representing `property_binding` nodes. */ - class PropertyBinding extends @swift_property_binding, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyBinding" } - - /** Gets the node corresponding to the field `computed_value`. */ - final ComputedProperty getComputedValue() { - swift_property_binding_computed_value(this, result) - } - - /** Gets the node corresponding to the field `name`. */ - final Pattern getName() { swift_property_binding_def(this, result) } - - /** Gets the node corresponding to the field `observers`. */ - final WillsetDidsetBlock getObservers() { swift_property_binding_observers(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final TypeAnnotation getType() { swift_property_binding_type(this, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_property_binding_type_constraints(this, result) - } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_property_binding_value(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_property_binding_computed_value(this, result) or - swift_property_binding_def(this, result) or - swift_property_binding_observers(this, result) or - swift_property_binding_type(this, result) or - swift_property_binding_type_constraints(this, result) or - swift_property_binding_value(this, result) - } - } - - /** A class representing `property_declaration` nodes. */ - class PropertyDeclaration extends @swift_property_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyDeclaration" } - - /** Gets the node corresponding to the field `binding`. */ - final ValueBindingPattern getBinding() { swift_property_declaration_def(this, result) } - - /** Gets the node corresponding to the field `declarator`. */ - final PropertyBinding getDeclarator(int i) { - swift_property_declaration_declarator(this, i, result) - } - - /** Gets the node corresponding to the field `modifiers`. */ - final AstNode getModifiers(int i) { swift_property_declaration_modifiers(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_property_declaration_def(this, result) or - swift_property_declaration_declarator(this, _, result) or - swift_property_declaration_modifiers(this, _, result) - } - } - - /** A class representing `property_modifier` tokens. */ - class PropertyModifier extends @swift_token_property_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "PropertyModifier" } - } - - /** A class representing `protocol_body` nodes. */ - class ProtocolBody extends @swift_protocol_body, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolBody" } - - /** Gets the node corresponding to the field `member`. */ - final ProtocolMemberDeclaration getMember(int i) { swift_protocol_body_member(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_protocol_body_member(this, _, result) } - } - - /** A class representing `protocol_composition_type` nodes. */ - class ProtocolCompositionType extends @swift_protocol_composition_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolCompositionType" } - - /** Gets the node corresponding to the field `type`. */ - final UnannotatedType getType(int i) { swift_protocol_composition_type_type(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_composition_type_type(this, _, result) - } - } - - /** A class representing `protocol_declaration` nodes. */ - class ProtocolDeclaration extends @swift_protocol_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolDeclaration" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_protocol_declaration_attribute(this, i, result) } - - /** Gets the node corresponding to the field `body`. */ - final ProtocolBody getBody() { swift_protocol_declaration_def(this, result, _) } - - /** Gets the node corresponding to the field `inherits`. */ - final InheritanceSpecifier getInherits(int i) { - swift_protocol_declaration_inherits(this, i, result) - } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_protocol_declaration_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_protocol_declaration_def(this, _, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_protocol_declaration_type_constraints(this, result) - } - - /** Gets the node corresponding to the field `type_parameters`. */ - final TypeParameters getTypeParameters() { - swift_protocol_declaration_type_parameters(this, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_declaration_attribute(this, _, result) or - swift_protocol_declaration_def(this, result, _) or - swift_protocol_declaration_inherits(this, _, result) or - swift_protocol_declaration_modifiers(this, result) or - swift_protocol_declaration_def(this, _, result) or - swift_protocol_declaration_type_constraints(this, result) or - swift_protocol_declaration_type_parameters(this, result) - } - } - - /** A class representing `protocol_function_declaration` nodes. */ - class ProtocolFunctionDeclaration extends @swift_protocol_function_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolFunctionDeclaration" } - - /** Gets the node corresponding to the field `async`. */ - final ReservedWord getAsync() { swift_protocol_function_declaration_async(this, result) } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_protocol_function_declaration_body(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_protocol_function_declaration_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_protocol_function_declaration_def(this, result) } - - /** Gets the node corresponding to the field `parameter`. */ - final FunctionParameter getParameter(int i) { - swift_protocol_function_declaration_parameter(this, i, result) - } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_protocol_function_declaration_return_type(this, result) } - - /** Gets the node corresponding to the field `throws`. */ - final AstNode getThrows() { swift_protocol_function_declaration_throws(this, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_protocol_function_declaration_type_constraints(this, result) - } - - /** Gets the node corresponding to the field `type_parameters`. */ - final TypeParameters getTypeParameters() { - swift_protocol_function_declaration_type_parameters(this, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_function_declaration_async(this, result) or - swift_protocol_function_declaration_body(this, result) or - swift_protocol_function_declaration_modifiers(this, result) or - swift_protocol_function_declaration_def(this, result) or - swift_protocol_function_declaration_parameter(this, _, result) or - swift_protocol_function_declaration_return_type(this, result) or - swift_protocol_function_declaration_throws(this, result) or - swift_protocol_function_declaration_type_constraints(this, result) or - swift_protocol_function_declaration_type_parameters(this, result) - } - } - - class ProtocolMemberDeclaration extends @swift_protocol_member_declaration, AstNode { } - - /** A class representing `protocol_property_declaration` nodes. */ - class ProtocolPropertyDeclaration extends @swift_protocol_property_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolPropertyDeclaration" } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_protocol_property_declaration_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final Pattern getName() { swift_protocol_property_declaration_def(this, result, _) } - - /** Gets the node corresponding to the field `requirements`. */ - final ProtocolPropertyRequirements getRequirements() { - swift_protocol_property_declaration_def(this, _, result) - } - - /** Gets the node corresponding to the field `type`. */ - final TypeAnnotation getType() { swift_protocol_property_declaration_type(this, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_protocol_property_declaration_type_constraints(this, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_property_declaration_modifiers(this, result) or - swift_protocol_property_declaration_def(this, result, _) or - swift_protocol_property_declaration_def(this, _, result) or - swift_protocol_property_declaration_type(this, result) or - swift_protocol_property_declaration_type_constraints(this, result) - } - } - - /** A class representing `protocol_property_requirements` nodes. */ - class ProtocolPropertyRequirements extends @swift_protocol_property_requirements, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ProtocolPropertyRequirements" } - - /** Gets the node corresponding to the field `accessor`. */ - final AstNode getAccessor(int i) { - swift_protocol_property_requirements_accessor(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_protocol_property_requirements_accessor(this, _, result) - } - } - - /** A class representing `range_expression` nodes. */ - class RangeExpression extends @swift_range_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RangeExpression" } - - /** Gets the node corresponding to the field `end`. */ - final Expression getEnd() { swift_range_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `op`. */ - final string getOp() { - exists(int value | swift_range_expression_def(this, _, value, _) | - result = "..." and value = 0 - or - result = "..<" and value = 1 - ) - } - - /** Gets the node corresponding to the field `start`. */ - final Expression getStart() { swift_range_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_range_expression_def(this, result, _, _) or - swift_range_expression_def(this, _, _, result) - } - } - - /** A class representing `raw_str_continuing_indicator` tokens. */ - class RawStrContinuingIndicator extends @swift_token_raw_str_continuing_indicator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrContinuingIndicator" } - } - - /** A class representing `raw_str_end_part` tokens. */ - class RawStrEndPart extends @swift_token_raw_str_end_part, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrEndPart" } - } - - /** A class representing `raw_str_interpolation` nodes. */ - class RawStrInterpolation extends @swift_raw_str_interpolation, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrInterpolation" } - - /** Gets the node corresponding to the field `interpolation`. */ - final InterpolatedExpression getInterpolation(int i) { - swift_raw_str_interpolation_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `start`. */ - final RawStrInterpolationStart getStart() { swift_raw_str_interpolation_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_raw_str_interpolation_interpolation(this, _, result) or - swift_raw_str_interpolation_def(this, result) - } - } - - /** A class representing `raw_str_interpolation_start` tokens. */ - class RawStrInterpolationStart extends @swift_token_raw_str_interpolation_start, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrInterpolationStart" } - } - - /** A class representing `raw_str_part` tokens. */ - class RawStrPart extends @swift_token_raw_str_part, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStrPart" } - } - - /** A class representing `raw_string_literal` nodes. */ - class RawStringLiteral extends @swift_raw_string_literal, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RawStringLiteral" } - - /** Gets the node corresponding to the field `continuing`. */ - final RawStrContinuingIndicator getContinuing(int i) { - swift_raw_string_literal_continuing(this, i, result) - } - - /** Gets the node corresponding to the field `interpolation`. */ - final RawStrInterpolation getInterpolation(int i) { - swift_raw_string_literal_interpolation(this, i, result) - } - - /** Gets the node corresponding to the field `text`. */ - final AstNode getText(int i) { swift_raw_string_literal_text(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_raw_string_literal_continuing(this, _, result) or - swift_raw_string_literal_interpolation(this, _, result) or - swift_raw_string_literal_text(this, _, result) - } - } - - /** A class representing `real_literal` tokens. */ - class RealLiteral extends @swift_token_real_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RealLiteral" } - } - - /** A class representing `referenceable_operator` nodes. */ - class ReferenceableOperator extends @swift_referenceable_operator, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ReferenceableOperator" } - - /** Gets the node corresponding to the field `operator`. */ - final AstNode getOperator() { swift_referenceable_operator_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_referenceable_operator_def(this, result) } - } - - /** A class representing `regex_literal` tokens. */ - class RegexLiteral extends @swift_token_regex_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RegexLiteral" } - } - - /** A class representing `repeat_while_statement` nodes. */ - class RepeatWhileStatement extends @swift_repeat_while_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "RepeatWhileStatement" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_repeat_while_statement_def(this, result) } + final override string getAPrimaryQlClass() { result = "SequenceCondition" } /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { - swift_repeat_while_statement_condition(this, i, result) - } + final Condition getCondition() { unified_sequence_condition_def(this, result) } + + /** Gets the node corresponding to the field `stmt`. */ + final Stmt getStmt(int i) { unified_sequence_condition_stmt(this, i, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_repeat_while_statement_def(this, result) or - swift_repeat_while_statement_condition(this, _, result) + unified_sequence_condition_def(this, result) or + unified_sequence_condition_stmt(this, _, result) } } - /** A class representing `selector_expression` nodes. */ - class SelectorExpression extends @swift_selector_expression, AstNode { + class Stmt extends @unified_stmt, AstNode { } + + /** A class representing `string_literal` tokens. */ + class StringLiteral extends @unified_token_string_literal, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SelectorExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_selector_expression_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_selector_expression_def(this, result) } + final override string getAPrimaryQlClass() { result = "StringLiteral" } } - /** A class representing `self_expression` tokens. */ - class SelfExpression extends @swift_token_self_expression, Token { + /** A class representing `top_level` nodes. */ + class TopLevel extends @unified_top_level, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SelfExpression" } - } - - /** A class representing `setter_specifier` nodes. */ - class SetterSpecifier extends @swift_setter_specifier, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SetterSpecifier" } - - /** Gets the node corresponding to the field `mutation`. */ - final MutationModifier getMutation() { swift_setter_specifier_mutation(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_setter_specifier_mutation(this, result) } - } - - /** A class representing `shebang_line` tokens. */ - class ShebangLine extends @swift_token_shebang_line, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ShebangLine" } - } - - /** A class representing `simple_identifier` tokens. */ - class SimpleIdentifier extends @swift_token_simple_identifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SimpleIdentifier" } - } - - /** A class representing `simple_user_type` nodes. */ - class SimpleUserType extends @swift_simple_user_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SimpleUserType" } - - /** Gets the node corresponding to the field `arguments`. */ - final TypeArguments getArguments() { swift_simple_user_type_arguments(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_simple_user_type_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_simple_user_type_arguments(this, result) or swift_simple_user_type_def(this, result) - } - } - - /** A class representing `source_file` nodes. */ - class SourceFile extends @swift_source_file, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SourceFile" } - - /** Gets the node corresponding to the field `shebang`. */ - final ShebangLine getShebang() { swift_source_file_shebang(this, result) } - - /** Gets the node corresponding to the field `statement`. */ - final AstNode getStatement(int i) { swift_source_file_statement(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_source_file_shebang(this, result) or swift_source_file_statement(this, _, result) - } - } - - /** A class representing `special_literal` tokens. */ - class SpecialLiteral extends @swift_token_special_literal, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SpecialLiteral" } - } - - /** A class representing `statement_label` tokens. */ - class StatementLabel extends @swift_token_statement_label, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "StatementLabel" } - } - - /** A class representing `str_escaped_char` tokens. */ - class StrEscapedChar extends @swift_token_str_escaped_char, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "StrEscapedChar" } - } - - /** A class representing `subscript_declaration` nodes. */ - class SubscriptDeclaration extends @swift_subscript_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SubscriptDeclaration" } + final override string getAPrimaryQlClass() { result = "TopLevel" } /** Gets the node corresponding to the field `body`. */ - final ComputedProperty getBody() { swift_subscript_declaration_def(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_subscript_declaration_modifiers(this, result) } - - /** Gets the node corresponding to the field `parameter`. */ - final FunctionParameter getParameter(int i) { - swift_subscript_declaration_parameter(this, i, result) - } - - /** Gets the node corresponding to the field `return_type`. */ - final AstNode getReturnType() { swift_subscript_declaration_return_type(this, result) } - - /** Gets the node corresponding to the field `type_constraints`. */ - final TypeConstraints getTypeConstraints() { - swift_subscript_declaration_type_constraints(this, result) - } - - /** Gets the node corresponding to the field `type_parameters`. */ - final TypeParameters getTypeParameters() { - swift_subscript_declaration_type_parameters(this, result) - } + final AstNode getBody(int i) { unified_top_level_body(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_subscript_declaration_def(this, result) or - swift_subscript_declaration_modifiers(this, result) or - swift_subscript_declaration_parameter(this, _, result) or - swift_subscript_declaration_return_type(this, result) or - swift_subscript_declaration_type_constraints(this, result) or - swift_subscript_declaration_type_parameters(this, result) - } - } - - /** A class representing `super_expression` tokens. */ - class SuperExpression extends @swift_token_super_expression, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SuperExpression" } - } - - /** A class representing `suppressed_constraint` nodes. */ - class SuppressedConstraint extends @swift_suppressed_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SuppressedConstraint" } - - /** Gets the node corresponding to the field `suppressed`. */ - final TypeIdentifier getSuppressed() { swift_suppressed_constraint_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_suppressed_constraint_def(this, result) } - } - - /** A class representing `switch_entry` nodes. */ - class SwitchEntry extends @swift_switch_entry, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SwitchEntry" } - - /** Gets the node corresponding to the field `default`. */ - final DefaultKeyword getDefault() { swift_switch_entry_default(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_switch_entry_modifiers(this, result) } - - /** Gets the node corresponding to the field `pattern`. */ - final SwitchPattern getPattern(int i) { swift_switch_entry_pattern(this, i, result) } - - /** Gets the node corresponding to the field `statement`. */ - final AstNode getStatement(int i) { swift_switch_entry_statement(this, i, result) } - - /** Gets the node corresponding to the field `where`. */ - final WhereClause getWhere() { swift_switch_entry_where(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_switch_entry_default(this, result) or - swift_switch_entry_modifiers(this, result) or - swift_switch_entry_pattern(this, _, result) or - swift_switch_entry_statement(this, _, result) or - swift_switch_entry_where(this, result) - } - } - - /** A class representing `switch_pattern` nodes. */ - class SwitchPattern extends @swift_switch_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SwitchPattern" } - - /** Gets the node corresponding to the field `pattern`. */ - final Pattern getPattern() { swift_switch_pattern_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_switch_pattern_def(this, result) } - } - - /** A class representing `switch_statement` nodes. */ - class SwitchStatement extends @swift_switch_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "SwitchStatement" } - - /** Gets the node corresponding to the field `entry`. */ - final SwitchEntry getEntry(int i) { swift_switch_statement_entry(this, i, result) } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_switch_statement_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_switch_statement_entry(this, _, result) or swift_switch_statement_def(this, result) - } - } - - /** A class representing `ternary_expression` nodes. */ - class TernaryExpression extends @swift_ternary_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TernaryExpression" } - - /** Gets the node corresponding to the field `condition`. */ - final Expression getCondition() { swift_ternary_expression_def(this, result, _, _) } - - /** Gets the node corresponding to the field `if_false`. */ - final Expression getIfFalse() { swift_ternary_expression_def(this, _, result, _) } - - /** Gets the node corresponding to the field `if_true`. */ - final Expression getIfTrue() { swift_ternary_expression_def(this, _, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_ternary_expression_def(this, result, _, _) or - swift_ternary_expression_def(this, _, result, _) or - swift_ternary_expression_def(this, _, _, result) - } - } - - /** A class representing `throw_keyword` tokens. */ - class ThrowKeyword extends @swift_token_throw_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ThrowKeyword" } - } - - /** A class representing `throws` tokens. */ - class Throws extends @swift_token_throws, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Throws" } - } - - /** A class representing `throws_clause` nodes. */ - class ThrowsClause extends @swift_throws_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ThrowsClause" } - - /** Gets the node corresponding to the field `type`. */ - final UnannotatedType getType() { swift_throws_clause_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_throws_clause_def(this, result) } - } - - /** A class representing `try_expression` nodes. */ - class TryExpression extends @swift_try_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TryExpression" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_try_expression_def(this, result, _) } - - /** Gets the node corresponding to the field `operator`. */ - final TryOperator getOperator() { swift_try_expression_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_try_expression_def(this, result, _) or swift_try_expression_def(this, _, result) - } - } - - /** A class representing `try_operator` tokens. */ - class TryOperator extends @swift_token_try_operator, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TryOperator" } - } - - /** A class representing `tuple_expression` nodes. */ - class TupleExpression extends @swift_tuple_expression, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleExpression" } - - /** Gets the node corresponding to the field `element`. */ - final TupleExpressionItem getElement(int i) { swift_tuple_expression_element(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_tuple_expression_element(this, _, result) } - } - - /** A class representing `tuple_expression_item` nodes. */ - class TupleExpressionItem extends @swift_tuple_expression_item, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleExpressionItem" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_tuple_expression_item_name(this, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_tuple_expression_item_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_tuple_expression_item_name(this, result) or - swift_tuple_expression_item_def(this, result) - } + final override AstNode getAFieldOrChild() { unified_top_level_body(this, _, result) } } /** A class representing `tuple_pattern` nodes. */ - class TuplePattern extends @swift_tuple_pattern, AstNode { + class TuplePattern extends @unified_tuple_pattern, AstNode { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "TuplePattern" } - /** Gets the node corresponding to the field `item`. */ - final TuplePatternItem getItem(int i) { swift_tuple_pattern_item(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_tuple_pattern_item(this, _, result) } - } - - /** A class representing `tuple_pattern_item` nodes. */ - class TuplePatternItem extends @swift_tuple_pattern_item, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TuplePatternItem" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_tuple_pattern_item_name(this, result) } - - /** Gets the node corresponding to the field `pattern`. */ - final Pattern getPattern() { swift_tuple_pattern_item_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_tuple_pattern_item_name(this, result) or swift_tuple_pattern_item_def(this, result) - } - } - - /** A class representing `tuple_type` nodes. */ - class TupleType extends @swift_tuple_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleType" } - /** Gets the node corresponding to the field `element`. */ - final TupleTypeItem getElement(int i) { swift_tuple_type_element(this, i, result) } + final Pattern getElement(int i) { unified_tuple_pattern_element(this, i, result) } /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_tuple_type_element(this, _, result) } + final override AstNode getAFieldOrChild() { unified_tuple_pattern_element(this, _, result) } } - /** A class representing `tuple_type_item` nodes. */ - class TupleTypeItem extends @swift_tuple_type_item, AstNode { + /** A class representing `unary_expr` nodes. */ + class UnaryExpr extends @unified_unary_expr, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TupleTypeItem" } + final override string getAPrimaryQlClass() { result = "UnaryExpr" } - /** Gets the node corresponding to the field `external_name`. */ - final WildcardPattern getExternalName() { swift_tuple_type_item_external_name(this, result) } + /** Gets the node corresponding to the field `operand`. */ + final Expr getOperand() { unified_unary_expr_def(this, result, _) } - /** Gets the node corresponding to the field `modifiers`. */ - final ParameterModifiers getModifiers() { swift_tuple_type_item_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_tuple_type_item_name(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_tuple_type_item_def(this, result) } + /** Gets the node corresponding to the field `operator`. */ + final Operator getOperator() { unified_unary_expr_def(this, _, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_tuple_type_item_external_name(this, result) or - swift_tuple_type_item_modifiers(this, result) or - swift_tuple_type_item_name(this, result) or - swift_tuple_type_item_def(this, result) + unified_unary_expr_def(this, result, _) or unified_unary_expr_def(this, _, result) } } - /** A class representing `type` nodes. */ - class Type extends @swift_type__, AstNode { + /** A class representing `unsupported_node` tokens. */ + class UnsupportedNode extends @unified_token_unsupported_node, Token { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "Type" } + final override string getAPrimaryQlClass() { result = "UnsupportedNode" } + } - /** Gets the node corresponding to the field `modifiers`. */ - final TypeModifiers getModifiers() { swift_type_modifiers(this, result) } + /** A class representing `var_pattern` nodes. */ + class VarPattern extends @unified_var_pattern, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "VarPattern" } - /** Gets the node corresponding to the field `name`. */ - final UnannotatedType getName() { swift_type_def(this, result) } + /** Gets the node corresponding to the field `identifier`. */ + final Identifier getIdentifier() { unified_var_pattern_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { unified_var_pattern_def(this, result) } + } + + /** A class representing `variable_declaration_stmt` nodes. */ + class VariableDeclarationStmt extends @unified_variable_declaration_stmt, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "VariableDeclarationStmt" } + + /** Gets the node corresponding to the field `variable_declarator`. */ + final VariableDeclarator getVariableDeclarator(int i) { + unified_variable_declaration_stmt_variable_declarator(this, i, result) + } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_type_modifiers(this, result) or swift_type_def(this, result) + unified_variable_declaration_stmt_variable_declarator(this, _, result) } } - /** A class representing `type_annotation` nodes. */ - class TypeAnnotation extends @swift_type_annotation, AstNode { + /** A class representing `variable_declarator` nodes. */ + class VariableDeclarator extends @unified_variable_declarator, AstNode { /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeAnnotation" } - - /** Gets the node corresponding to the field `type`. */ - final AstNode getType() { swift_type_annotation_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_annotation_def(this, result) } - } - - /** A class representing `type_arguments` nodes. */ - class TypeArguments extends @swift_type_arguments, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeArguments" } - - /** Gets the node corresponding to the field `argument`. */ - final Type getArgument(int i) { swift_type_arguments_argument(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_arguments_argument(this, _, result) } - } - - /** A class representing `type_casting_pattern` nodes. */ - class TypeCastingPattern extends @swift_type_casting_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeCastingPattern" } + final override string getAPrimaryQlClass() { result = "VariableDeclarator" } /** Gets the node corresponding to the field `pattern`. */ - final Pattern getPattern() { swift_type_casting_pattern_pattern(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_type_casting_pattern_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_type_casting_pattern_pattern(this, result) or - swift_type_casting_pattern_def(this, result) - } - } - - /** A class representing `type_constraint` nodes. */ - class TypeConstraint extends @swift_type_constraint, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeConstraint" } - - /** Gets the node corresponding to the field `constraint`. */ - final AstNode getConstraint() { swift_type_constraint_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_constraint_def(this, result) } - } - - /** A class representing `type_constraints` nodes. */ - class TypeConstraints extends @swift_type_constraints, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeConstraints" } - - /** Gets the node corresponding to the field `constraint`. */ - final TypeConstraint getConstraint(int i) { swift_type_constraints_constraint(this, i, result) } - - /** Gets the node corresponding to the field `keyword`. */ - final WhereKeyword getKeyword() { swift_type_constraints_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_type_constraints_constraint(this, _, result) or swift_type_constraints_def(this, result) - } - } - - /** A class representing `type_identifier` tokens. */ - class TypeIdentifier extends @swift_token_type_identifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeIdentifier" } - } - - class TypeLevelDeclaration extends @swift_type_level_declaration, AstNode { } - - /** A class representing `type_modifiers` nodes. */ - class TypeModifiers extends @swift_type_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeModifiers" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { swift_type_modifiers_attribute(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_modifiers_attribute(this, _, result) } - } - - /** A class representing `type_pack_expansion` nodes. */ - class TypePackExpansion extends @swift_type_pack_expansion, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypePackExpansion" } - - /** Gets the node corresponding to the field `name`. */ - final UnannotatedType getName() { swift_type_pack_expansion_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_pack_expansion_def(this, result) } - } - - /** A class representing `type_parameter` nodes. */ - class TypeParameter extends @swift_type_parameter, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameter" } - - /** Gets the node corresponding to the field `modifiers`. */ - final TypeParameterModifiers getModifiers() { swift_type_parameter_modifiers(this, result) } - - /** Gets the node corresponding to the field `name`. */ - final AstNode getName() { swift_type_parameter_def(this, result) } - - /** Gets the node corresponding to the field `type`. */ - final Type getType() { swift_type_parameter_type(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_type_parameter_modifiers(this, result) or - swift_type_parameter_def(this, result) or - swift_type_parameter_type(this, result) - } - } - - /** A class representing `type_parameter_modifiers` nodes. */ - class TypeParameterModifiers extends @swift_type_parameter_modifiers, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameterModifiers" } - - /** Gets the node corresponding to the field `attribute`. */ - final Attribute getAttribute(int i) { - swift_type_parameter_modifiers_attribute(this, i, result) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_type_parameter_modifiers_attribute(this, _, result) - } - } - - /** A class representing `type_parameter_pack` nodes. */ - class TypeParameterPack extends @swift_type_parameter_pack, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameterPack" } - - /** Gets the node corresponding to the field `name`. */ - final UnannotatedType getName() { swift_type_parameter_pack_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_type_parameter_pack_def(this, result) } - } - - /** A class representing `type_parameters` nodes. */ - class TypeParameters extends @swift_type_parameters, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypeParameters" } - - /** Gets the node corresponding to the field `constraints`. */ - final TypeConstraints getConstraints() { swift_type_parameters_constraints(this, result) } - - /** Gets the node corresponding to the field `parameter`. */ - final TypeParameter getParameter(int i) { swift_type_parameters_parameter(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_type_parameters_constraints(this, result) or - swift_type_parameters_parameter(this, _, result) - } - } - - /** A class representing `typealias_declaration` nodes. */ - class TypealiasDeclaration extends @swift_typealias_declaration, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "TypealiasDeclaration" } - - /** Gets the node corresponding to the field `modifiers`. */ - final AstNode getModifiers(int i) { swift_typealias_declaration_modifiers(this, i, result) } - - /** Gets the node corresponding to the field `name`. */ - final TypeIdentifier getName() { swift_typealias_declaration_def(this, result, _) } - - /** Gets the node corresponding to the field `type_parameters`. */ - final TypeParameters getTypeParameters() { - swift_typealias_declaration_type_parameters(this, result) - } + final Pattern getPattern() { unified_variable_declarator_def(this, result) } /** Gets the node corresponding to the field `value`. */ - final Type getValue() { swift_typealias_declaration_def(this, _, result) } + final Expr getValue() { unified_variable_declarator_value(this, result) } /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - swift_typealias_declaration_modifiers(this, _, result) or - swift_typealias_declaration_def(this, result, _) or - swift_typealias_declaration_type_parameters(this, result) or - swift_typealias_declaration_def(this, _, result) - } - } - - class UnannotatedType extends @swift_unannotated_type, AstNode { } - - /** A class representing `user_type` nodes. */ - class UserType extends @swift_user_type, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "UserType" } - - /** Gets the node corresponding to the field `part`. */ - final SimpleUserType getPart(int i) { swift_user_type_part(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_user_type_part(this, _, result) } - } - - /** A class representing `value_argument` nodes. */ - class ValueArgument extends @swift_value_argument, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueArgument" } - - /** Gets the node corresponding to the field `name`. */ - final ValueArgumentLabel getName() { swift_value_argument_name(this, result) } - - /** Gets the node corresponding to the field `reference_specifier`. */ - final ValueArgumentLabel getReferenceSpecifier(int i) { - swift_value_argument_reference_specifier(this, i, result) - } - - /** Gets the node corresponding to the field `type_modifiers`. */ - final TypeModifiers getTypeModifiers() { swift_value_argument_type_modifiers(this, result) } - - /** Gets the node corresponding to the field `value`. */ - final Expression getValue() { swift_value_argument_value(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_value_argument_name(this, result) or - swift_value_argument_reference_specifier(this, _, result) or - swift_value_argument_type_modifiers(this, result) or - swift_value_argument_value(this, result) - } - } - - /** A class representing `value_argument_label` nodes. */ - class ValueArgumentLabel extends @swift_value_argument_label, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueArgumentLabel" } - - /** Gets the node corresponding to the field `name`. */ - final SimpleIdentifier getName() { swift_value_argument_label_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_argument_label_def(this, result) } - } - - /** A class representing `value_arguments` nodes. */ - class ValueArguments extends @swift_value_arguments, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueArguments" } - - /** Gets the node corresponding to the field `argument`. */ - final ValueArgument getArgument(int i) { swift_value_arguments_argument(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_arguments_argument(this, _, result) } - } - - /** A class representing `value_binding_pattern` nodes. */ - class ValueBindingPattern extends @swift_value_binding_pattern, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueBindingPattern" } - - /** Gets the node corresponding to the field `mutability`. */ - final string getMutability() { - exists(int value | swift_value_binding_pattern_def(this, value) | - result = "let" and value = 0 - or - result = "var" and value = 1 - ) - } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { none() } - } - - /** A class representing `value_pack_expansion` nodes. */ - class ValuePackExpansion extends @swift_value_pack_expansion, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValuePackExpansion" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_value_pack_expansion_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_pack_expansion_def(this, result) } - } - - /** A class representing `value_parameter_pack` nodes. */ - class ValueParameterPack extends @swift_value_parameter_pack, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "ValueParameterPack" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_value_parameter_pack_def(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { swift_value_parameter_pack_def(this, result) } - } - - /** A class representing `visibility_modifier` tokens. */ - class VisibilityModifier extends @swift_token_visibility_modifier, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "VisibilityModifier" } - } - - /** A class representing `where_clause` nodes. */ - class WhereClause extends @swift_where_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WhereClause" } - - /** Gets the node corresponding to the field `expr`. */ - final Expression getExpr() { swift_where_clause_def(this, result, _) } - - /** Gets the node corresponding to the field `keyword`. */ - final WhereKeyword getKeyword() { swift_where_clause_def(this, _, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_where_clause_def(this, result, _) or swift_where_clause_def(this, _, result) - } - } - - /** A class representing `where_keyword` tokens. */ - class WhereKeyword extends @swift_token_where_keyword, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WhereKeyword" } - } - - /** A class representing `while_statement` nodes. */ - class WhileStatement extends @swift_while_statement, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WhileStatement" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_while_statement_def(this, result) } - - /** Gets the node corresponding to the field `condition`. */ - final IfCondition getCondition(int i) { swift_while_statement_condition(this, i, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_while_statement_def(this, result) or swift_while_statement_condition(this, _, result) - } - } - - /** A class representing `wildcard_pattern` tokens. */ - class WildcardPattern extends @swift_token_wildcard_pattern, Token { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WildcardPattern" } - } - - /** A class representing `willset_clause` nodes. */ - class WillsetClause extends @swift_willset_clause, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WillsetClause" } - - /** Gets the node corresponding to the field `body`. */ - final Block getBody() { swift_willset_clause_def(this, result) } - - /** Gets the node corresponding to the field `modifiers`. */ - final Modifiers getModifiers() { swift_willset_clause_modifiers(this, result) } - - /** Gets the node corresponding to the field `parameter`. */ - final SimpleIdentifier getParameter() { swift_willset_clause_parameter(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_willset_clause_def(this, result) or - swift_willset_clause_modifiers(this, result) or - swift_willset_clause_parameter(this, result) - } - } - - /** A class representing `willset_didset_block` nodes. */ - class WillsetDidsetBlock extends @swift_willset_didset_block, AstNode { - /** Gets the name of the primary QL class for this element. */ - final override string getAPrimaryQlClass() { result = "WillsetDidsetBlock" } - - /** Gets the node corresponding to the field `didset`. */ - final DidsetClause getDidset() { swift_willset_didset_block_didset(this, result) } - - /** Gets the node corresponding to the field `willset`. */ - final WillsetClause getWillset() { swift_willset_didset_block_willset(this, result) } - - /** Gets a field or child node of this node. */ - final override AstNode getAFieldOrChild() { - swift_willset_didset_block_didset(this, result) or - swift_willset_didset_block_willset(this, result) + unified_variable_declarator_def(this, result) or + unified_variable_declarator_value(this, result) } } } diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme index 5cf748c1571..28718d79423 100644 --- a/unified/ql/lib/unified.dbscheme +++ b/unified/ql/lib/unified.dbscheme @@ -1,4 +1,4 @@ -// CodeQL database schema for Swift +// CodeQL database schema for Unified // Automatically generated from the tree-sitter grammar; do not edit // To regenerate, run unified/scripts/create-extractor-pack.sh @@ -131,2391 +131,220 @@ overlayChangedFiles( string path: string ref ); -/*- Swift dbscheme -*/ -case @swift_additive_expression.op of - 0 = @swift_additive_expression_plus -| 1 = @swift_additive_expression_minus -; - - -swift_additive_expression_def( - unique int id: @swift_additive_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -#keyset[swift_array_literal, index] -swift_array_literal_element( - int swift_array_literal: @swift_array_literal ref, - int index: int ref, - unique int element: @swift_expression ref -); - -swift_array_literal_def( - unique int id: @swift_array_literal -); - -swift_array_type_def( - unique int id: @swift_array_type, - int element: @swift_type__ ref -); - -swift_as_expression_def( - unique int id: @swift_as_expression, - int expr: @swift_expression ref, - int operator: @swift_token_as_operator ref, - int type__: @swift_type__ ref -); - -case @swift_assignment.operator of - 0 = @swift_assignment_percentequal -| 1 = @swift_assignment_starequal -| 2 = @swift_assignment_plusequal -| 3 = @swift_assignment_minusequal -| 4 = @swift_assignment_slashequal -| 5 = @swift_assignment_equal -; - - -swift_assignment_def( - unique int id: @swift_assignment, - int operator: int ref, - int result: @swift_expression ref, - int target: @swift_directly_assignable_expression ref -); - -swift_associatedtype_declaration_default_value( - unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - unique int default_value: @swift_type__ ref -); - -swift_associatedtype_declaration_modifiers( - unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - unique int modifiers: @swift_modifiers ref -); - -swift_associatedtype_declaration_must_inherit( - unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - unique int must_inherit: @swift_type__ ref -); - -swift_associatedtype_declaration_type_constraints( - unique int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_associatedtype_declaration_def( - unique int id: @swift_associatedtype_declaration, - int name: @swift_token_type_identifier ref -); - -#keyset[swift_attribute, index] -swift_attribute_argument( - int swift_attribute: @swift_attribute ref, - int index: int ref, - unique int argument: @swift_expression ref -); - -#keyset[swift_attribute, index] -swift_attribute_argument_name( - int swift_attribute: @swift_attribute ref, - int index: int ref, - unique int argument_name: @swift_token_simple_identifier ref -); - -#keyset[swift_attribute, index] -swift_attribute_param_ref( - int swift_attribute: @swift_attribute ref, - int index: int ref, - unique int param_ref: @swift_token_simple_identifier ref -); - -#keyset[swift_attribute, index] -swift_attribute_platform( - int swift_attribute: @swift_attribute ref, - int index: int ref, - unique int platform: @swift_token_simple_identifier ref -); - -#keyset[swift_attribute, index] -swift_attribute_version( - int swift_attribute: @swift_attribute ref, - int index: int ref, - unique int version: @swift_token_integer_literal ref -); - -swift_attribute_def( - unique int id: @swift_attribute, - int name: @swift_user_type ref -); - -#keyset[swift_availability_condition, index] -swift_availability_condition_platform( - int swift_availability_condition: @swift_availability_condition ref, - int index: int ref, - unique int platform: @swift_identifier ref -); - -#keyset[swift_availability_condition, index] -swift_availability_condition_version( - int swift_availability_condition: @swift_availability_condition ref, - int index: int ref, - unique int version: @swift_token_integer_literal ref -); - -swift_availability_condition_def( - unique int id: @swift_availability_condition -); - -swift_await_expression_def( - unique int id: @swift_await_expression, - int expr: @swift_expression ref -); - -swift_binding_pattern_def( - unique int id: @swift_binding_pattern, - int binding: @swift_value_binding_pattern ref, - int pattern: @swift_pattern ref -); - -case @swift_bitwise_operation.op of - 0 = @swift_bitwise_operation_ampersand -| 1 = @swift_bitwise_operation_langlelangle -| 2 = @swift_bitwise_operation_ranglerangle -| 3 = @swift_bitwise_operation_caret -| 4 = @swift_bitwise_operation_pipe -; - - -swift_bitwise_operation_def( - unique int id: @swift_bitwise_operation, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_block_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement - -#keyset[swift_block, index] -swift_block_statement( - int swift_block: @swift_block ref, - int index: int ref, - unique int statement: @swift_block_statement_type ref -); - -swift_block_def( - unique int id: @swift_block -); - -swift_call_expression_def( - unique int id: @swift_call_expression, - int function: @swift_expression ref, - int suffix: @swift_call_suffix ref -); - -swift_call_suffix_arguments( - unique int swift_call_suffix: @swift_call_suffix ref, - unique int arguments: @swift_value_arguments ref -); - -#keyset[swift_call_suffix, index] -swift_call_suffix_lambda( - int swift_call_suffix: @swift_call_suffix ref, - int index: int ref, - unique int lambda: @swift_lambda_literal ref -); - -#keyset[swift_call_suffix, index] -swift_call_suffix_name( - int swift_call_suffix: @swift_call_suffix ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -swift_call_suffix_def( - unique int id: @swift_call_suffix -); - -#keyset[swift_capture_list, index] -swift_capture_list_item( - int swift_capture_list: @swift_capture_list ref, - int index: int ref, - unique int item: @swift_capture_list_item ref -); - -swift_capture_list_def( - unique int id: @swift_capture_list -); - -@swift_capture_list_item_name_type = @swift_token_self_expression | @swift_token_simple_identifier - -swift_capture_list_item_ownership( - unique int swift_capture_list_item: @swift_capture_list_item ref, - unique int ownership: @swift_token_ownership_modifier ref -); - -swift_capture_list_item_value( - unique int swift_capture_list_item: @swift_capture_list_item ref, - unique int value: @swift_expression ref -); - -swift_capture_list_item_def( - unique int id: @swift_capture_list_item, - int name: @swift_capture_list_item_name_type ref -); - -swift_case_pattern_arguments( - unique int swift_case_pattern: @swift_case_pattern ref, - unique int arguments: @swift_tuple_pattern ref -); - -swift_case_pattern_type( - unique int swift_case_pattern: @swift_case_pattern ref, - unique int type__: @swift_user_type ref -); - -swift_case_pattern_def( - unique int id: @swift_case_pattern, - int name: @swift_token_simple_identifier ref -); - -swift_catch_block_error( - unique int swift_catch_block: @swift_catch_block ref, - unique int error: @swift_pattern ref -); - -swift_catch_block_where( - unique int swift_catch_block: @swift_catch_block ref, - unique int where: @swift_where_clause ref -); - -swift_catch_block_def( - unique int id: @swift_catch_block, - int body: @swift_block ref, - int keyword: @swift_token_catch_keyword ref -); - -case @swift_check_expression.op of - 0 = @swift_check_expression_is -; - - -swift_check_expression_def( - unique int id: @swift_check_expression, - int op: int ref, - int target: @swift_expression ref, - int type__: @swift_type__ ref -); - -#keyset[swift_class_body, index] -swift_class_body_member( - int swift_class_body: @swift_class_body ref, - int index: int ref, - unique int member: @swift_type_level_declaration ref -); - -swift_class_body_def( - unique int id: @swift_class_body -); - -#keyset[swift_class_declaration, index] -swift_class_declaration_attribute( - int swift_class_declaration: @swift_class_declaration ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -@swift_class_declaration_body_type = @swift_class_body | @swift_enum_class_body - -case @swift_class_declaration.declaration_kind of - 0 = @swift_class_declaration_actor -| 1 = @swift_class_declaration_class -| 2 = @swift_class_declaration_enum -| 3 = @swift_class_declaration_extension -| 4 = @swift_class_declaration_struct -; - - -#keyset[swift_class_declaration, index] -swift_class_declaration_inherits( - int swift_class_declaration: @swift_class_declaration ref, - int index: int ref, - unique int inherits: @swift_inheritance_specifier ref -); - -@swift_class_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier - -#keyset[swift_class_declaration, index] -swift_class_declaration_modifiers( - int swift_class_declaration: @swift_class_declaration ref, - int index: int ref, - unique int modifiers: @swift_class_declaration_modifiers_type ref -); - -@swift_class_declaration_name_type = @swift_token_type_identifier | @swift_unannotated_type - -swift_class_declaration_type_constraints( - unique int swift_class_declaration: @swift_class_declaration ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_class_declaration_type_parameters( - unique int swift_class_declaration: @swift_class_declaration ref, - unique int type_parameters: @swift_type_parameters ref -); - -swift_class_declaration_def( - unique int id: @swift_class_declaration, - int body: @swift_class_declaration_body_type ref, - int declaration_kind: int ref, - int name: @swift_class_declaration_name_type ref -); - -case @swift_comparison_expression.op of - 0 = @swift_comparison_expression_langle -| 1 = @swift_comparison_expression_langleequal -| 2 = @swift_comparison_expression_rangle -| 3 = @swift_comparison_expression_rangleequal -; - - -swift_comparison_expression_def( - unique int id: @swift_comparison_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -swift_compilation_condition_inner( - unique int swift_compilation_condition: @swift_compilation_condition ref, - unique int inner: @swift_compilation_condition ref -); - -swift_compilation_condition_lhs( - unique int swift_compilation_condition: @swift_compilation_condition ref, - unique int lhs: @swift_compilation_condition ref -); - -#keyset[swift_compilation_condition, index] -swift_compilation_condition_name( - int swift_compilation_condition: @swift_compilation_condition ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -swift_compilation_condition_operand( - unique int swift_compilation_condition: @swift_compilation_condition ref, - unique int operand: @swift_compilation_condition ref -); - -swift_compilation_condition_rhs( - unique int swift_compilation_condition: @swift_compilation_condition ref, - unique int rhs: @swift_compilation_condition ref -); - -swift_compilation_condition_value( - unique int swift_compilation_condition: @swift_compilation_condition ref, - unique int value: @swift_token_boolean_literal ref -); - -#keyset[swift_compilation_condition, index] -swift_compilation_condition_version( - int swift_compilation_condition: @swift_compilation_condition ref, - int index: int ref, - unique int version: @swift_token_integer_literal ref -); - -swift_compilation_condition_def( - unique int id: @swift_compilation_condition -); - -#keyset[swift_computed_getter, index] -swift_computed_getter_attribute( - int swift_computed_getter: @swift_computed_getter ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -swift_computed_getter_body( - unique int swift_computed_getter: @swift_computed_getter ref, - unique int body: @swift_block ref -); - -swift_computed_getter_def( - unique int id: @swift_computed_getter, - int specifier: @swift_getter_specifier ref -); - -#keyset[swift_computed_modify, index] -swift_computed_modify_attribute( - int swift_computed_modify: @swift_computed_modify ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -swift_computed_modify_body( - unique int swift_computed_modify: @swift_computed_modify ref, - unique int body: @swift_block ref -); - -swift_computed_modify_def( - unique int id: @swift_computed_modify, - int specifier: @swift_modify_specifier ref -); - -@swift_computed_property_accessor_type = @swift_computed_getter | @swift_computed_modify | @swift_computed_setter - -#keyset[swift_computed_property, index] -swift_computed_property_accessor( - int swift_computed_property: @swift_computed_property ref, - int index: int ref, - unique int accessor: @swift_computed_property_accessor_type ref -); - -@swift_computed_property_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement - -#keyset[swift_computed_property, index] -swift_computed_property_statement( - int swift_computed_property: @swift_computed_property ref, - int index: int ref, - unique int statement: @swift_computed_property_statement_type ref -); - -swift_computed_property_def( - unique int id: @swift_computed_property -); - -#keyset[swift_computed_setter, index] -swift_computed_setter_attribute( - int swift_computed_setter: @swift_computed_setter ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -swift_computed_setter_body( - unique int swift_computed_setter: @swift_computed_setter ref, - unique int body: @swift_block ref -); - -swift_computed_setter_parameter( - unique int swift_computed_setter: @swift_computed_setter ref, - unique int parameter: @swift_token_simple_identifier ref -); - -swift_computed_setter_def( - unique int id: @swift_computed_setter, - int specifier: @swift_setter_specifier ref -); - -case @swift_conjunction_expression.op of - 0 = @swift_conjunction_expression_ampersandampersand -; - - -swift_conjunction_expression_def( - unique int id: @swift_conjunction_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_constructor_expression_constructed_type_type = @swift_array_type | @swift_dictionary_type | @swift_user_type - -swift_constructor_expression_def( - unique int id: @swift_constructor_expression, - int constructed_type: @swift_constructor_expression_constructed_type_type ref, - int suffix: @swift_constructor_suffix ref -); - -swift_constructor_suffix_arguments( - unique int swift_constructor_suffix: @swift_constructor_suffix ref, - unique int arguments: @swift_value_arguments ref -); - -#keyset[swift_constructor_suffix, index] -swift_constructor_suffix_lambda( - int swift_constructor_suffix: @swift_constructor_suffix ref, - int index: int ref, - unique int lambda: @swift_lambda_literal ref -); - -#keyset[swift_constructor_suffix, index] -swift_constructor_suffix_name( - int swift_constructor_suffix: @swift_constructor_suffix ref, - int index: int ref, - unique int name: @swift_token_simple_identifier ref -); - -swift_constructor_suffix_def( - unique int id: @swift_constructor_suffix -); - -@swift_control_transfer_statement_kind_type = @swift_reserved_word | @swift_token_throw_keyword - -swift_control_transfer_statement_result( - unique int swift_control_transfer_statement: @swift_control_transfer_statement ref, - unique int result: @swift_expression ref -); - -swift_control_transfer_statement_def( - unique int id: @swift_control_transfer_statement, - int kind: @swift_control_transfer_statement_kind_type ref -); - -swift_deinit_declaration_modifiers( - unique int swift_deinit_declaration: @swift_deinit_declaration ref, - unique int modifiers: @swift_modifiers ref -); - -swift_deinit_declaration_def( - unique int id: @swift_deinit_declaration, - int body: @swift_block ref -); - -@swift_deprecated_operator_declaration_body_entry_type = @swift_line_string_literal | @swift_multi_line_string_literal | @swift_raw_string_literal | @swift_reserved_word | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_simple_identifier - -#keyset[swift_deprecated_operator_declaration_body, index] -swift_deprecated_operator_declaration_body_entry( - int swift_deprecated_operator_declaration_body: @swift_deprecated_operator_declaration_body ref, - int index: int ref, - unique int entry: @swift_deprecated_operator_declaration_body_entry_type ref -); - -swift_deprecated_operator_declaration_body_def( - unique int id: @swift_deprecated_operator_declaration_body -); - -#keyset[swift_dictionary_literal, index] -swift_dictionary_literal_element( - int swift_dictionary_literal: @swift_dictionary_literal ref, - int index: int ref, - unique int element: @swift_dictionary_literal_item ref -); - -swift_dictionary_literal_def( - unique int id: @swift_dictionary_literal -); - -swift_dictionary_literal_item_def( - unique int id: @swift_dictionary_literal_item, - int key__: @swift_expression ref, - int value: @swift_expression ref -); - -swift_dictionary_type_def( - unique int id: @swift_dictionary_type, - int key__: @swift_type__ ref, - int value: @swift_type__ ref -); - -swift_didset_clause_modifiers( - unique int swift_didset_clause: @swift_didset_clause ref, - unique int modifiers: @swift_modifiers ref -); - -swift_didset_clause_parameter( - unique int swift_didset_clause: @swift_didset_clause ref, - unique int parameter: @swift_token_simple_identifier ref -); - -swift_didset_clause_def( - unique int id: @swift_didset_clause, - int body: @swift_block ref -); - -swift_directive_condition( - unique int swift_directive: @swift_directive ref, - unique int condition: @swift_compilation_condition ref -); - -swift_directive_def( - unique int id: @swift_directive -); - -swift_directly_assignable_expression_def( - unique int id: @swift_directly_assignable_expression, - int expr: @swift_expression ref -); - -case @swift_disjunction_expression.op of - 0 = @swift_disjunction_expression_pipepipe -; - - -swift_disjunction_expression_def( - unique int id: @swift_disjunction_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -#keyset[swift_do_statement, index] -swift_do_statement_catch( - int swift_do_statement: @swift_do_statement ref, - int index: int ref, - unique int catch: @swift_catch_block ref -); - -swift_do_statement_def( - unique int id: @swift_do_statement, - int body: @swift_block ref -); - -swift_enum_case_entry_data_contents( - unique int swift_enum_case_entry: @swift_enum_case_entry ref, - unique int data_contents: @swift_enum_type_parameters ref -); - -swift_enum_case_entry_raw_value( - unique int swift_enum_case_entry: @swift_enum_case_entry ref, - unique int raw_value: @swift_expression ref -); - -swift_enum_case_entry_def( - unique int id: @swift_enum_case_entry, - int name: @swift_token_simple_identifier ref -); - -@swift_enum_class_body_member_type = @swift_enum_entry | @swift_type_level_declaration - -#keyset[swift_enum_class_body, index] -swift_enum_class_body_member( - int swift_enum_class_body: @swift_enum_class_body ref, - int index: int ref, - unique int member: @swift_enum_class_body_member_type ref -); - -swift_enum_class_body_def( - unique int id: @swift_enum_class_body -); - -#keyset[swift_enum_entry, index] -swift_enum_entry_case( - int swift_enum_entry: @swift_enum_entry ref, - int index: int ref, - unique int case__: @swift_enum_case_entry ref -); - -swift_enum_entry_modifiers( - unique int swift_enum_entry: @swift_enum_entry ref, - unique int modifiers: @swift_modifiers ref -); - -swift_enum_entry_def( - unique int id: @swift_enum_entry -); - -swift_enum_type_parameter_default_value( - unique int swift_enum_type_parameter: @swift_enum_type_parameter ref, - unique int default_value: @swift_expression ref -); - -swift_enum_type_parameter_external_name( - unique int swift_enum_type_parameter: @swift_enum_type_parameter ref, - unique int external_name: @swift_token_wildcard_pattern ref -); - -swift_enum_type_parameter_name( - unique int swift_enum_type_parameter: @swift_enum_type_parameter ref, - unique int name: @swift_token_simple_identifier ref -); - -swift_enum_type_parameter_def( - unique int id: @swift_enum_type_parameter, - int type__: @swift_type__ ref -); - -#keyset[swift_enum_type_parameters, index] -swift_enum_type_parameters_parameter( - int swift_enum_type_parameters: @swift_enum_type_parameters ref, - int index: int ref, - unique int parameter: @swift_enum_type_parameter ref -); - -swift_enum_type_parameters_def( - unique int id: @swift_enum_type_parameters -); - -#keyset[swift_equality_constraint, index] -swift_equality_constraint_attribute( - int swift_equality_constraint: @swift_equality_constraint ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -@swift_equality_constraint_constrained_type_type = @swift_identifier | @swift_nested_type_identifier - -swift_equality_constraint_def( - unique int id: @swift_equality_constraint, - int constrained_type: @swift_equality_constraint_constrained_type_type ref, - int must_equal: @swift_type__ ref -); - -case @swift_equality_expression.op of - 0 = @swift_equality_expression_bangequal -| 1 = @swift_equality_expression_bangequalequal -| 2 = @swift_equality_expression_equalequal -| 3 = @swift_equality_expression_equalequalequal -; - - -swift_equality_expression_def( - unique int id: @swift_equality_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -swift_existential_type_def( - unique int id: @swift_existential_type, - int name: @swift_unannotated_type ref -); - -@swift_expression = @swift_additive_expression | @swift_array_literal | @swift_as_expression | @swift_assignment | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_check_expression | @swift_comparison_expression | @swift_conjunction_expression | @swift_constructor_expression | @swift_dictionary_literal | @swift_directive | @swift_disjunction_expression | @swift_equality_expression | @swift_if_statement | @swift_infix_expression | @swift_key_path_expression | @swift_key_path_string_expression | @swift_lambda_literal | @swift_line_string_literal | @swift_macro_invocation | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_nil_coalescing_expression | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_optional_chain_marker | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_referenceable_operator | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_diagnostic | @swift_token_fully_open_range | @swift_token_hex_literal | @swift_token_integer_literal | @swift_token_oct_literal | @swift_token_real_literal | @swift_token_regex_literal | @swift_token_self_expression | @swift_token_simple_identifier | @swift_token_special_literal | @swift_token_super_expression | @swift_try_expression | @swift_tuple_expression | @swift_value_pack_expansion | @swift_value_parameter_pack - -swift_external_macro_definition_def( - unique int id: @swift_external_macro_definition, - int arguments: @swift_value_arguments ref -); - -swift_for_statement_try( - unique int swift_for_statement: @swift_for_statement ref, - unique int try: @swift_token_try_operator ref -); - -swift_for_statement_type( - unique int swift_for_statement: @swift_for_statement ref, - unique int type__: @swift_type_annotation ref -); - -swift_for_statement_where( - unique int swift_for_statement: @swift_for_statement ref, - unique int where: @swift_where_clause ref -); - -swift_for_statement_def( - unique int id: @swift_for_statement, - int body: @swift_block ref, - int collection: @swift_expression ref, - int item: @swift_pattern ref -); - -swift_function_declaration_async( - unique int swift_function_declaration: @swift_function_declaration ref, - unique int async: @swift_reserved_word ref -); - -@swift_function_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier - -#keyset[swift_function_declaration, index] -swift_function_declaration_modifiers( - int swift_function_declaration: @swift_function_declaration ref, - int index: int ref, - unique int modifiers: @swift_function_declaration_modifiers_type ref -); - -@swift_function_declaration_name_type = @swift_referenceable_operator | @swift_token_simple_identifier - -#keyset[swift_function_declaration, index] -swift_function_declaration_parameter( - int swift_function_declaration: @swift_function_declaration ref, - int index: int ref, - unique int parameter: @swift_function_parameter ref -); - -@swift_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_function_declaration_return_type( - unique int swift_function_declaration: @swift_function_declaration ref, - unique int return_type: @swift_function_declaration_return_type_type ref -); - -@swift_function_declaration_throws_type = @swift_throws_clause | @swift_token_throws - -swift_function_declaration_throws( - unique int swift_function_declaration: @swift_function_declaration ref, - unique int throws: @swift_function_declaration_throws_type ref -); - -swift_function_declaration_type_constraints( - unique int swift_function_declaration: @swift_function_declaration ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_function_declaration_type_parameters( - unique int swift_function_declaration: @swift_function_declaration ref, - unique int type_parameters: @swift_type_parameters ref -); - -swift_function_declaration_def( - unique int id: @swift_function_declaration, - int body: @swift_block ref, - int name: @swift_function_declaration_name_type ref -); - -swift_function_parameter_attribute( - unique int swift_function_parameter: @swift_function_parameter ref, - unique int attribute: @swift_attribute ref -); - -swift_function_parameter_default_value( - unique int swift_function_parameter: @swift_function_parameter ref, - unique int default_value: @swift_expression ref -); - -swift_function_parameter_def( - unique int id: @swift_function_parameter, - int parameter: @swift_parameter ref -); - -swift_function_type_async( - unique int swift_function_type: @swift_function_type ref, - unique int async: @swift_reserved_word ref -); - -@swift_function_type_throws_type = @swift_throws_clause | @swift_token_throws - -swift_function_type_throws( - unique int swift_function_type: @swift_function_type ref, - unique int throws: @swift_function_type_throws_type ref -); - -swift_function_type_def( - unique int id: @swift_function_type, - int params: @swift_unannotated_type ref, - int return_type: @swift_type__ ref -); - -@swift_getter_specifier_effect_type = @swift_throws_clause | @swift_token_async_keyword | @swift_token_throws - -#keyset[swift_getter_specifier, index] -swift_getter_specifier_effect( - int swift_getter_specifier: @swift_getter_specifier ref, - int index: int ref, - unique int effect: @swift_getter_specifier_effect_type ref -); - -swift_getter_specifier_mutation( - unique int swift_getter_specifier: @swift_getter_specifier ref, - unique int mutation: @swift_token_mutation_modifier ref -); - -swift_getter_specifier_def( - unique int id: @swift_getter_specifier -); - -@swift_global_declaration = @swift_associatedtype_declaration | @swift_class_declaration | @swift_function_declaration | @swift_import_declaration | @swift_init_declaration | @swift_macro_declaration | @swift_operator_declaration | @swift_precedence_group_declaration | @swift_property_declaration | @swift_protocol_declaration | @swift_typealias_declaration - -#keyset[swift_guard_statement, index] -swift_guard_statement_condition( - int swift_guard_statement: @swift_guard_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -swift_guard_statement_def( - unique int id: @swift_guard_statement, - int body: @swift_block ref -); - -#keyset[swift_identifier, index] -swift_identifier_part( - int swift_identifier: @swift_identifier ref, - int index: int ref, - unique int part: @swift_token_simple_identifier ref -); - -swift_identifier_def( - unique int id: @swift_identifier -); - -@swift_if_condition_kind_type = @swift_availability_condition | @swift_expression | @swift_if_let_binding - -swift_if_condition_def( - unique int id: @swift_if_condition, - int kind: @swift_if_condition_kind_type ref -); - -swift_if_let_binding_type( - unique int swift_if_let_binding: @swift_if_let_binding ref, - unique int type__: @swift_type_annotation ref -); - -swift_if_let_binding_value( - unique int swift_if_let_binding: @swift_if_let_binding ref, - unique int value: @swift_expression ref -); - -swift_if_let_binding_where( - unique int swift_if_let_binding: @swift_if_let_binding ref, - unique int where: @swift_where_clause ref -); - -swift_if_let_binding_def( - unique int id: @swift_if_let_binding, - int pattern: @swift_pattern ref -); - -#keyset[swift_if_statement, index] -swift_if_statement_condition( - int swift_if_statement: @swift_if_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -@swift_if_statement_else_branch_type = @swift_block | @swift_if_statement - -swift_if_statement_else_branch( - unique int swift_if_statement: @swift_if_statement ref, - unique int else_branch: @swift_if_statement_else_branch_type ref -); - -swift_if_statement_def( - unique int id: @swift_if_statement, - int body: @swift_block ref -); - -swift_implicitly_unwrapped_type_def( - unique int id: @swift_implicitly_unwrapped_type, - int name: @swift_type__ ref -); - -swift_import_declaration_modifiers( - unique int swift_import_declaration: @swift_import_declaration ref, - unique int modifiers: @swift_modifiers ref -); - -swift_import_declaration_def( - unique int id: @swift_import_declaration, - int name: @swift_identifier ref -); - -swift_infix_expression_def( - unique int id: @swift_infix_expression, - int lhs: @swift_expression ref, - int op: @swift_token_custom_operator ref, - int rhs: @swift_expression ref -); - -#keyset[swift_inheritance_constraint, index] -swift_inheritance_constraint_attribute( - int swift_inheritance_constraint: @swift_inheritance_constraint ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -@swift_inheritance_constraint_constrained_type_type = @swift_identifier | @swift_nested_type_identifier - -@swift_inheritance_constraint_inherits_from_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_inheritance_constraint_def( - unique int id: @swift_inheritance_constraint, - int constrained_type: @swift_inheritance_constraint_constrained_type_type ref, - int inherits_from: @swift_inheritance_constraint_inherits_from_type ref -); - -@swift_inheritance_specifier_inherits_from_type = @swift_function_type | @swift_suppressed_constraint | @swift_user_type - -swift_inheritance_specifier_def( - unique int id: @swift_inheritance_specifier, - int inherits_from: @swift_inheritance_specifier_inherits_from_type ref -); - -swift_init_declaration_async( - unique int swift_init_declaration: @swift_init_declaration ref, - unique int async: @swift_reserved_word ref -); - -swift_init_declaration_bang( - unique int swift_init_declaration: @swift_init_declaration ref, - unique int bang: @swift_token_bang ref -); - -swift_init_declaration_body( - unique int swift_init_declaration: @swift_init_declaration ref, - unique int body: @swift_block ref -); - -swift_init_declaration_modifiers( - unique int swift_init_declaration: @swift_init_declaration ref, - unique int modifiers: @swift_modifiers ref -); - -#keyset[swift_init_declaration, index] -swift_init_declaration_parameter( - int swift_init_declaration: @swift_init_declaration ref, - int index: int ref, - unique int parameter: @swift_function_parameter ref -); - -@swift_init_declaration_throws_type = @swift_throws_clause | @swift_token_throws - -swift_init_declaration_throws( - unique int swift_init_declaration: @swift_init_declaration ref, - unique int throws: @swift_init_declaration_throws_type ref -); - -swift_init_declaration_type_constraints( - unique int swift_init_declaration: @swift_init_declaration ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_init_declaration_type_parameters( - unique int swift_init_declaration: @swift_init_declaration ref, - unique int type_parameters: @swift_type_parameters ref -); - -swift_init_declaration_def( - unique int id: @swift_init_declaration -); - -swift_interpolated_expression_name( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int name: @swift_value_argument_label ref -); - -#keyset[swift_interpolated_expression, index] -swift_interpolated_expression_reference_specifier( - int swift_interpolated_expression: @swift_interpolated_expression ref, - int index: int ref, - unique int reference_specifier: @swift_value_argument_label ref -); - -swift_interpolated_expression_type_modifiers( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int type_modifiers: @swift_type_modifiers ref -); - -swift_interpolated_expression_value( - unique int swift_interpolated_expression: @swift_interpolated_expression ref, - unique int value: @swift_expression ref -); - -swift_interpolated_expression_def( - unique int id: @swift_interpolated_expression -); - -swift_key_path_component_name( - unique int swift_key_path_component: @swift_key_path_component ref, - unique int name: @swift_token_simple_identifier ref -); - -#keyset[swift_key_path_component, index] -swift_key_path_component_postfix( - int swift_key_path_component: @swift_key_path_component ref, - int index: int ref, - unique int postfix: @swift_key_path_postfix ref -); - -swift_key_path_component_def( - unique int id: @swift_key_path_component -); - -#keyset[swift_key_path_expression, index] -swift_key_path_expression_component( - int swift_key_path_expression: @swift_key_path_expression ref, - int index: int ref, - unique int component: @swift_key_path_component ref -); - -@swift_key_path_expression_type_type = @swift_array_type | @swift_dictionary_type | @swift_simple_user_type - -swift_key_path_expression_type( - unique int swift_key_path_expression: @swift_key_path_expression ref, - unique int type__: @swift_key_path_expression_type_type ref -); - -swift_key_path_expression_def( - unique int id: @swift_key_path_expression -); - -#keyset[swift_key_path_postfix, index] -swift_key_path_postfix_argument( - int swift_key_path_postfix: @swift_key_path_postfix ref, - int index: int ref, - unique int argument: @swift_value_argument ref -); - -swift_key_path_postfix_force_unwrap( - unique int swift_key_path_postfix: @swift_key_path_postfix ref, - unique int force_unwrap: @swift_token_bang ref -); - -swift_key_path_postfix_def( - unique int id: @swift_key_path_postfix -); - -swift_key_path_string_expression_def( - unique int id: @swift_key_path_string_expression, - int expr: @swift_expression ref -); - -swift_lambda_function_type_async( - unique int swift_lambda_function_type: @swift_lambda_function_type ref, - unique int async: @swift_reserved_word ref -); - -swift_lambda_function_type_params( - unique int swift_lambda_function_type: @swift_lambda_function_type ref, - unique int params: @swift_lambda_function_type_parameters ref -); - -@swift_lambda_function_type_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_lambda_function_type_return_type( - unique int swift_lambda_function_type: @swift_lambda_function_type ref, - unique int return_type: @swift_lambda_function_type_return_type_type ref -); - -@swift_lambda_function_type_throws_type = @swift_throws_clause | @swift_token_throws - -swift_lambda_function_type_throws( - unique int swift_lambda_function_type: @swift_lambda_function_type ref, - unique int throws: @swift_lambda_function_type_throws_type ref -); - -swift_lambda_function_type_def( - unique int id: @swift_lambda_function_type -); - -#keyset[swift_lambda_function_type_parameters, index] -swift_lambda_function_type_parameters_parameter( - int swift_lambda_function_type_parameters: @swift_lambda_function_type_parameters ref, - int index: int ref, - unique int parameter: @swift_lambda_parameter ref -); - -swift_lambda_function_type_parameters_def( - unique int id: @swift_lambda_function_type_parameters -); - -#keyset[swift_lambda_literal, index] -swift_lambda_literal_attribute( - int swift_lambda_literal: @swift_lambda_literal ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -swift_lambda_literal_captures( - unique int swift_lambda_literal: @swift_lambda_literal ref, - unique int captures: @swift_capture_list ref -); - -@swift_lambda_literal_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement - -#keyset[swift_lambda_literal, index] -swift_lambda_literal_statement( - int swift_lambda_literal: @swift_lambda_literal ref, - int index: int ref, - unique int statement: @swift_lambda_literal_statement_type ref -); - -swift_lambda_literal_type( - unique int swift_lambda_literal: @swift_lambda_literal ref, - unique int type__: @swift_lambda_function_type ref -); - -swift_lambda_literal_def( - unique int id: @swift_lambda_literal -); - -swift_lambda_parameter_external_name( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int external_name: @swift_token_simple_identifier ref -); - -swift_lambda_parameter_modifiers( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int modifiers: @swift_parameter_modifiers ref -); - -@swift_lambda_parameter_name_type = @swift_token_self_expression | @swift_token_simple_identifier - -@swift_lambda_parameter_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_lambda_parameter_type( - unique int swift_lambda_parameter: @swift_lambda_parameter ref, - unique int type__: @swift_lambda_parameter_type_type ref -); - -swift_lambda_parameter_def( - unique int id: @swift_lambda_parameter, - int name: @swift_lambda_parameter_name_type ref -); - -#keyset[swift_line_string_literal, index] -swift_line_string_literal_interpolation( - int swift_line_string_literal: @swift_line_string_literal ref, - int index: int ref, - unique int interpolation: @swift_interpolated_expression ref -); - -@swift_line_string_literal_text_type = @swift_token_line_str_text | @swift_token_str_escaped_char - -#keyset[swift_line_string_literal, index] -swift_line_string_literal_text( - int swift_line_string_literal: @swift_line_string_literal ref, - int index: int ref, - unique int text: @swift_line_string_literal_text_type ref -); - -swift_line_string_literal_def( - unique int id: @swift_line_string_literal -); - -@swift_local_declaration = @swift_class_declaration | @swift_function_declaration | @swift_property_declaration | @swift_typealias_declaration - -swift_macro_declaration_definition( - unique int swift_macro_declaration: @swift_macro_declaration ref, - unique int definition: @swift_macro_definition ref -); - -swift_macro_declaration_modifiers( - unique int swift_macro_declaration: @swift_macro_declaration ref, - unique int modifiers: @swift_modifiers ref -); - -#keyset[swift_macro_declaration, index] -swift_macro_declaration_parameter( - int swift_macro_declaration: @swift_macro_declaration ref, - int index: int ref, - unique int parameter: @swift_function_parameter ref -); - -swift_macro_declaration_return_type( - unique int swift_macro_declaration: @swift_macro_declaration ref, - unique int return_type: @swift_unannotated_type ref -); - -swift_macro_declaration_type_constraints( - unique int swift_macro_declaration: @swift_macro_declaration ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_macro_declaration_type_parameters( - unique int swift_macro_declaration: @swift_macro_declaration ref, - unique int type_parameters: @swift_type_parameters ref -); - -swift_macro_declaration_def( - unique int id: @swift_macro_declaration, - int name: @swift_token_simple_identifier ref -); - -@swift_macro_definition_body_type = @swift_expression | @swift_external_macro_definition - -swift_macro_definition_def( - unique int id: @swift_macro_definition, - int body: @swift_macro_definition_body_type ref -); - -swift_macro_invocation_type_parameters( - unique int swift_macro_invocation: @swift_macro_invocation ref, - unique int type_parameters: @swift_type_parameters ref -); - -swift_macro_invocation_def( - unique int id: @swift_macro_invocation, - int name: @swift_token_simple_identifier ref, - int suffix: @swift_call_suffix ref -); - -swift_metatype_def( - unique int id: @swift_metatype, - int name: @swift_unannotated_type ref -); - -@swift_modifiers_modifier_type = @swift_attribute | @swift_token_function_modifier | @swift_token_inheritance_modifier | @swift_token_member_modifier | @swift_token_mutation_modifier | @swift_token_ownership_modifier | @swift_token_parameter_modifier | @swift_token_property_behavior_modifier | @swift_token_property_modifier | @swift_token_visibility_modifier - -#keyset[swift_modifiers, index] -swift_modifiers_modifier( - int swift_modifiers: @swift_modifiers ref, - int index: int ref, - unique int modifier: @swift_modifiers_modifier_type ref -); - -swift_modifiers_def( - unique int id: @swift_modifiers -); - -swift_modify_specifier_mutation( - unique int swift_modify_specifier: @swift_modify_specifier ref, - unique int mutation: @swift_token_mutation_modifier ref -); - -swift_modify_specifier_def( - unique int id: @swift_modify_specifier -); - -#keyset[swift_multi_line_string_literal, index] -swift_multi_line_string_literal_interpolation( - int swift_multi_line_string_literal: @swift_multi_line_string_literal ref, - int index: int ref, - unique int interpolation: @swift_interpolated_expression ref -); - -@swift_multi_line_string_literal_text_type = @swift_reserved_word | @swift_token_multi_line_str_text | @swift_token_str_escaped_char - -#keyset[swift_multi_line_string_literal, index] -swift_multi_line_string_literal_text( - int swift_multi_line_string_literal: @swift_multi_line_string_literal ref, - int index: int ref, - unique int text: @swift_multi_line_string_literal_text_type ref -); - -swift_multi_line_string_literal_def( - unique int id: @swift_multi_line_string_literal -); - -case @swift_multiplicative_expression.op of - 0 = @swift_multiplicative_expression_percent -| 1 = @swift_multiplicative_expression_star -| 2 = @swift_multiplicative_expression_slash -; - - -swift_multiplicative_expression_def( - unique int id: @swift_multiplicative_expression, - int lhs: @swift_expression ref, - int op: int ref, - int rhs: @swift_expression ref -); - -@swift_navigation_expression_target_type = @swift_array_type | @swift_dictionary_type | @swift_expression | @swift_parenthesized_type | @swift_user_type - -swift_navigation_expression_def( - unique int id: @swift_navigation_expression, - int suffix: @swift_navigation_suffix ref, - int target: @swift_navigation_expression_target_type ref -); - -@swift_navigation_suffix_suffix_type = @swift_token_integer_literal | @swift_token_simple_identifier - -swift_navigation_suffix_def( - unique int id: @swift_navigation_suffix, - int suffix: @swift_navigation_suffix_suffix_type ref -); - -#keyset[swift_nested_type_identifier, index] -swift_nested_type_identifier_member( - int swift_nested_type_identifier: @swift_nested_type_identifier ref, - int index: int ref, - unique int member: @swift_token_simple_identifier ref -); - -swift_nested_type_identifier_def( - unique int id: @swift_nested_type_identifier, - int base: @swift_unannotated_type ref -); - -swift_nil_coalescing_expression_def( - unique int id: @swift_nil_coalescing_expression, - int if_nil: @swift_expression ref, - int value: @swift_expression ref -); - -swift_opaque_type_def( - unique int id: @swift_opaque_type, - int name: @swift_unannotated_type ref -); - -swift_open_end_range_expression_def( - unique int id: @swift_open_end_range_expression, - int start: @swift_expression ref -); - -swift_open_start_range_expression_def( - unique int id: @swift_open_start_range_expression, - int end: @swift_expression ref -); - -swift_operator_declaration_body( - unique int swift_operator_declaration: @swift_operator_declaration ref, - unique int body: @swift_deprecated_operator_declaration_body ref -); - -case @swift_operator_declaration.kind of - 0 = @swift_operator_declaration_infix -| 1 = @swift_operator_declaration_postfix -| 2 = @swift_operator_declaration_prefix -; - - -swift_operator_declaration_precedence_group( - unique int swift_operator_declaration: @swift_operator_declaration ref, - unique int precedence_group: @swift_token_simple_identifier ref -); - -swift_operator_declaration_def( - unique int id: @swift_operator_declaration, - int kind: int ref, - int name: @swift_referenceable_operator ref -); - -swift_optional_chain_marker_def( - unique int id: @swift_optional_chain_marker, - int expr: @swift_expression ref -); - -@swift_optional_type_wrapped_type = @swift_array_type | @swift_dictionary_type | @swift_tuple_type | @swift_user_type - -swift_optional_type_def( - unique int id: @swift_optional_type, - int wrapped: @swift_optional_type_wrapped_type ref -); - -swift_parameter_external_name( - unique int swift_parameter: @swift_parameter ref, - unique int external_name: @swift_token_simple_identifier ref -); - -swift_parameter_modifiers( - unique int swift_parameter: @swift_parameter ref, - unique int modifiers: @swift_parameter_modifiers ref -); - -@swift_parameter_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_parameter_def( - unique int id: @swift_parameter, - int name: @swift_token_simple_identifier ref, - int type__: @swift_parameter_type_type ref -); - -#keyset[swift_parameter_modifiers, index] -swift_parameter_modifiers_modifier( - int swift_parameter_modifiers: @swift_parameter_modifiers ref, - int index: int ref, - unique int modifier: @swift_token_parameter_modifier ref -); - -swift_parameter_modifiers_def( - unique int id: @swift_parameter_modifiers -); - -@swift_parenthesized_type_type_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type - -swift_parenthesized_type_def( - unique int id: @swift_parenthesized_type, - int type__: @swift_parenthesized_type_type_type ref -); - -swift_pattern_binding( - unique int swift_pattern: @swift_pattern ref, - unique int binding: @swift_value_binding_pattern ref -); - -swift_pattern_bound_identifier( - unique int swift_pattern: @swift_pattern ref, - unique int bound_identifier: @swift_token_simple_identifier ref -); - -@swift_pattern_kind_type = @swift_binding_pattern | @swift_case_pattern | @swift_expression | @swift_token_wildcard_pattern | @swift_tuple_pattern | @swift_type_casting_pattern - -swift_pattern_def( - unique int id: @swift_pattern, - int kind: @swift_pattern_kind_type ref -); - -#keyset[swift_playground_literal, index] -swift_playground_literal_argument( - int swift_playground_literal: @swift_playground_literal ref, - int index: int ref, - unique int argument: @swift_playground_literal_argument ref -); - -case @swift_playground_literal.kind of - 0 = @swift_playground_literal_color_literal -| 1 = @swift_playground_literal_file_literal -| 2 = @swift_playground_literal_image_literal -; - - -swift_playground_literal_def( - unique int id: @swift_playground_literal, - int kind: int ref -); - -swift_playground_literal_argument_def( - unique int id: @swift_playground_literal_argument, - int name: @swift_token_simple_identifier ref, - int value: @swift_expression ref -); - -@swift_postfix_expression_operation_type = @swift_reserved_word | @swift_token_bang - -swift_postfix_expression_def( - unique int id: @swift_postfix_expression, - int operation: @swift_postfix_expression_operation_type ref, - int target: @swift_expression ref -); - -@swift_precedence_group_attribute_value_type = @swift_token_boolean_literal | @swift_token_simple_identifier - -swift_precedence_group_attribute_def( - unique int id: @swift_precedence_group_attribute, - int name: @swift_token_simple_identifier ref, - int value: @swift_precedence_group_attribute_value_type ref -); - -#keyset[swift_precedence_group_attributes, index] -swift_precedence_group_attributes_attribute( - int swift_precedence_group_attributes: @swift_precedence_group_attributes ref, - int index: int ref, - unique int attribute: @swift_precedence_group_attribute ref -); - -swift_precedence_group_attributes_def( - unique int id: @swift_precedence_group_attributes -); - -swift_precedence_group_declaration_attributes( - unique int swift_precedence_group_declaration: @swift_precedence_group_declaration ref, - unique int attributes: @swift_precedence_group_attributes ref -); - -swift_precedence_group_declaration_def( - unique int id: @swift_precedence_group_declaration, - int name: @swift_token_simple_identifier ref -); - -@swift_prefix_expression_operation_type = @swift_reserved_word | @swift_token_bang | @swift_token_custom_operator - -swift_prefix_expression_def( - unique int id: @swift_prefix_expression, - int operation: @swift_prefix_expression_operation_type ref, - int target: @swift_expression ref -); - -swift_property_binding_computed_value( - unique int swift_property_binding: @swift_property_binding ref, - unique int computed_value: @swift_computed_property ref -); - -swift_property_binding_observers( - unique int swift_property_binding: @swift_property_binding ref, - unique int observers: @swift_willset_didset_block ref -); - -swift_property_binding_type( - unique int swift_property_binding: @swift_property_binding ref, - unique int type__: @swift_type_annotation ref -); - -swift_property_binding_type_constraints( - unique int swift_property_binding: @swift_property_binding ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_property_binding_value( - unique int swift_property_binding: @swift_property_binding ref, - unique int value: @swift_expression ref -); - -swift_property_binding_def( - unique int id: @swift_property_binding, - int name: @swift_pattern ref -); - -#keyset[swift_property_declaration, index] -swift_property_declaration_declarator( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int declarator: @swift_property_binding ref -); - -@swift_property_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier - -#keyset[swift_property_declaration, index] -swift_property_declaration_modifiers( - int swift_property_declaration: @swift_property_declaration ref, - int index: int ref, - unique int modifiers: @swift_property_declaration_modifiers_type ref -); - -swift_property_declaration_def( - unique int id: @swift_property_declaration, - int binding: @swift_value_binding_pattern ref -); - -#keyset[swift_protocol_body, index] -swift_protocol_body_member( - int swift_protocol_body: @swift_protocol_body ref, - int index: int ref, - unique int member: @swift_protocol_member_declaration ref -); - -swift_protocol_body_def( - unique int id: @swift_protocol_body -); - -#keyset[swift_protocol_composition_type, index] -swift_protocol_composition_type_type( - int swift_protocol_composition_type: @swift_protocol_composition_type ref, - int index: int ref, - unique int type__: @swift_unannotated_type ref -); - -swift_protocol_composition_type_def( - unique int id: @swift_protocol_composition_type -); - -#keyset[swift_protocol_declaration, index] -swift_protocol_declaration_attribute( - int swift_protocol_declaration: @swift_protocol_declaration ref, - int index: int ref, - unique int attribute: @swift_attribute ref -); - -#keyset[swift_protocol_declaration, index] -swift_protocol_declaration_inherits( - int swift_protocol_declaration: @swift_protocol_declaration ref, - int index: int ref, - unique int inherits: @swift_inheritance_specifier ref -); - -swift_protocol_declaration_modifiers( - unique int swift_protocol_declaration: @swift_protocol_declaration ref, - unique int modifiers: @swift_modifiers ref -); - -swift_protocol_declaration_type_constraints( - unique int swift_protocol_declaration: @swift_protocol_declaration ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_protocol_declaration_type_parameters( - unique int swift_protocol_declaration: @swift_protocol_declaration ref, - unique int type_parameters: @swift_type_parameters ref -); - -swift_protocol_declaration_def( - unique int id: @swift_protocol_declaration, - int body: @swift_protocol_body ref, - int name: @swift_token_type_identifier ref -); - -swift_protocol_function_declaration_async( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int async: @swift_reserved_word ref -); - -swift_protocol_function_declaration_body( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int body: @swift_block ref -); - -swift_protocol_function_declaration_modifiers( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int modifiers: @swift_modifiers ref -); - -@swift_protocol_function_declaration_name_type = @swift_referenceable_operator | @swift_token_simple_identifier - -#keyset[swift_protocol_function_declaration, index] -swift_protocol_function_declaration_parameter( - int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - int index: int ref, - unique int parameter: @swift_function_parameter ref -); - -@swift_protocol_function_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_protocol_function_declaration_return_type( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int return_type: @swift_protocol_function_declaration_return_type_type ref -); - -@swift_protocol_function_declaration_throws_type = @swift_throws_clause | @swift_token_throws - -swift_protocol_function_declaration_throws( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int throws: @swift_protocol_function_declaration_throws_type ref -); - -swift_protocol_function_declaration_type_constraints( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_protocol_function_declaration_type_parameters( - unique int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, - unique int type_parameters: @swift_type_parameters ref -); - -swift_protocol_function_declaration_def( - unique int id: @swift_protocol_function_declaration, - int name: @swift_protocol_function_declaration_name_type ref -); - -@swift_protocol_member_declaration = @swift_associatedtype_declaration | @swift_deinit_declaration | @swift_init_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_subscript_declaration | @swift_typealias_declaration - -swift_protocol_property_declaration_modifiers( - unique int swift_protocol_property_declaration: @swift_protocol_property_declaration ref, - unique int modifiers: @swift_modifiers ref -); - -swift_protocol_property_declaration_type( - unique int swift_protocol_property_declaration: @swift_protocol_property_declaration ref, - unique int type__: @swift_type_annotation ref -); - -swift_protocol_property_declaration_type_constraints( - unique int swift_protocol_property_declaration: @swift_protocol_property_declaration ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_protocol_property_declaration_def( - unique int id: @swift_protocol_property_declaration, - int name: @swift_pattern ref, - int requirements: @swift_protocol_property_requirements ref -); - -@swift_protocol_property_requirements_accessor_type = @swift_getter_specifier | @swift_setter_specifier - -#keyset[swift_protocol_property_requirements, index] -swift_protocol_property_requirements_accessor( - int swift_protocol_property_requirements: @swift_protocol_property_requirements ref, - int index: int ref, - unique int accessor: @swift_protocol_property_requirements_accessor_type ref -); - -swift_protocol_property_requirements_def( - unique int id: @swift_protocol_property_requirements -); - -case @swift_range_expression.op of - 0 = @swift_range_expression_dotdotdot -| 1 = @swift_range_expression_dotdotlangle -; - - -swift_range_expression_def( - unique int id: @swift_range_expression, - int end: @swift_expression ref, - int op: int ref, - int start: @swift_expression ref -); - -#keyset[swift_raw_str_interpolation, index] -swift_raw_str_interpolation_interpolation( - int swift_raw_str_interpolation: @swift_raw_str_interpolation ref, - int index: int ref, - unique int interpolation: @swift_interpolated_expression ref -); - -swift_raw_str_interpolation_def( - unique int id: @swift_raw_str_interpolation, - int start: @swift_token_raw_str_interpolation_start ref -); - -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_continuing( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int continuing: @swift_token_raw_str_continuing_indicator ref -); - -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_interpolation( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int interpolation: @swift_raw_str_interpolation ref -); - -@swift_raw_string_literal_text_type = @swift_token_raw_str_end_part | @swift_token_raw_str_part - -#keyset[swift_raw_string_literal, index] -swift_raw_string_literal_text( - int swift_raw_string_literal: @swift_raw_string_literal ref, - int index: int ref, - unique int text: @swift_raw_string_literal_text_type ref -); - -swift_raw_string_literal_def( - unique int id: @swift_raw_string_literal -); - -@swift_referenceable_operator_operator_type = @swift_reserved_word | @swift_token_bang | @swift_token_custom_operator - -swift_referenceable_operator_def( - unique int id: @swift_referenceable_operator, - int operator: @swift_referenceable_operator_operator_type ref -); - -#keyset[swift_repeat_while_statement, index] -swift_repeat_while_statement_condition( - int swift_repeat_while_statement: @swift_repeat_while_statement ref, - int index: int ref, - unique int condition: @swift_if_condition ref -); - -swift_repeat_while_statement_def( - unique int id: @swift_repeat_while_statement, - int body: @swift_block ref -); - -swift_selector_expression_def( - unique int id: @swift_selector_expression, - int expr: @swift_expression ref -); - -swift_setter_specifier_mutation( - unique int swift_setter_specifier: @swift_setter_specifier ref, - unique int mutation: @swift_token_mutation_modifier ref -); - -swift_setter_specifier_def( - unique int id: @swift_setter_specifier -); - -swift_simple_user_type_arguments( - unique int swift_simple_user_type: @swift_simple_user_type ref, - unique int arguments: @swift_type_arguments ref -); - -swift_simple_user_type_def( - unique int id: @swift_simple_user_type, - int name: @swift_token_type_identifier ref -); - -swift_source_file_shebang( - unique int swift_source_file: @swift_source_file ref, - unique int shebang: @swift_token_shebang_line ref -); - -@swift_source_file_statement_type = @swift_do_statement | @swift_expression | @swift_for_statement | @swift_global_declaration | @swift_guard_statement | @swift_repeat_while_statement | @swift_token_statement_label | @swift_token_throw_keyword | @swift_while_statement - -#keyset[swift_source_file, index] -swift_source_file_statement( - int swift_source_file: @swift_source_file ref, - int index: int ref, - unique int statement: @swift_source_file_statement_type ref -); - -swift_source_file_def( - unique int id: @swift_source_file -); - -swift_subscript_declaration_modifiers( - unique int swift_subscript_declaration: @swift_subscript_declaration ref, - unique int modifiers: @swift_modifiers ref -); - -#keyset[swift_subscript_declaration, index] -swift_subscript_declaration_parameter( - int swift_subscript_declaration: @swift_subscript_declaration ref, - int index: int ref, - unique int parameter: @swift_function_parameter ref -); - -@swift_subscript_declaration_return_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_subscript_declaration_return_type( - unique int swift_subscript_declaration: @swift_subscript_declaration ref, - unique int return_type: @swift_subscript_declaration_return_type_type ref -); - -swift_subscript_declaration_type_constraints( - unique int swift_subscript_declaration: @swift_subscript_declaration ref, - unique int type_constraints: @swift_type_constraints ref -); - -swift_subscript_declaration_type_parameters( - unique int swift_subscript_declaration: @swift_subscript_declaration ref, - unique int type_parameters: @swift_type_parameters ref -); - -swift_subscript_declaration_def( - unique int id: @swift_subscript_declaration, - int body: @swift_computed_property ref -); - -swift_suppressed_constraint_def( - unique int id: @swift_suppressed_constraint, - int suppressed: @swift_token_type_identifier ref -); - -swift_switch_entry_default( - unique int swift_switch_entry: @swift_switch_entry ref, - unique int default: @swift_token_default_keyword ref -); - -swift_switch_entry_modifiers( - unique int swift_switch_entry: @swift_switch_entry ref, - unique int modifiers: @swift_modifiers ref -); - -#keyset[swift_switch_entry, index] -swift_switch_entry_pattern( - int swift_switch_entry: @swift_switch_entry ref, - int index: int ref, - unique int pattern: @swift_switch_pattern ref -); - -@swift_switch_entry_statement_type = @swift_control_transfer_statement | @swift_do_statement | @swift_expression | @swift_for_statement | @swift_guard_statement | @swift_local_declaration | @swift_repeat_while_statement | @swift_token_statement_label | @swift_while_statement - -#keyset[swift_switch_entry, index] -swift_switch_entry_statement( - int swift_switch_entry: @swift_switch_entry ref, - int index: int ref, - unique int statement: @swift_switch_entry_statement_type ref -); - -swift_switch_entry_where( - unique int swift_switch_entry: @swift_switch_entry ref, - unique int where: @swift_where_clause ref -); - -swift_switch_entry_def( - unique int id: @swift_switch_entry -); - -swift_switch_pattern_def( - unique int id: @swift_switch_pattern, - int pattern: @swift_pattern ref -); - -#keyset[swift_switch_statement, index] -swift_switch_statement_entry( - int swift_switch_statement: @swift_switch_statement ref, - int index: int ref, - unique int entry: @swift_switch_entry ref -); - -swift_switch_statement_def( - unique int id: @swift_switch_statement, - int expr: @swift_expression ref -); - -swift_ternary_expression_def( - unique int id: @swift_ternary_expression, - int condition: @swift_expression ref, - int if_false: @swift_expression ref, - int if_true: @swift_expression ref -); - -swift_throws_clause_def( - unique int id: @swift_throws_clause, - int type__: @swift_unannotated_type ref -); - -swift_try_expression_def( - unique int id: @swift_try_expression, - int expr: @swift_expression ref, - int operator: @swift_token_try_operator ref -); - -#keyset[swift_tuple_expression, index] -swift_tuple_expression_element( - int swift_tuple_expression: @swift_tuple_expression ref, - int index: int ref, - unique int element: @swift_tuple_expression_item ref -); - -swift_tuple_expression_def( - unique int id: @swift_tuple_expression -); - -swift_tuple_expression_item_name( - unique int swift_tuple_expression_item: @swift_tuple_expression_item ref, - unique int name: @swift_token_simple_identifier ref -); - -swift_tuple_expression_item_def( - unique int id: @swift_tuple_expression_item, - int value: @swift_expression ref -); - -#keyset[swift_tuple_pattern, index] -swift_tuple_pattern_item( - int swift_tuple_pattern: @swift_tuple_pattern ref, +/*- Unified dbscheme -*/ +#keyset[unified_apply_pattern, index] +unified_apply_pattern_argument( + int unified_apply_pattern: @unified_apply_pattern ref, int index: int ref, - unique int item: @swift_tuple_pattern_item ref -); - -swift_tuple_pattern_def( - unique int id: @swift_tuple_pattern + unique int argument: @unified_pattern ref ); -swift_tuple_pattern_item_name( - unique int swift_tuple_pattern_item: @swift_tuple_pattern_item ref, - unique int name: @swift_token_simple_identifier ref +unified_apply_pattern_def( + unique int id: @unified_apply_pattern, + int constructor: @unified_expr ref ); -swift_tuple_pattern_item_def( - unique int id: @swift_tuple_pattern_item, - int pattern: @swift_pattern ref +unified_binary_expr_def( + unique int id: @unified_binary_expr, + int left: @unified_expr ref, + int operator: @unified_token_operator ref, + int right: @unified_expr ref ); -#keyset[swift_tuple_type, index] -swift_tuple_type_element( - int swift_tuple_type: @swift_tuple_type ref, +#keyset[unified_block_stmt, index] +unified_block_stmt_body( + int unified_block_stmt: @unified_block_stmt ref, int index: int ref, - unique int element: @swift_tuple_type_item ref -); - -swift_tuple_type_def( - unique int id: @swift_tuple_type -); - -swift_tuple_type_item_external_name( - unique int swift_tuple_type_item: @swift_tuple_type_item ref, - unique int external_name: @swift_token_wildcard_pattern ref -); - -swift_tuple_type_item_modifiers( - unique int swift_tuple_type_item: @swift_tuple_type_item ref, - unique int modifiers: @swift_parameter_modifiers ref -); - -swift_tuple_type_item_name( - unique int swift_tuple_type_item: @swift_tuple_type_item ref, - unique int name: @swift_token_simple_identifier ref -); - -@swift_tuple_type_item_type_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type | @swift_type__ - -swift_tuple_type_item_def( - unique int id: @swift_tuple_type_item, - int type__: @swift_tuple_type_item_type_type ref -); - -swift_type_modifiers( - unique int swift_type__: @swift_type__ ref, - unique int modifiers: @swift_type_modifiers ref + unique int body: @unified_stmt ref ); -swift_type_def( - unique int id: @swift_type__, - int name: @swift_unannotated_type ref +unified_block_stmt_def( + unique int id: @unified_block_stmt ); -@swift_type_annotation_type_type = @swift_implicitly_unwrapped_type | @swift_type__ - -swift_type_annotation_def( - unique int id: @swift_type_annotation, - int type__: @swift_type_annotation_type_type ref -); - -#keyset[swift_type_arguments, index] -swift_type_arguments_argument( - int swift_type_arguments: @swift_type_arguments ref, +#keyset[unified_call_expr, index] +unified_call_expr_argument( + int unified_call_expr: @unified_call_expr ref, int index: int ref, - unique int argument: @swift_type__ ref -); - -swift_type_arguments_def( - unique int id: @swift_type_arguments -); - -swift_type_casting_pattern_pattern( - unique int swift_type_casting_pattern: @swift_type_casting_pattern ref, - unique int pattern: @swift_pattern ref + unique int argument: @unified_expr ref ); -swift_type_casting_pattern_def( - unique int id: @swift_type_casting_pattern, - int type__: @swift_type__ ref +unified_call_expr_def( + unique int id: @unified_call_expr, + int function: @unified_expr ref ); -@swift_type_constraint_constraint_type = @swift_equality_constraint | @swift_inheritance_constraint - -swift_type_constraint_def( - unique int id: @swift_type_constraint, - int constraint: @swift_type_constraint_constraint_type ref -); +@unified_condition = @unified_expr_condition | @unified_let_pattern_condition | @unified_sequence_condition | @unified_token_unsupported_node -#keyset[swift_type_constraints, index] -swift_type_constraints_constraint( - int swift_type_constraints: @swift_type_constraints ref, - int index: int ref, - unique int constraint: @swift_type_constraint ref -); +@unified_expr = @unified_binary_expr | @unified_call_expr | @unified_lambda_expr | @unified_member_access_expr | @unified_name_expr | @unified_token_int_literal | @unified_token_string_literal | @unified_token_unsupported_node | @unified_unary_expr -swift_type_constraints_def( - unique int id: @swift_type_constraints, - int keyword: @swift_token_where_keyword ref +unified_expr_condition_def( + unique int id: @unified_expr_condition, + int expr: @unified_expr ref ); -@swift_type_level_declaration = @swift_associatedtype_declaration | @swift_class_declaration | @swift_deinit_declaration | @swift_function_declaration | @swift_import_declaration | @swift_init_declaration | @swift_operator_declaration | @swift_precedence_group_declaration | @swift_property_declaration | @swift_protocol_declaration | @swift_subscript_declaration | @swift_typealias_declaration - -#keyset[swift_type_modifiers, index] -swift_type_modifiers_attribute( - int swift_type_modifiers: @swift_type_modifiers ref, - int index: int ref, - unique int attribute: @swift_attribute ref +unified_expr_stmt_def( + unique int id: @unified_expr_stmt, + int expr: @unified_expr ref ); -swift_type_modifiers_def( - unique int id: @swift_type_modifiers +unified_guard_if_stmt_def( + unique int id: @unified_guard_if_stmt, + int condition: @unified_condition ref, + int else: @unified_stmt ref ); -swift_type_pack_expansion_def( - unique int id: @swift_type_pack_expansion, - int name: @swift_unannotated_type ref +unified_if_stmt_else( + unique int unified_if_stmt: @unified_if_stmt ref, + unique int else: @unified_stmt ref ); -swift_type_parameter_modifiers( - unique int swift_type_parameter: @swift_type_parameter ref, - unique int modifiers: @swift_type_parameter_modifiers ref +unified_if_stmt_then( + unique int unified_if_stmt: @unified_if_stmt ref, + unique int then: @unified_stmt ref ); -@swift_type_parameter_name_type = @swift_token_type_identifier | @swift_type_parameter_pack - -swift_type_parameter_type( - unique int swift_type_parameter: @swift_type_parameter ref, - unique int type__: @swift_type__ ref +unified_if_stmt_def( + unique int id: @unified_if_stmt, + int condition: @unified_condition ref ); -swift_type_parameter_def( - unique int id: @swift_type_parameter, - int name: @swift_type_parameter_name_type ref -); +@unified_lambda_expr_body_type = @unified_expr | @unified_stmt -#keyset[swift_type_parameter_modifiers, index] -swift_type_parameter_modifiers_attribute( - int swift_type_parameter_modifiers: @swift_type_parameter_modifiers ref, +#keyset[unified_lambda_expr, index] +unified_lambda_expr_parameter( + int unified_lambda_expr: @unified_lambda_expr ref, int index: int ref, - unique int attribute: @swift_attribute ref + unique int parameter: @unified_parameter ref ); -swift_type_parameter_modifiers_def( - unique int id: @swift_type_parameter_modifiers +unified_lambda_expr_def( + unique int id: @unified_lambda_expr, + int body: @unified_lambda_expr_body_type ref ); -swift_type_parameter_pack_def( - unique int id: @swift_type_parameter_pack, - int name: @swift_unannotated_type ref +unified_let_pattern_condition_def( + unique int id: @unified_let_pattern_condition, + int pattern: @unified_pattern ref, + int value: @unified_expr ref ); -swift_type_parameters_constraints( - unique int swift_type_parameters: @swift_type_parameters ref, - unique int constraints: @swift_type_constraints ref +unified_member_access_expr_def( + unique int id: @unified_member_access_expr, + int member: @unified_token_identifier ref, + int target: @unified_expr ref ); -#keyset[swift_type_parameters, index] -swift_type_parameters_parameter( - int swift_type_parameters: @swift_type_parameters ref, - int index: int ref, - unique int parameter: @swift_type_parameter ref +unified_name_expr_def( + unique int id: @unified_name_expr, + int identifier: @unified_token_identifier ref ); -swift_type_parameters_def( - unique int id: @swift_type_parameters +unified_parameter_def( + unique int id: @unified_parameter, + int pattern: @unified_pattern ref ); -@swift_typealias_declaration_modifiers_type = @swift_attribute | @swift_modifiers | @swift_token_inheritance_modifier | @swift_token_ownership_modifier | @swift_token_property_behavior_modifier +@unified_pattern = @unified_apply_pattern | @unified_token_ignore_pattern | @unified_token_unsupported_node | @unified_tuple_pattern | @unified_var_pattern -#keyset[swift_typealias_declaration, index] -swift_typealias_declaration_modifiers( - int swift_typealias_declaration: @swift_typealias_declaration ref, +#keyset[unified_sequence_condition, index] +unified_sequence_condition_stmt( + int unified_sequence_condition: @unified_sequence_condition ref, int index: int ref, - unique int modifiers: @swift_typealias_declaration_modifiers_type ref -); - -swift_typealias_declaration_type_parameters( - unique int swift_typealias_declaration: @swift_typealias_declaration ref, - unique int type_parameters: @swift_type_parameters ref -); - -swift_typealias_declaration_def( - unique int id: @swift_typealias_declaration, - int name: @swift_token_type_identifier ref, - int value: @swift_type__ ref + unique int stmt: @unified_stmt ref ); -@swift_unannotated_type = @swift_array_type | @swift_dictionary_type | @swift_existential_type | @swift_function_type | @swift_metatype | @swift_opaque_type | @swift_optional_type | @swift_protocol_composition_type | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type - -#keyset[swift_user_type, index] -swift_user_type_part( - int swift_user_type: @swift_user_type ref, - int index: int ref, - unique int part: @swift_simple_user_type ref +unified_sequence_condition_def( + unique int id: @unified_sequence_condition, + int condition: @unified_condition ref ); -swift_user_type_def( - unique int id: @swift_user_type -); +@unified_stmt = @unified_block_stmt | @unified_expr_stmt | @unified_guard_if_stmt | @unified_if_stmt | @unified_token_empty_stmt | @unified_token_unsupported_node | @unified_variable_declaration_stmt -swift_value_argument_name( - unique int swift_value_argument: @swift_value_argument ref, - unique int name: @swift_value_argument_label ref -); +@unified_top_level_body_type = @unified_expr | @unified_stmt -#keyset[swift_value_argument, index] -swift_value_argument_reference_specifier( - int swift_value_argument: @swift_value_argument ref, +#keyset[unified_top_level, index] +unified_top_level_body( + int unified_top_level: @unified_top_level ref, int index: int ref, - unique int reference_specifier: @swift_value_argument_label ref -); - -swift_value_argument_type_modifiers( - unique int swift_value_argument: @swift_value_argument ref, - unique int type_modifiers: @swift_type_modifiers ref -); - -swift_value_argument_value( - unique int swift_value_argument: @swift_value_argument ref, - unique int value: @swift_expression ref + unique int body: @unified_top_level_body_type ref ); -swift_value_argument_def( - unique int id: @swift_value_argument +unified_top_level_def( + unique int id: @unified_top_level ); -swift_value_argument_label_def( - unique int id: @swift_value_argument_label, - int name: @swift_token_simple_identifier ref -); - -#keyset[swift_value_arguments, index] -swift_value_arguments_argument( - int swift_value_arguments: @swift_value_arguments ref, +#keyset[unified_tuple_pattern, index] +unified_tuple_pattern_element( + int unified_tuple_pattern: @unified_tuple_pattern ref, int index: int ref, - unique int argument: @swift_value_argument ref -); - -swift_value_arguments_def( - unique int id: @swift_value_arguments -); - -case @swift_value_binding_pattern.mutability of - 0 = @swift_value_binding_pattern_let -| 1 = @swift_value_binding_pattern_var -; - - -swift_value_binding_pattern_def( - unique int id: @swift_value_binding_pattern, - int mutability: int ref + unique int element: @unified_pattern ref ); -swift_value_pack_expansion_def( - unique int id: @swift_value_pack_expansion, - int expr: @swift_expression ref +unified_tuple_pattern_def( + unique int id: @unified_tuple_pattern ); -swift_value_parameter_pack_def( - unique int id: @swift_value_parameter_pack, - int expr: @swift_expression ref +unified_unary_expr_def( + unique int id: @unified_unary_expr, + int operand: @unified_expr ref, + int operator: @unified_token_operator ref ); -swift_where_clause_def( - unique int id: @swift_where_clause, - int expr: @swift_expression ref, - int keyword: @swift_token_where_keyword ref +unified_var_pattern_def( + unique int id: @unified_var_pattern, + int identifier: @unified_token_identifier ref ); -#keyset[swift_while_statement, index] -swift_while_statement_condition( - int swift_while_statement: @swift_while_statement ref, +#keyset[unified_variable_declaration_stmt, index] +unified_variable_declaration_stmt_variable_declarator( + int unified_variable_declaration_stmt: @unified_variable_declaration_stmt ref, int index: int ref, - unique int condition: @swift_if_condition ref -); - -swift_while_statement_def( - unique int id: @swift_while_statement, - int body: @swift_block ref -); - -swift_willset_clause_modifiers( - unique int swift_willset_clause: @swift_willset_clause ref, - unique int modifiers: @swift_modifiers ref -); - -swift_willset_clause_parameter( - unique int swift_willset_clause: @swift_willset_clause ref, - unique int parameter: @swift_token_simple_identifier ref -); - -swift_willset_clause_def( - unique int id: @swift_willset_clause, - int body: @swift_block ref + unique int variable_declarator: @unified_variable_declarator ref ); -swift_willset_didset_block_didset( - unique int swift_willset_didset_block: @swift_willset_didset_block ref, - unique int didset: @swift_didset_clause ref +unified_variable_declaration_stmt_def( + unique int id: @unified_variable_declaration_stmt ); -swift_willset_didset_block_willset( - unique int swift_willset_didset_block: @swift_willset_didset_block ref, - unique int willset: @swift_willset_clause ref +unified_variable_declarator_value( + unique int unified_variable_declarator: @unified_variable_declarator ref, + unique int value: @unified_expr ref ); -swift_willset_didset_block_def( - unique int id: @swift_willset_didset_block +unified_variable_declarator_def( + unique int id: @unified_variable_declarator, + int pattern: @unified_pattern ref ); -swift_tokeninfo( - unique int id: @swift_token, +unified_tokeninfo( + unique int id: @unified_token, int kind: int ref, string value: string ref ); -case @swift_token.kind of - 0 = @swift_reserved_word -| 1 = @swift_token_as_operator -| 2 = @swift_token_async_keyword -| 3 = @swift_token_bang -| 4 = @swift_token_bin_literal -| 5 = @swift_token_boolean_literal -| 6 = @swift_token_catch_keyword -| 7 = @swift_token_comment -| 8 = @swift_token_custom_operator -| 9 = @swift_token_default_keyword -| 10 = @swift_token_diagnostic -| 11 = @swift_token_fully_open_range -| 12 = @swift_token_function_modifier -| 13 = @swift_token_hex_literal -| 14 = @swift_token_inheritance_modifier -| 15 = @swift_token_integer_literal -| 16 = @swift_token_line_str_text -| 17 = @swift_token_member_modifier -| 18 = @swift_token_multi_line_str_text -| 19 = @swift_token_multiline_comment -| 20 = @swift_token_mutation_modifier -| 21 = @swift_token_oct_literal -| 22 = @swift_token_ownership_modifier -| 23 = @swift_token_parameter_modifier -| 24 = @swift_token_property_behavior_modifier -| 25 = @swift_token_property_modifier -| 26 = @swift_token_raw_str_continuing_indicator -| 27 = @swift_token_raw_str_end_part -| 28 = @swift_token_raw_str_interpolation_start -| 29 = @swift_token_raw_str_part -| 30 = @swift_token_real_literal -| 31 = @swift_token_regex_literal -| 32 = @swift_token_self_expression -| 33 = @swift_token_shebang_line -| 34 = @swift_token_simple_identifier -| 35 = @swift_token_special_literal -| 36 = @swift_token_statement_label -| 37 = @swift_token_str_escaped_char -| 38 = @swift_token_super_expression -| 39 = @swift_token_throw_keyword -| 40 = @swift_token_throws -| 41 = @swift_token_try_operator -| 42 = @swift_token_type_identifier -| 43 = @swift_token_visibility_modifier -| 44 = @swift_token_where_keyword -| 45 = @swift_token_wildcard_pattern +case @unified_token.kind of + 1 = @unified_token_empty_stmt +| 2 = @unified_token_identifier +| 3 = @unified_token_ignore_pattern +| 4 = @unified_token_int_literal +| 5 = @unified_token_operator +| 6 = @unified_token_string_literal +| 7 = @unified_token_unsupported_node ; -@swift_ast_node = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_associatedtype_declaration | @swift_attribute | @swift_availability_condition | @swift_await_expression | @swift_binding_pattern | @swift_bitwise_operation | @swift_block | @swift_call_expression | @swift_call_suffix | @swift_capture_list | @swift_capture_list_item | @swift_case_pattern | @swift_catch_block | @swift_check_expression | @swift_class_body | @swift_class_declaration | @swift_comparison_expression | @swift_compilation_condition | @swift_computed_getter | @swift_computed_modify | @swift_computed_property | @swift_computed_setter | @swift_conjunction_expression | @swift_constructor_expression | @swift_constructor_suffix | @swift_control_transfer_statement | @swift_deinit_declaration | @swift_deprecated_operator_declaration_body | @swift_dictionary_literal | @swift_dictionary_literal_item | @swift_dictionary_type | @swift_didset_clause | @swift_directive | @swift_directly_assignable_expression | @swift_disjunction_expression | @swift_do_statement | @swift_enum_case_entry | @swift_enum_class_body | @swift_enum_entry | @swift_enum_type_parameter | @swift_enum_type_parameters | @swift_equality_constraint | @swift_equality_expression | @swift_existential_type | @swift_external_macro_definition | @swift_for_statement | @swift_function_declaration | @swift_function_parameter | @swift_function_type | @swift_getter_specifier | @swift_guard_statement | @swift_identifier | @swift_if_condition | @swift_if_let_binding | @swift_if_statement | @swift_implicitly_unwrapped_type | @swift_import_declaration | @swift_infix_expression | @swift_inheritance_constraint | @swift_inheritance_specifier | @swift_init_declaration | @swift_interpolated_expression | @swift_key_path_component | @swift_key_path_expression | @swift_key_path_postfix | @swift_key_path_string_expression | @swift_lambda_function_type | @swift_lambda_function_type_parameters | @swift_lambda_literal | @swift_lambda_parameter | @swift_line_string_literal | @swift_macro_declaration | @swift_macro_definition | @swift_macro_invocation | @swift_metatype | @swift_modifiers | @swift_modify_specifier | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_navigation_suffix | @swift_nested_type_identifier | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_operator_declaration | @swift_optional_chain_marker | @swift_optional_type | @swift_parameter | @swift_parameter_modifiers | @swift_parenthesized_type | @swift_pattern | @swift_playground_literal | @swift_playground_literal_argument | @swift_postfix_expression | @swift_precedence_group_attribute | @swift_precedence_group_attributes | @swift_precedence_group_declaration | @swift_prefix_expression | @swift_property_binding | @swift_property_declaration | @swift_protocol_body | @swift_protocol_composition_type | @swift_protocol_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_protocol_property_requirements | @swift_range_expression | @swift_raw_str_interpolation | @swift_raw_string_literal | @swift_referenceable_operator | @swift_repeat_while_statement | @swift_selector_expression | @swift_setter_specifier | @swift_simple_user_type | @swift_source_file | @swift_subscript_declaration | @swift_suppressed_constraint | @swift_switch_entry | @swift_switch_pattern | @swift_switch_statement | @swift_ternary_expression | @swift_throws_clause | @swift_token | @swift_try_expression | @swift_tuple_expression | @swift_tuple_expression_item | @swift_tuple_pattern | @swift_tuple_pattern_item | @swift_tuple_type | @swift_tuple_type_item | @swift_type__ | @swift_type_annotation | @swift_type_arguments | @swift_type_casting_pattern | @swift_type_constraint | @swift_type_constraints | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter | @swift_type_parameter_modifiers | @swift_type_parameter_pack | @swift_type_parameters | @swift_typealias_declaration | @swift_user_type | @swift_value_argument | @swift_value_argument_label | @swift_value_arguments | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause | @swift_while_statement | @swift_willset_clause | @swift_willset_didset_block +@unified_ast_node = @unified_apply_pattern | @unified_binary_expr | @unified_block_stmt | @unified_call_expr | @unified_expr_condition | @unified_expr_stmt | @unified_guard_if_stmt | @unified_if_stmt | @unified_lambda_expr | @unified_let_pattern_condition | @unified_member_access_expr | @unified_name_expr | @unified_parameter | @unified_sequence_condition | @unified_token | @unified_top_level | @unified_tuple_pattern | @unified_unary_expr | @unified_var_pattern | @unified_variable_declaration_stmt | @unified_variable_declarator -swift_ast_node_location( - unique int node: @swift_ast_node ref, +unified_ast_node_location( + unique int node: @unified_ast_node ref, int loc: @location_default ref ); #keyset[parent, parent_index] -swift_ast_node_parent( - unique int node: @swift_ast_node ref, - int parent: @swift_ast_node ref, +unified_ast_node_parent( + unique int node: @unified_ast_node ref, + int parent: @unified_ast_node ref, int parent_index: int ref ); From 5f54a8691d3c1de741ecee37ebc9637e181c3467 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 May 2026 17:11:58 +0200 Subject: [PATCH 120/226] C++: Small cleanup. This has no effect on semantics. --- cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index fb2108c2ac5..5bab7dd00f2 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -276,6 +276,12 @@ private predicate isClassConstructedFrom(Class c, Class templateClass) { not c.isConstructedFrom(_) and c = templateClass } +/** Gets the fully templated version of `f`. */ +private Class getFullyTemplatedClass(Class c) { + not c.isFromUninstantiatedTemplate(_) and + isClassConstructedFrom(c, result) +} + /** * Holds if `f` is an instantiation of a function template `templateFunc`, or * holds with `f = templateFunc` if `f` is not an instantiation of any function @@ -312,7 +318,7 @@ private string withConst(string s, Type t) { if t.isConst() then result = "const " + s else result = s } -/** Prefixes `volatile` to `s` if `t` is const, or returns `s` otherwise. */ +/** Prefixes `volatile` to `s` if `t` is volatile, or returns `s` otherwise. */ bindingset[s, t] private string withVolatile(string s, Type t) { if t.isVolatile() then result = "volatile " + s else result = s @@ -490,7 +496,7 @@ pragma[nomagic] private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) { // If there is a declaring type then we start by expanding the function templates exists(Class template | - isClassConstructedFrom(f.getDeclaringType(), template) and + template = getFullyTemplatedClass(f.getDeclaringType()) and remaining = getNumberOfSupportedClassTemplateArguments(template) and result = getTypeNameWithoutFunctionTemplates(f, n, 0) ) @@ -502,7 +508,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining or exists(string mid, TypeTemplateParameter tp, Class template | mid = getTypeNameWithoutClassTemplates(f, n, remaining + 1) and - isClassConstructedFrom(f.getDeclaringType(), template) and + template = getFullyTemplatedClass(f.getDeclaringType()) and tp = getSupportedClassTemplateArgument(template, remaining) | result = mid.replaceAll(tp.getName(), "class:" + remaining.toString()) From 6042adebae6089df3a0d2f5b0f8599e6b485564b Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Wed, 27 May 2026 17:23:28 +0200 Subject: [PATCH 121/226] move identical java and cs bound.qll to shared library --- .../lib/semmle/code/java/dataflow/Bound.qll | 67 ++---------- .../internal/rangeanalysis/BoundSpecific.qll | 29 ++--- .../codeql/rangeanalysis/Bound.qll | 100 ++++++++++++++++++ 3 files changed, 125 insertions(+), 71 deletions(-) create mode 100644 shared/rangeanalysis/codeql/rangeanalysis/Bound.qll diff --git a/java/ql/lib/semmle/code/java/dataflow/Bound.qll b/java/ql/lib/semmle/code/java/dataflow/Bound.qll index 65af6fb13a8..a1588020838 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Bound.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Bound.qll @@ -4,67 +4,16 @@ overlay[local?] module; -private import internal.rangeanalysis.BoundSpecific +private import java as J +private import internal.rangeanalysis.BoundSpecific as BoundSpecific +private import codeql.rangeanalysis.Bound as SharedBound -private newtype TBound = - TBoundZero() or - TBoundSsa(SsaVariable v) { v.getSourceVariable().getType() instanceof IntegralType } or - TBoundExpr(Expr e) { - interestingExprBound(e) and - not exists(SsaVariable v | e = v.getAUse()) - } +module BoundInstantiation = SharedBound::Bound; -/** - * A bound that may be inferred for an expression plus/minus an integer delta. - */ -abstract class Bound extends TBound { - /** Gets a textual representation of this bound. */ - abstract string toString(); +class Bound = BoundInstantiation::Bound; - /** Gets an expression that equals this bound plus `delta`. */ - abstract Expr getExpr(int delta); +class ZeroBound = BoundInstantiation::ZeroBound; - /** Gets an expression that equals this bound. */ - Expr getExpr() { result = this.getExpr(0) } +class SsaBound = BoundInstantiation::SsaBound; - /** Gets the location of this bound. */ - abstract Location getLocation(); -} - -/** - * The bound that corresponds to the integer 0. This is used to represent all - * integer bounds as bounds are always accompanied by an added integer delta. - */ -class ZeroBound extends Bound, TBoundZero { - override string toString() { result = "0" } - - override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta } - - override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } -} - -/** - * A bound corresponding to the value of an SSA variable. - */ -class SsaBound extends Bound, TBoundSsa { - /** Gets the SSA variable that equals this bound. */ - SsaVariable getSsa() { this = TBoundSsa(result) } - - override string toString() { result = this.getSsa().toString() } - - override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 } - - override Location getLocation() { result = this.getSsa().getLocation() } -} - -/** - * A bound that corresponds to the value of a specific expression that might be - * interesting, but isn't otherwise represented by the value of an SSA variable. - */ -class ExprBound extends Bound, TBoundExpr { - override string toString() { result = this.getExpr().toString() } - - override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 } - - override Location getLocation() { result = this.getExpr().getLocation() } -} +class ExprBound = BoundInstantiation::ExprBound; \ No newline at end of file diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll index cd85883f7bc..ba2f8027b30 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll @@ -7,21 +7,26 @@ module; private import java as J private import semmle.code.java.dataflow.SSA as Ssa private import semmle.code.java.dataflow.RangeUtils as RU +private import codeql.rangeanalysis.Bound as SharedBound -class SsaVariable extends Ssa::SsaDefinition { - /** Gets a use of this variable. */ - Expr getAUse() { result = super.getARead() } -} +module BoundDefs implements SharedBound::BoundDefinitions { + class SsaVariable extends Ssa::SsaDefinition { + /** Gets a use of this variable. */ + Expr getAUse() { result = super.getARead() } + } -class Expr = J::Expr; + class SsaSourceVariable = Ssa::SourceVariable; -class Location = J::Location; + class Type = J::Type; -class IntegralType = J::IntegralType; + class Expr = J::Expr; -class ConstantIntegerExpr = RU::ConstantIntegerExpr; + class IntegralType = J::IntegralType; -/** Holds if `e` is a bound expression and it is not an SSA variable read. */ -predicate interestingExprBound(Expr e) { - e.(J::FieldRead).getField() instanceof J::ArrayLengthField -} + class ConstantIntegerExpr = RU::ConstantIntegerExpr; + + /** Holds if `e` is a bound expression and it is not an SSA variable read. */ + predicate interestingExprBound(Expr e) { + e.(J::FieldRead).getField() instanceof J::ArrayLengthField + } +} \ No newline at end of file diff --git a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll new file mode 100644 index 00000000000..10ef74d4001 --- /dev/null +++ b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll @@ -0,0 +1,100 @@ +/** + * Provides classes for representing abstract bounds for use in, for example, range analysis. + */ + +private import codeql.util.Location + +signature module BoundDefinitions { + class Type; + class IntegralType extends Type; + + class ConstantIntegerExpr extends Expr { + int getIntValue(); + } + + class SsaSourceVariable { + Type getType(); + } + + class SsaVariable { + SsaSourceVariable getSourceVariable(); + string toString(); + Location getLocation(); + Expr getAUse(); + } + + class Expr { + string toString(); + Location getLocation(); + } + + predicate interestingExprBound(Expr e); +} + +overlay[local?] +module Bound Defs> { + private import Defs + + private newtype TBound = + TBoundZero() or + TBoundSsa(SsaVariable v) { v.getSourceVariable().getType() instanceof IntegralType } or + TBoundExpr(Expr e) { + interestingExprBound(e) and + not exists(SsaVariable v | e = v.getAUse()) + } + + /** + * A bound that may be inferred for an expression plus/minus an integer delta. + */ + abstract class Bound extends TBound { + /** Gets a textual representation of this bound. */ + abstract string toString(); + + /** Gets an expression that equals this bound plus `delta`. */ + abstract Expr getExpr(int delta); + + /** Gets an expression that equals this bound. */ + Expr getExpr() { result = this.getExpr(0) } + + /** Gets the location of this bound. */ + abstract Location getLocation(); + } + + /** + * The bound that corresponds to the integer 0. This is used to represent all + * integer bounds as bounds are always accompanied by an added integer delta. + */ + class ZeroBound extends Bound, TBoundZero { + override string toString() { result = "0" } + + override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta } + + override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } + } + + /** + * A bound corresponding to the value of an SSA variable. + */ + class SsaBound extends Bound, TBoundSsa { + /** Gets the SSA variable that equals this bound. */ + SsaVariable getSsa() { this = TBoundSsa(result) } + + override string toString() { result = this.getSsa().toString() } + + override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 } + + override Location getLocation() { result = this.getSsa().getLocation() } + } + + /** + * A bound that corresponds to the value of a specific expression that might be + * interesting, but isn't otherwise represented by the value of an SSA variable. + */ + class ExprBound extends Bound, TBoundExpr { + override string toString() { result = this.getExpr().toString() } + + override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 } + + override Location getLocation() { result = this.getExpr().getLocation() } + } +} From acb5c0e70f56d981cec2f2e408b7a15247e4d818 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Wed, 27 May 2026 17:23:45 +0200 Subject: [PATCH 122/226] missed changes --- csharp/ql/lib/qlpack.yml | 1 + .../lib/semmle/code/csharp/dataflow/Bound.qll | 52 +++---------------- .../internal/rangeanalysis/BoundSpecific.qll | 32 ++++++++---- .../lib/semmle/code/java/dataflow/Bound.qll | 24 +++++++-- 4 files changed, 49 insertions(+), 60 deletions(-) diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index b3a0dab7303..8501130e2e7 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -9,6 +9,7 @@ dependencies: codeql/controlflow: ${workspace} codeql/dataflow: ${workspace} codeql/mad: ${workspace} + codeql/rangeanalysis: ${workspace} codeql/ssa: ${workspace} codeql/threat-models: ${workspace} codeql/tutorial: ${workspace} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll index 65af6fb13a8..b37222c1daa 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll @@ -4,67 +4,31 @@ overlay[local?] module; +private import csharp as CS private import internal.rangeanalysis.BoundSpecific +private import internal.rangeanalysis.BoundSpecific as BoundSpecific +private import codeql.rangeanalysis.Bound as SharedBound -private newtype TBound = - TBoundZero() or - TBoundSsa(SsaVariable v) { v.getSourceVariable().getType() instanceof IntegralType } or - TBoundExpr(Expr e) { - interestingExprBound(e) and - not exists(SsaVariable v | e = v.getAUse()) - } +private module BoundImpl = SharedBound::Bound; /** * A bound that may be inferred for an expression plus/minus an integer delta. */ -abstract class Bound extends TBound { - /** Gets a textual representation of this bound. */ - abstract string toString(); - - /** Gets an expression that equals this bound plus `delta`. */ - abstract Expr getExpr(int delta); - - /** Gets an expression that equals this bound. */ - Expr getExpr() { result = this.getExpr(0) } - - /** Gets the location of this bound. */ - abstract Location getLocation(); -} +class Bound = BoundImpl::Bound; /** * The bound that corresponds to the integer 0. This is used to represent all * integer bounds as bounds are always accompanied by an added integer delta. */ -class ZeroBound extends Bound, TBoundZero { - override string toString() { result = "0" } - - override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta } - - override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } -} +class ZeroBound = BoundImpl::ZeroBound; /** * A bound corresponding to the value of an SSA variable. */ -class SsaBound extends Bound, TBoundSsa { - /** Gets the SSA variable that equals this bound. */ - SsaVariable getSsa() { this = TBoundSsa(result) } - - override string toString() { result = this.getSsa().toString() } - - override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 } - - override Location getLocation() { result = this.getSsa().getLocation() } -} +class SsaBound = BoundImpl::SsaBound; /** * A bound that corresponds to the value of a specific expression that might be * interesting, but isn't otherwise represented by the value of an SSA variable. */ -class ExprBound extends Bound, TBoundExpr { - override string toString() { result = this.getExpr().toString() } - - override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 } - - override Location getLocation() { result = this.getExpr().getLocation() } -} +class ExprBound = BoundImpl::ExprBound; \ No newline at end of file diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll index 03742268430..069f0034eed 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll @@ -7,16 +7,26 @@ private import semmle.code.csharp.dataflow.SSA::Ssa as Ssa private import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils as CU private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU - -class SsaVariable = SU::SsaVariable; - -class Expr = CS::ControlFlowNodes::ExprNode; - -class Location = CS::Location; - -class IntegralType = CS::IntegralType; - -class ConstantIntegerExpr = CU::ConstantIntegerExpr; +private import codeql.rangeanalysis.Bound as SharedBound /** Holds if `e` is a bound expression and it is not an SSA variable read. */ -predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.getExpr()) } + + +module BoundDefs implements SharedBound::BoundDefinitions { + class Type = CS::Type; + + class SsaVariable = SU::SsaVariable; + + class SsaSourceVariable = Ssa::SourceVariable; + + class Expr = CS::ControlFlowNodes::ExprNode; + + class IntegralType = CS::IntegralType; + + class ConstantIntegerExpr = CU::ConstantIntegerExpr; + + /** Holds if `e` is a bound expression and it is not an SSA variable read. */ + predicate interestingExprBound(Expr e) { + CU::systemArrayLengthAccess(e.getExpr()) + } +} diff --git a/java/ql/lib/semmle/code/java/dataflow/Bound.qll b/java/ql/lib/semmle/code/java/dataflow/Bound.qll index a1588020838..0cfe3e9039d 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Bound.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Bound.qll @@ -8,12 +8,26 @@ private import java as J private import internal.rangeanalysis.BoundSpecific as BoundSpecific private import codeql.rangeanalysis.Bound as SharedBound -module BoundInstantiation = SharedBound::Bound; +private module BoundImpl = SharedBound::Bound; -class Bound = BoundInstantiation::Bound; +/** + * A bound that may be inferred for an expression plus/minus an integer delta. + */ +class Bound = BoundImpl::Bound; -class ZeroBound = BoundInstantiation::ZeroBound; +/** + * The bound that corresponds to the integer 0. This is used to represent all + * integer bounds as bounds are always accompanied by an added integer delta. + */ +class ZeroBound = BoundImpl::ZeroBound; -class SsaBound = BoundInstantiation::SsaBound; +/** + * A bound corresponding to the value of an SSA variable. + */ +class SsaBound = BoundImpl::SsaBound; -class ExprBound = BoundInstantiation::ExprBound; \ No newline at end of file +/** + * A bound that corresponds to the value of a specific expression that might be + * interesting, but isn't otherwise represented by the value of an SSA variable. + */ +class ExprBound = BoundImpl::ExprBound; \ No newline at end of file From 35faec3db1e18b7aa9858779000b1e1c291bd138 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 27 May 2026 15:27:19 +0000 Subject: [PATCH 123/226] Python: Address review comments - Get rid of unnecessary parentheses - Use call syntax in the relevant test - Get rid of `dead(2)` annotation --- .../evaluation-order/BasicBlockOrdering.expected | 2 +- .../ControlFlow/evaluation-order/NoBackwardFlow.expected | 2 +- .../ControlFlow/evaluation-order/StrictForward.expected | 2 +- .../ControlFlow/evaluation-order/test_basic.py | 8 ++++---- .../ControlFlow/evaluation-order/test_boolean.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.expected index c5ef1ba9394..910fd3c8a80 100644 --- a/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.expected +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/BasicBlockOrdering.expected @@ -1,7 +1,7 @@ | test_boolean.py:9:10:9:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:9:59:9:59 | IntegerLiteral | timestamp 2 | test_boolean.py:9:19:9:19 | IntegerLiteral | timestamp 0 | | test_boolean.py:15:10:15:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:15:50:15:50 | IntegerLiteral | timestamp 1 | test_boolean.py:15:20:15:20 | IntegerLiteral | timestamp 0 | | test_boolean.py:21:10:21:42 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:21:49:21:49 | IntegerLiteral | timestamp 1 | test_boolean.py:21:19:21:19 | IntegerLiteral | timestamp 0 | -| test_boolean.py:27:10:27:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:27:59:27:59 | IntegerLiteral | timestamp 2 | test_boolean.py:27:20:27:20 | IntegerLiteral | timestamp 0 | +| test_boolean.py:27:10:27:34 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:27:50:27:50 | IntegerLiteral | timestamp 2 | test_boolean.py:27:20:27:20 | IntegerLiteral | timestamp 0 | | test_boolean.py:40:10:40:61 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:40:86:40:86 | IntegerLiteral | timestamp 3 | test_boolean.py:40:16:40:16 | IntegerLiteral | timestamp 0 | | test_boolean.py:46:10:46:61 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:46:86:46:86 | IntegerLiteral | timestamp 3 | test_boolean.py:46:16:46:16 | IntegerLiteral | timestamp 0 | | test_boolean.py:52:10:52:95 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:52:120:52:120 | IntegerLiteral | timestamp 4 | test_boolean.py:52:20:52:20 | IntegerLiteral | timestamp 0 | diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.expected index 775cc7bdbbf..6e8ea12c9dd 100644 --- a/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.expected +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/NoBackwardFlow.expected @@ -1,7 +1,7 @@ | test_boolean.py:9:10:9:43 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:9:59:9:59 | IntegerLiteral | 2 | test_boolean.py:9:10:9:13 | ControlFlowNode for True | True | test_boolean.py:9:19:9:19 | IntegerLiteral | 0 | | test_boolean.py:15:10:15:43 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:15:50:15:50 | IntegerLiteral | 1 | test_boolean.py:15:10:15:14 | ControlFlowNode for False | False | test_boolean.py:15:20:15:20 | IntegerLiteral | 0 | | test_boolean.py:21:10:21:42 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:21:49:21:49 | IntegerLiteral | 1 | test_boolean.py:21:10:21:13 | ControlFlowNode for True | True | test_boolean.py:21:19:21:19 | IntegerLiteral | 0 | -| test_boolean.py:27:10:27:43 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:27:59:27:59 | IntegerLiteral | 2 | test_boolean.py:27:10:27:14 | ControlFlowNode for False | False | test_boolean.py:27:20:27:20 | IntegerLiteral | 0 | +| test_boolean.py:27:10:27:34 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:27:50:27:50 | IntegerLiteral | 2 | test_boolean.py:27:10:27:14 | ControlFlowNode for False | False | test_boolean.py:27:20:27:20 | IntegerLiteral | 0 | | test_boolean.py:40:10:40:61 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:40:86:40:86 | IntegerLiteral | 3 | test_boolean.py:40:10:40:10 | ControlFlowNode for IntegerLiteral | IntegerLiteral | test_boolean.py:40:16:40:16 | IntegerLiteral | 0 | | test_boolean.py:46:10:46:61 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:46:86:46:86 | IntegerLiteral | 3 | test_boolean.py:46:10:46:10 | ControlFlowNode for IntegerLiteral | IntegerLiteral | test_boolean.py:46:16:46:16 | IntegerLiteral | 0 | | test_boolean.py:52:10:52:95 | ControlFlowNode for BoolExpr | Backward flow: $@ flows to $@ (max timestamp $@) | test_boolean.py:52:120:52:120 | IntegerLiteral | 4 | test_boolean.py:52:11:52:47 | ControlFlowNode for BoolExpr | BoolExpr | test_boolean.py:52:63:52:63 | IntegerLiteral | 2 | diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.expected b/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.expected index 34e050b0f8a..6562ff9f7b2 100644 --- a/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.expected +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/StrictForward.expected @@ -1,7 +1,7 @@ | test_boolean.py:9:10:9:43 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:9:59:9:59 | IntegerLiteral | timestamp 2 | test_boolean.py:9:19:9:19 | IntegerLiteral | timestamp 0 | | test_boolean.py:15:10:15:43 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:15:50:15:50 | IntegerLiteral | timestamp 1 | test_boolean.py:15:20:15:20 | IntegerLiteral | timestamp 0 | | test_boolean.py:21:10:21:42 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:21:49:21:49 | IntegerLiteral | timestamp 1 | test_boolean.py:21:19:21:19 | IntegerLiteral | timestamp 0 | -| test_boolean.py:27:10:27:43 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:27:59:27:59 | IntegerLiteral | timestamp 2 | test_boolean.py:27:20:27:20 | IntegerLiteral | timestamp 0 | +| test_boolean.py:27:10:27:34 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:27:50:27:50 | IntegerLiteral | timestamp 2 | test_boolean.py:27:20:27:20 | IntegerLiteral | timestamp 0 | | test_boolean.py:40:10:40:61 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:40:86:40:86 | IntegerLiteral | timestamp 3 | test_boolean.py:40:16:40:16 | IntegerLiteral | timestamp 0 | | test_boolean.py:46:10:46:61 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:46:86:46:86 | IntegerLiteral | timestamp 3 | test_boolean.py:46:16:46:16 | IntegerLiteral | timestamp 0 | | test_boolean.py:52:10:52:95 | ControlFlowNode for BoolExpr | Strict forward violation: $@ flows to $@ | test_boolean.py:52:120:52:120 | IntegerLiteral | timestamp 4 | test_boolean.py:52:63:52:63 | IntegerLiteral | timestamp 2 | diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py index b98ebe7b95c..efea733b0d9 100644 --- a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_basic.py @@ -46,7 +46,7 @@ def test_nested_binary(t): @test def test_chained_add(t): """a + b + c is (a + b) + c: left to right.""" - x = ((1 @ t[0] + 2 @ t[1]) @ t[2] + 3 @ t[3]) @ t[4] + x = (1 @ t[0] + 2 @ t[1] + 3 @ t[2]) @ t[3] @test @@ -58,7 +58,7 @@ def test_mixed_precedence(t): @test def test_string_concat(t): """String concatenation operands: left to right.""" - x = (("hello" @ t[0] + " " @ t[1]) @ t[2] + "world" @ t[3]) @ t[4] + x = ("hello" @ t[0] + " " @ t[1] + "world" @ t[2]) @ t[3] @test @@ -142,8 +142,8 @@ def test_multiple_assignment(t): @test def test_callable_syntax(t): """t(value, n) is equivalent to value @ t[n].""" - x = (1 @ t[0] + 2 @ t[1]) @ t[2] - y = (x @ t[3] * 3 @ t[4]) @ t[5] + x = t(t(1, 0) + t(2, 1), 2) + y = t(t(x, 3) * t(3, 4), 5) @test diff --git a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_boolean.py b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_boolean.py index a3b2268a831..a12975634f4 100644 --- a/python/ql/test/library-tests/ControlFlow/evaluation-order/test_boolean.py +++ b/python/ql/test/library-tests/ControlFlow/evaluation-order/test_boolean.py @@ -24,7 +24,7 @@ def test_or_short_circuit(t): @test def test_or_both_sides(t): # False or X — both operands evaluated, result is X - x = (False @ t[0] or 42 @ t[1, dead(2)]) @ t[dead(1), 2] + x = (False @ t[0] or 42 @ t[1]) @ t[dead(1), 2] @test From 4fbea4ef95653911231071a846e41958a0d67579 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 27 May 2026 16:26:22 +0100 Subject: [PATCH 124/226] Swift: Autoformat. --- .../codeql/swift/security/WeakPasswordHashingExtensions.qll | 3 ++- .../swift/security/WeakSensitiveDataHashingExtensions.qll | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll index 8718e031e71..9442812ba2c 100644 --- a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll @@ -125,7 +125,8 @@ private class WeakPasswordHashingMetatypeSink extends WeakPasswordHashingSink { c.getAnArgument().getExpr() = this.asExpr() and algorithm = ["SHA256", "SHA384", "SHA512"] and c.getQualifier().getType().getFullName() = algorithm + ["", ".Type"] and - c.getStaticTarget().getName() = ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] + c.getStaticTarget().getName() = + ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] ) } diff --git a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll index dcb32995747..dbcd0beff7b 100755 --- a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll @@ -90,7 +90,8 @@ private class WeakSenitiveDataHashingMetatypeSink extends WeakSensitiveDataHashi c.getAnArgument().getExpr() = this.asExpr() and algorithm = ["MD5", "SHA1"] and c.getQualifier().getType().getFullName() = "Insecure." + algorithm + ["", ".Type"] and - c.getStaticTarget().getName() = ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] + c.getStaticTarget().getName() = + ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] ) } From 5c2488e304766991c11044e4564d12413feb71db Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 27 May 2026 16:29:48 +0100 Subject: [PATCH 125/226] Swift: Fix typo. --- .../swift/security/WeakSensitiveDataHashingExtensions.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll index dbcd0beff7b..58d9f466b78 100755 --- a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll @@ -71,10 +71,10 @@ private class WeakSensitiveDataHashingSinks extends SinkModelCsv { /** * A sink defined in a CSV model. */ -private class DefaultWeakSenitiveDataHashingSink extends WeakSensitiveDataHashingSink { +private class DefaultWeakSensitiveDataHashingSink extends WeakSensitiveDataHashingSink { string algorithm; - DefaultWeakSenitiveDataHashingSink() { sinkNode(this, "weak-hash-input-" + algorithm) } + DefaultWeakSensitiveDataHashingSink() { sinkNode(this, "weak-hash-input-" + algorithm) } override string getAlgorithm() { result = algorithm } } @@ -82,10 +82,10 @@ private class DefaultWeakSenitiveDataHashingSink extends WeakSensitiveDataHashin /** * A sink for weak sensitive data hashing through a call with a metatype qualifier. */ -private class WeakSenitiveDataHashingMetatypeSink extends WeakSensitiveDataHashingSink { +private class WeakSensitiveDataHashingMetatypeSink extends WeakSensitiveDataHashingSink { string algorithm; - WeakSenitiveDataHashingMetatypeSink() { + WeakSensitiveDataHashingMetatypeSink() { exists(CallExpr c | c.getAnArgument().getExpr() = this.asExpr() and algorithm = ["MD5", "SHA1"] and From cc12740c0e55379ddfdb57be1f62f9322fa06927 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Wed, 27 May 2026 17:41:44 +0200 Subject: [PATCH 126/226] remove check for files in sync --- config/identical-files.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/config/identical-files.json b/config/identical-files.json index 8a5c00a49f8..818f033e4db 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -11,10 +11,6 @@ "java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll" ], - "Bound Java/C#": [ - "java/ql/lib/semmle/code/java/dataflow/Bound.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll" - ], "ModulusAnalysis Java/C#": [ "java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll" From ad56ebd3615131cb34643749e05651f2b6fd4da7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 27 May 2026 21:25:32 +0200 Subject: [PATCH 127/226] Unified: update test output --- unified/ql/test/library-tests/BasicTest/test.expected | 9 --------- 1 file changed, 9 deletions(-) diff --git a/unified/ql/test/library-tests/BasicTest/test.expected b/unified/ql/test/library-tests/BasicTest/test.expected index 1d6bb8def2b..5298ec6f982 100644 --- a/unified/ql/test/library-tests/BasicTest/test.expected +++ b/unified/ql/test/library-tests/BasicTest/test.expected @@ -1,18 +1,9 @@ nameExpr -| name_expr.swift:1:9:1:9 | NameExpr | y | unsupported -| test.swift:1:1:1:17 | | | | test.swift:3:1:3:38 | | | -| test.swift:4:1:14:1 | | | | test.swift:16:1:16:32 | | | -| test.swift:17:1:21:1 | | | | test.swift:23:1:23:37 | | | -| test.swift:24:1:32:1 | | | | test.swift:34:1:34:49 | | | -| test.swift:35:1:55:1 | | | | test.swift:57:1:57:30 | | | -| test.swift:58:1:70:1 | | | | test.swift:72:1:72:37 | | | -| test.swift:73:1:82:1 | | | | test.swift:84:1:84:24 | | | -| test.swift:85:1:88:1 | | | From 313500e5812c00a6b7069f4eee07b1de70d401f8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 27 May 2026 21:27:09 +0200 Subject: [PATCH 128/226] Unified: update test outputs --- .../extractor/tests/corpus/swift/closures.txt | 363 ++++----- .../tests/corpus/swift/collections.txt | 351 ++++----- .../tests/corpus/swift/control-flow.txt | 605 +++++++------- .../extractor/tests/corpus/swift/desugar.txt | 30 +- .../tests/corpus/swift/functions.txt | 423 +++++----- .../extractor/tests/corpus/swift/literals.txt | 46 +- .../extractor/tests/corpus/swift/loops.txt | 272 ++++--- .../tests/corpus/swift/operators.txt | 221 ++---- .../corpus/swift/optionals-and-errors.txt | 316 ++++---- .../extractor/tests/corpus/swift/types.txt | 741 ++++++++++-------- .../tests/corpus/swift/variables.txt | 236 +++--- 11 files changed, 1838 insertions(+), 1766 deletions(-) diff --git a/unified/extractor/tests/corpus/swift/closures.txt b/unified/extractor/tests/corpus/swift/closures.txt index 57dbfe79381..0afea480a19 100644 --- a/unified/extractor/tests/corpus/swift/closures.txt +++ b/unified/extractor/tests/corpus/swift/closures.txt @@ -7,54 +7,49 @@ let f = { (x: Int) -> Int in x * 2 } --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "f" - value: - lambda_literal - type: - lambda_function_type - return_type: - type - name: - user_type - type_identifier "Int" - lambda_function_type_parameters - lambda_parameter - name: simple_identifier "x" - type: - type - name: - user_type - type_identifier "Int" - statements - multiplicative_expression - lhs: simple_identifier "x" - op: * - rhs: integer_literal "2" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + statement: + multiplicative_expression + lhs: simple_identifier "x" + op: * + rhs: integer_literal "2" + type: + lambda_function_type + params: + lambda_function_type_parameters + parameter: + lambda_parameter + name: simple_identifier "x" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + return_type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: - lambda_expr - body: - binary_expr - operator: operator "*" - left: - name_expr - identifier: identifier "x" - right: int_literal "2" - pattern: - var_pattern - identifier: identifier "f" === Closure with shorthand parameters @@ -65,41 +60,28 @@ let f = { $0 + $1 } --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "f" - value: - lambda_literal - statements - additive_expression - lhs: simple_identifier "$0" - op: + - rhs: simple_identifier "$1" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + statement: + additive_expression + lhs: simple_identifier "$0" + op: + + rhs: simple_identifier "$1" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: - lambda_expr - body: - binary_expr - operator: operator "+" - left: - name_expr - identifier: identifier "$0" - right: - name_expr - identifier: identifier "$1" - pattern: - var_pattern - identifier: identifier "f" === Trailing closure @@ -110,40 +92,28 @@ xs.map { $0 * 2 } --- source_file - call_expression - navigation_expression + statement: + call_expression + function: + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "map" + target: simple_identifier "xs" suffix: - navigation_suffix - suffix: simple_identifier "map" - target: simple_identifier "xs" - call_suffix - lambda_literal - statements - multiplicative_expression - lhs: simple_identifier "$0" - op: * - rhs: integer_literal "2" + call_suffix + lambda: + lambda_literal + statement: + multiplicative_expression + lhs: simple_identifier "$0" + op: * + rhs: integer_literal "2" --- top_level body: - call_expr - argument: - lambda_expr - body: - binary_expr - operator: operator "*" - left: - name_expr - identifier: identifier "$0" - right: int_literal "2" - function: - member_access_expr - target: - name_expr - identifier: identifier "xs" - member: identifier "map" === Closure with capture list @@ -154,50 +124,45 @@ let f = { [weak self] in self?.doThing() } --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "f" - value: - lambda_literal - captures: - capture_list - capture_list_item - name: simple_identifier "self" - ownership_modifier - statements - call_expression - navigation_expression - suffix: - navigation_suffix - suffix: simple_identifier "doThing" - target: - optional_chain_marker - self_expression - call_suffix - value_arguments - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + captures: + capture_list + item: + capture_list_item + name: simple_identifier "self" + ownership: + ownership_modifier + statement: + call_expression + function: + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "doThing" + target: + optional_chain_marker + expr: + self_expression + suffix: + call_suffix + arguments: + value_arguments --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: - lambda_expr - body: - call_expr - argument: - function: - member_access_expr - target: unsupported_node "self?" - member: identifier "doThing" - pattern: - var_pattern - identifier: identifier "f" === Multi-statement closure @@ -211,71 +176,63 @@ let f = { (x: Int) -> Int in --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "f" - value: - lambda_literal - type: - lambda_function_type - return_type: - type - name: - user_type - type_identifier "Int" - lambda_function_type_parameters - lambda_parameter - name: simple_identifier "x" - type: - type - name: - user_type - type_identifier "Int" - statements - property_declaration - name: - pattern - bound_identifier: simple_identifier "y" - value: - additive_expression - lhs: simple_identifier "x" - op: + - rhs: integer_literal "1" - value_binding_pattern - mutability: let - control_transfer_statement - result: - multiplicative_expression - lhs: simple_identifier "y" - op: * - rhs: integer_literal "2" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "f" + value: + lambda_literal + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "y" + value: + additive_expression + lhs: simple_identifier "x" + op: + + rhs: integer_literal "1" + control_transfer_statement + kind: return + result: + multiplicative_expression + lhs: simple_identifier "y" + op: * + rhs: integer_literal "2" + type: + lambda_function_type + params: + lambda_function_type_parameters + parameter: + lambda_parameter + name: simple_identifier "x" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + return_type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: - lambda_expr - body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: - binary_expr - operator: operator "+" - left: - name_expr - identifier: identifier "x" - right: int_literal "1" - pattern: - var_pattern - identifier: identifier "y" - pattern: - var_pattern - identifier: identifier "f" diff --git a/unified/extractor/tests/corpus/swift/collections.txt b/unified/extractor/tests/corpus/swift/collections.txt index 9a1186ac77d..afafc1e69ef 100644 --- a/unified/extractor/tests/corpus/swift/collections.txt +++ b/unified/extractor/tests/corpus/swift/collections.txt @@ -7,30 +7,27 @@ let xs = [1, 2, 3] --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "xs" - value: - array_literal - element: - integer_literal "1" - integer_literal "2" - integer_literal "3" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "xs" + value: + array_literal + element: + integer_literal "1" + integer_literal "2" + integer_literal "3" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "[1, 2, 3]" - pattern: - var_pattern - identifier: identifier "xs" === Empty array literal with type @@ -41,36 +38,36 @@ let xs: [Int] = [] --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "xs" - value: - array_literal - value_binding_pattern - mutability: let - type_annotation - type: - type + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding name: - array_type - element: + pattern + bound_identifier: simple_identifier "xs" + type: + type_annotation + type: type name: - user_type - type_identifier "Int" + array_type + element: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + value: + array_literal --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "[]" - pattern: - var_pattern - identifier: identifier "xs" === Dictionary literal @@ -81,34 +78,34 @@ let d = ["a": 1, "b": 2] --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "d" - value: - dictionary_literal - key: - line_string_literal - text: line_str_text "a" - line_string_literal - text: line_str_text "b" - value: - integer_literal "1" - integer_literal "2" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "d" + value: + dictionary_literal + element: + dictionary_literal_item + key: + line_string_literal + text: line_str_text "a" + value: integer_literal "1" + dictionary_literal_item + key: + line_string_literal + text: line_str_text "b" + value: integer_literal "2" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "[\"a\": 1, \"b\": 2]" - pattern: - var_pattern - identifier: identifier "d" === Set literal @@ -119,41 +116,45 @@ let s: Set = [1, 2, 3] --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "s" - value: - array_literal - element: - integer_literal "1" - integer_literal "2" - integer_literal "3" - value_binding_pattern - mutability: let - type_annotation - type: - type + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding name: - user_type - type_identifier "Set" - type_arguments + pattern + bound_identifier: simple_identifier "s" + type: + type_annotation + type: type name: user_type - type_identifier "Int" + part: + simple_user_type + arguments: + type_arguments + argument: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + name: type_identifier "Set" + value: + array_literal + element: + integer_literal "1" + integer_literal "2" + integer_literal "3" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "[1, 2, 3]" - pattern: - var_pattern - identifier: identifier "s" === Tuple literal @@ -164,31 +165,32 @@ let t = (1, "two", 3.0) --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "t" - value: - tuple_expression - value: - integer_literal "1" - line_string_literal - text: line_str_text "two" - real_literal "3.0" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "t" + value: + tuple_expression + element: + tuple_expression_item + value: integer_literal "1" + tuple_expression_item + value: + line_string_literal + text: line_str_text "two" + tuple_expression_item + value: real_literal "3.0" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "(1, \"two\", 3.0)" - pattern: - var_pattern - identifier: identifier "t" === Subscript access @@ -202,22 +204,29 @@ let first = xs[0] --- source_file + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "first" + value: + call_expression + function: simple_identifier "xs" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: integer_literal "0" comment "// TODO: tree-sitter-swift parses `xs[0]` as a call_expression (same shape" comment "// as `xs(0)`), so the mapping currently produces a call_expr. Update the" comment "// parser / add a separate subscript_expr node and remap when fixed." - property_declaration - name: - pattern - bound_identifier: simple_identifier "first" - value: - call_expression - simple_identifier "xs" - call_suffix - value_arguments - value_argument - value: integer_literal "0" - value_binding_pattern - mutability: let --- @@ -226,18 +235,6 @@ top_level unsupported_node "// TODO: tree-sitter-swift parses `xs[0]` as a call_expression (same shape" unsupported_node "// as `xs(0)`), so the mapping currently produces a call_expr. Update the" unsupported_node "// parser / add a separate subscript_expr node and remap when fixed." - variable_declaration_stmt - variable_declarator: - variable_declarator - value: - call_expr - argument: int_literal "0" - function: - name_expr - identifier: identifier "xs" - pattern: - var_pattern - identifier: identifier "first" === Dictionary subscript @@ -250,23 +247,30 @@ let v = d["key"] --- source_file + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "v" + value: + call_expression + function: simple_identifier "d" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: + line_string_literal + text: line_str_text "key" comment "// TODO: same parser issue as the array subscript case above —" comment "// `d[\"key\"]` is parsed as `call_expression(d, (\"key\"))`." - property_declaration - name: - pattern - bound_identifier: simple_identifier "v" - value: - call_expression - simple_identifier "d" - call_suffix - value_arguments - value_argument - value: - line_string_literal - text: line_str_text "key" - value_binding_pattern - mutability: let --- @@ -274,18 +278,6 @@ top_level body: unsupported_node "// TODO: same parser issue as the array subscript case above —" unsupported_node "// `d[\"key\"]` is parsed as `call_expression(d, (\"key\"))`." - variable_declaration_stmt - variable_declarator: - variable_declarator - value: - call_expr - argument: string_literal "\"key\"" - function: - name_expr - identifier: identifier "d" - pattern: - var_pattern - identifier: identifier "v" === Tuple member access @@ -296,27 +288,24 @@ let n = t.0 --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "n" - value: - navigation_expression - suffix: - navigation_suffix - suffix: integer_literal "0" - target: simple_identifier "t" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "n" + value: + navigation_expression + suffix: + navigation_suffix + suffix: integer_literal "0" + target: simple_identifier "t" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "t.0" - pattern: - var_pattern - identifier: identifier "n" diff --git a/unified/extractor/tests/corpus/swift/control-flow.txt b/unified/extractor/tests/corpus/swift/control-flow.txt index f8526183d4d..600e1126cbf 100644 --- a/unified/extractor/tests/corpus/swift/control-flow.txt +++ b/unified/extractor/tests/corpus/swift/control-flow.txt @@ -9,41 +9,32 @@ if x > 0 { --- source_file - if_statement - condition: - if_condition - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "x" + statement: + if_statement + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "x" + condition: + if_condition + kind: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" --- top_level body: - if_stmt - condition: - expr_condition - expr: unsupported_node "x > 0" - then: - block_stmt - body: - expr_stmt - expr: - call_expr - argument: - name_expr - identifier: identifier "x" - function: - name_expr - identifier: identifier "print" === If-else @@ -58,67 +49,47 @@ if x > 0 { --- source_file - if_statement - condition: - if_condition - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "x" - else "else" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: - prefix_expression - operation: - - target: simple_identifier "x" + statement: + if_statement + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "x" + condition: + if_condition + kind: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + else_branch: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: + prefix_expression + operation: - + target: simple_identifier "x" --- top_level body: - if_stmt - condition: - expr_condition - expr: unsupported_node "x > 0" - else: - block_stmt - body: - expr_stmt - expr: - call_expr - argument: - unary_expr - operator: operator "-" - operand: - name_expr - identifier: identifier "x" - function: - name_expr - identifier: identifier "print" - then: - block_stmt - body: - expr_stmt - expr: - call_expr - argument: - name_expr - identifier: identifier "x" - function: - name_expr - identifier: identifier "print" === If-else-if chain @@ -135,87 +106,65 @@ if x > 0 { --- source_file - if_statement - condition: - if_condition - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: integer_literal "1" - else "else" + statement: if_statement + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: integer_literal "1" condition: if_condition - comparison_expression - lhs: simple_identifier "x" - op: < - rhs: integer_literal "0" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: integer_literal "2" - else "else" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: integer_literal "3" + kind: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + else_branch: + if_statement + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: integer_literal "2" + condition: + if_condition + kind: + comparison_expression + lhs: simple_identifier "x" + op: < + rhs: integer_literal "0" + else_branch: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: integer_literal "3" --- top_level body: - if_stmt - condition: - expr_condition - expr: unsupported_node "x > 0" - else: - if_stmt - condition: - expr_condition - expr: unsupported_node "x < 0" - else: - block_stmt - body: - expr_stmt - expr: - call_expr - argument: int_literal "3" - function: - name_expr - identifier: identifier "print" - then: - block_stmt - body: - expr_stmt - expr: - call_expr - argument: int_literal "2" - function: - name_expr - identifier: identifier "print" - then: - block_stmt - body: - expr_stmt - expr: - call_expr - argument: int_literal "1" - function: - name_expr - identifier: identifier "print" === If-let optional binding @@ -228,42 +177,36 @@ if let value = optional { --- source_file - if_statement - condition: - if_condition - if_let_binding - bound_identifier: simple_identifier "value" - value_binding_pattern - mutability: let - simple_identifier "optional" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "value" + statement: + if_statement + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "value" + condition: + if_condition + kind: + if_let_binding + pattern: + pattern + binding: + value_binding_pattern + mutability: let + bound_identifier: simple_identifier "value" + value: simple_identifier "optional" --- top_level body: - if_stmt - condition: - expr_condition - expr: unsupported_node "let value = optional" - then: - block_stmt - body: - expr_stmt - expr: - call_expr - argument: - name_expr - identifier: identifier "value" - function: - name_expr - identifier: identifier "print" === Guard let @@ -274,22 +217,29 @@ guard let value = optional else { return } --- source_file - guard_statement - condition: - if_condition - if_let_binding - bound_identifier: simple_identifier "value" - value_binding_pattern - mutability: let - simple_identifier "optional" - else "else" - statements - control_transfer_statement + statement: + guard_statement + body: + block + statement: + control_transfer_statement + kind: return + condition: + if_condition + kind: + if_let_binding + pattern: + pattern + binding: + value_binding_pattern + mutability: let + bound_identifier: simple_identifier "value" + value: simple_identifier "optional" --- top_level - body: unsupported_node "guard let value = optional else { return }" + body: === Ternary expression @@ -300,36 +250,33 @@ let y = x > 0 ? 1 : -1 --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "y" - value: - ternary_expression - condition: - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" - if_false: - prefix_expression - operation: - - target: integer_literal "1" - if_true: integer_literal "1" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "y" + value: + ternary_expression + condition: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + if_false: + prefix_expression + operation: - + target: integer_literal "1" + if_true: integer_literal "1" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "x > 0 ? 1 : -1" - pattern: - var_pattern - identifier: identifier "y" === Switch statement @@ -347,53 +294,69 @@ default: --- source_file - switch_statement - expr: simple_identifier "x" - switch_entry - switch_pattern - pattern - integer_literal "1" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: - line_string_literal - text: line_str_text "one" - switch_entry - switch_pattern - pattern - integer_literal "2" - switch_pattern - pattern - integer_literal "3" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: - line_string_literal - text: line_str_text "two or three" - switch_entry - default_keyword "default" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: - line_string_literal - text: line_str_text "other" + statement: + switch_statement + entry: + switch_entry + pattern: + switch_pattern + pattern: + pattern + kind: integer_literal "1" + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: + line_string_literal + text: line_str_text "one" + switch_entry + pattern: + switch_pattern + pattern: + pattern + kind: integer_literal "2" + switch_pattern + pattern: + pattern + kind: integer_literal "3" + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: + line_string_literal + text: line_str_text "two or three" + switch_entry + default: default_keyword "default" + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: + line_string_literal + text: line_str_text "other" + expr: simple_identifier "x" --- top_level - body: unsupported_node "switch x {\ncase 1:\n print(\"one\")\ncase 2, 3:\n print(\"two or three\")\ndefault:\n print(\"other\")\n}" + body: === Switch with binding pattern @@ -409,40 +372,76 @@ case .square(let s): --- source_file - switch_statement - expr: simple_identifier "shape" - switch_entry - switch_pattern - pattern - simple_identifier "circle" - pattern - bound_identifier: simple_identifier "r" - value_binding_pattern - mutability: let - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "r" - switch_entry - switch_pattern - pattern - simple_identifier "square" - pattern - bound_identifier: simple_identifier "s" - value_binding_pattern - mutability: let - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "s" + statement: + switch_statement + entry: + switch_entry + pattern: + switch_pattern + pattern: + pattern + kind: + case_pattern + arguments: + tuple_pattern + item: + tuple_pattern_item + pattern: + pattern + kind: + binding_pattern + binding: + value_binding_pattern + mutability: let + pattern: + pattern + bound_identifier: simple_identifier "r" + name: simple_identifier "circle" + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "r" + switch_entry + pattern: + switch_pattern + pattern: + pattern + kind: + case_pattern + arguments: + tuple_pattern + item: + tuple_pattern_item + pattern: + pattern + kind: + binding_pattern + binding: + value_binding_pattern + mutability: let + pattern: + pattern + bound_identifier: simple_identifier "s" + name: simple_identifier "square" + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "s" + expr: simple_identifier "shape" --- top_level - body: unsupported_node "switch shape {\ncase .circle(let r):\n print(r)\ncase .square(let s):\n print(s)\n}" + body: diff --git a/unified/extractor/tests/corpus/swift/desugar.txt b/unified/extractor/tests/corpus/swift/desugar.txt index 4e0defef022..9f9ffeb070a 100644 --- a/unified/extractor/tests/corpus/swift/desugar.txt +++ b/unified/extractor/tests/corpus/swift/desugar.txt @@ -7,19 +7,16 @@ Additive expression is desugared --- source_file - additive_expression - lhs: integer_literal "1" - op: + - rhs: integer_literal "2" + statement: + additive_expression + lhs: integer_literal "1" + op: + + rhs: integer_literal "2" --- top_level body: - binary_expr - operator: operator "+" - left: int_literal "1" - right: int_literal "2" === Another additive expression is desugared @@ -30,20 +27,13 @@ foo + bar --- source_file - additive_expression - lhs: simple_identifier "foo" - op: + - rhs: simple_identifier "bar" + statement: + additive_expression + lhs: simple_identifier "foo" + op: + + rhs: simple_identifier "bar" --- top_level body: - binary_expr - operator: operator "+" - left: - name_expr - identifier: identifier "foo" - right: - name_expr - identifier: identifier "bar" diff --git a/unified/extractor/tests/corpus/swift/functions.txt b/unified/extractor/tests/corpus/swift/functions.txt index 3329a6255f3..0a8210a4cf7 100644 --- a/unified/extractor/tests/corpus/swift/functions.txt +++ b/unified/extractor/tests/corpus/swift/functions.txt @@ -9,24 +9,28 @@ func greet() { --- source_file - function_declaration - body: - function_body - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: - line_string_literal - text: line_str_text "hello" - name: simple_identifier "greet" + statement: + function_declaration + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: + line_string_literal + text: line_str_text "hello" + name: simple_identifier "greet" --- top_level - body: unsupported_node "func greet() {\n print(\"hello\")\n}" + body: === Function with parameters and return type @@ -39,43 +43,56 @@ func add(_ a: Int, _ b: Int) -> Int { --- source_file - function_declaration - body: - function_body - statements - control_transfer_statement - result: - additive_expression - lhs: simple_identifier "a" - op: + - rhs: simple_identifier "b" - name: simple_identifier "add" - return_type: - type - name: - user_type - type_identifier "Int" - parameter - external_name: simple_identifier "_" - name: simple_identifier "a" - type: + statement: + function_declaration + body: + block + statement: + control_transfer_statement + kind: return + result: + additive_expression + lhs: simple_identifier "a" + op: + + rhs: simple_identifier "b" + name: simple_identifier "add" + parameter: + function_parameter + parameter: + parameter + external_name: simple_identifier "_" + name: simple_identifier "a" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + function_parameter + parameter: + parameter + external_name: simple_identifier "_" + name: simple_identifier "b" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + return_type: type name: user_type - type_identifier "Int" - parameter - external_name: simple_identifier "_" - name: simple_identifier "b" - type: - type - name: - user_type - type_identifier "Int" + part: + simple_user_type + name: type_identifier "Int" --- top_level - body: unsupported_node "func add(_ a: Int, _ b: Int) -> Int {\n return a + b\n}" + body: === Function with named parameters @@ -88,30 +105,39 @@ func greet(person name: String) { --- source_file - function_declaration - body: - function_body - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "name" - name: simple_identifier "greet" - parameter - external_name: simple_identifier "person" - name: simple_identifier "name" - type: - type - name: - user_type - type_identifier "String" + statement: + function_declaration + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "name" + name: simple_identifier "greet" + parameter: + function_parameter + parameter: + parameter + external_name: simple_identifier "person" + name: simple_identifier "name" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "String" --- top_level - body: unsupported_node "func greet(person name: String) {\n print(name)\n}" + body: === Function with default parameter value @@ -124,32 +150,41 @@ func greet(name: String = "world") { --- source_file - function_declaration - body: - function_body - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "name" - default_value: - line_string_literal - text: line_str_text "world" - name: simple_identifier "greet" - parameter - name: simple_identifier "name" - type: - type - name: - user_type - type_identifier "String" + statement: + function_declaration + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "name" + name: simple_identifier "greet" + parameter: + function_parameter + default_value: + line_string_literal + text: line_str_text "world" + parameter: + parameter + name: simple_identifier "name" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "String" --- top_level - body: unsupported_node "func greet(name: String = \"world\") {\n print(name)\n}" + body: === Variadic function @@ -162,44 +197,58 @@ func sum(_ values: Int...) -> Int { --- source_file - function_declaration - body: - function_body - statements - control_transfer_statement - result: - call_expression - navigation_expression + statement: + function_declaration + body: + block + statement: + control_transfer_statement + kind: return + result: + call_expression + function: + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "reduce" + target: simple_identifier "values" suffix: - navigation_suffix - suffix: simple_identifier "reduce" - target: simple_identifier "values" - call_suffix - value_arguments - value_argument - value: integer_literal "0" - value_argument - value: - referenceable_operator - name: simple_identifier "sum" - return_type: - type - name: - user_type - type_identifier "Int" - parameter - external_name: simple_identifier "_" - name: simple_identifier "values" - type: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: integer_literal "0" + value_argument + value: + referenceable_operator + operator: + + name: simple_identifier "sum" + parameter: + function_parameter + parameter: + parameter + external_name: simple_identifier "_" + name: simple_identifier "values" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + return_type: type name: user_type - type_identifier "Int" + part: + simple_user_type + name: type_identifier "Int" --- top_level - body: unsupported_node "func sum(_ values: Int...) -> Int {\n return values.reduce(0, +)\n}" + body: === Function call @@ -210,26 +259,23 @@ foo(1, 2) --- source_file - call_expression - simple_identifier "foo" - call_suffix - value_arguments - value_argument - value: integer_literal "1" - value_argument - value: integer_literal "2" + statement: + call_expression + function: simple_identifier "foo" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: integer_literal "1" + value_argument + value: integer_literal "2" --- top_level body: - call_expr - argument: - int_literal "1" - int_literal "2" - function: - name_expr - identifier: identifier "foo" === Function call with labelled arguments @@ -240,27 +286,26 @@ greet(person: "Bob") --- source_file - call_expression - simple_identifier "greet" - call_suffix - value_arguments - value_argument - name: - value_argument_label - simple_identifier "person" - value: - line_string_literal - text: line_str_text "Bob" + statement: + call_expression + function: simple_identifier "greet" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + name: + value_argument_label + name: simple_identifier "person" + value: + line_string_literal + text: line_str_text "Bob" --- top_level body: - call_expr - argument: string_literal "\"Bob\"" - function: - name_expr - identifier: identifier "greet" === Method call @@ -271,29 +316,26 @@ list.append(1) --- source_file - call_expression - navigation_expression + statement: + call_expression + function: + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "append" + target: simple_identifier "list" suffix: - navigation_suffix - suffix: simple_identifier "append" - target: simple_identifier "list" - call_suffix - value_arguments - value_argument - value: integer_literal "1" + call_suffix + arguments: + value_arguments + argument: + value_argument + value: integer_literal "1" --- top_level body: - call_expr - argument: int_literal "1" - function: - member_access_expr - target: - name_expr - identifier: identifier "list" - member: identifier "append" === Generic function @@ -306,31 +348,42 @@ func identity(_ x: T) -> T { --- source_file - function_declaration - body: - function_body - statements - control_transfer_statement - result: simple_identifier "x" - name: simple_identifier "identity" - return_type: - type - name: - user_type - type_identifier "T" - type_parameters - type_parameter - type_identifier "T" - parameter - external_name: simple_identifier "_" - name: simple_identifier "x" - type: + statement: + function_declaration + body: + block + statement: + control_transfer_statement + kind: return + result: simple_identifier "x" + name: simple_identifier "identity" + parameter: + function_parameter + parameter: + parameter + external_name: simple_identifier "_" + name: simple_identifier "x" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "T" + return_type: type name: user_type - type_identifier "T" + part: + simple_user_type + name: type_identifier "T" + type_parameters: + type_parameters + parameter: + type_parameter + name: type_identifier "T" --- top_level - body: unsupported_node "func identity(_ x: T) -> T {\n return x\n}" + body: diff --git a/unified/extractor/tests/corpus/swift/literals.txt b/unified/extractor/tests/corpus/swift/literals.txt index 5f44733e136..5044831a869 100644 --- a/unified/extractor/tests/corpus/swift/literals.txt +++ b/unified/extractor/tests/corpus/swift/literals.txt @@ -7,12 +7,12 @@ Integer literal --- source_file - integer_literal "42" + statement: integer_literal "42" --- top_level - body: int_literal "42" + body: === Negative integer literal @@ -23,17 +23,15 @@ Negative integer literal --- source_file - prefix_expression - operation: - - target: integer_literal "7" + statement: + prefix_expression + operation: - + target: integer_literal "7" --- top_level body: - unary_expr - operator: operator "-" - operand: int_literal "7" === Floating-point literal @@ -44,12 +42,12 @@ Floating-point literal --- source_file - real_literal "3.14" + statement: real_literal "3.14" --- top_level - body: unsupported_node "3.14" + body: === Boolean literals @@ -61,15 +59,14 @@ false --- source_file - boolean_literal - boolean_literal + statement: + boolean_literal + boolean_literal --- top_level body: - unsupported_node "true" - unsupported_node "false" === Nil literal @@ -80,6 +77,7 @@ nil --- source_file + statement: nil --- @@ -95,13 +93,14 @@ String literal --- source_file - line_string_literal - text: line_str_text "hello" + statement: + line_string_literal + text: line_str_text "hello" --- top_level - body: string_literal "\"hello\"" + body: === String with interpolation @@ -112,13 +111,14 @@ String with interpolation --- source_file - line_string_literal - interpolation: - interpolated_expression - value: simple_identifier "name" - text: line_str_text "hello " + statement: + line_string_literal + interpolation: + interpolated_expression + value: simple_identifier "name" + text: line_str_text "hello " --- top_level - body: string_literal "\"hello \\(name)\"" + body: diff --git a/unified/extractor/tests/corpus/swift/loops.txt b/unified/extractor/tests/corpus/swift/loops.txt index 62d0d097bb0..8b9f3410d35 100644 --- a/unified/extractor/tests/corpus/swift/loops.txt +++ b/unified/extractor/tests/corpus/swift/loops.txt @@ -9,28 +9,34 @@ for x in [1, 2, 3] { --- source_file - for_statement - collection: - array_literal - element: - integer_literal "1" - integer_literal "2" - integer_literal "3" - item: - pattern - bound_identifier: simple_identifier "x" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "x" + statement: + for_statement + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "x" + collection: + array_literal + element: + integer_literal "1" + integer_literal "2" + integer_literal "3" + item: + pattern + bound_identifier: simple_identifier "x" --- top_level - body: unsupported_node "for x in [1, 2, 3] {\n print(x)\n}" + body: === For-in over range @@ -43,27 +49,33 @@ for i in 0..<10 { --- source_file - for_statement - collection: - range_expression - end: integer_literal "10" - op: ..< - start: integer_literal "0" - item: - pattern - bound_identifier: simple_identifier "i" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "i" + statement: + for_statement + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "i" + collection: + range_expression + end: integer_literal "10" + op: ..< + start: integer_literal "0" + item: + pattern + bound_identifier: simple_identifier "i" --- top_level - body: unsupported_node "for i in 0..<10 {\n print(i)\n}" + body: === For-in with where clause @@ -76,29 +88,37 @@ for x in xs where x > 0 { --- source_file - for_statement - collection: simple_identifier "xs" - item: - pattern - bound_identifier: simple_identifier "x" - where_clause - where_keyword "where" - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "x" + statement: + for_statement + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "x" + collection: simple_identifier "xs" + item: + pattern + bound_identifier: simple_identifier "x" + where: + where_clause + expr: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" + keyword: where_keyword "where" --- top_level - body: unsupported_node "for x in xs where x > 0 {\n print(x)\n}" + body: === While loop @@ -111,25 +131,29 @@ while x > 0 { --- source_file - while_statement - condition: - if_condition - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" - statements - assignment - operator: -= - result: integer_literal "1" - target: - directly_assignable_expression - simple_identifier "x" + statement: + while_statement + body: + block + statement: + assignment + operator: -= + result: integer_literal "1" + target: + directly_assignable_expression + expr: simple_identifier "x" + condition: + if_condition + kind: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" --- top_level - body: unsupported_node "while x > 0 {\n x -= 1\n}" + body: === Repeat-while loop @@ -142,25 +166,29 @@ repeat { --- source_file - repeat_while_statement - condition: - if_condition - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "0" - statements - assignment - operator: -= - result: integer_literal "1" - target: - directly_assignable_expression - simple_identifier "x" + statement: + repeat_while_statement + body: + block + statement: + assignment + operator: -= + result: integer_literal "1" + target: + directly_assignable_expression + expr: simple_identifier "x" + condition: + if_condition + kind: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "0" --- top_level - body: unsupported_node "repeat {\n x -= 1\n} while x > 0" + body: === Break and continue @@ -175,38 +203,52 @@ for x in xs { --- source_file - for_statement - collection: simple_identifier "xs" - item: - pattern - bound_identifier: simple_identifier "x" - statements - if_statement - condition: - if_condition - comparison_expression - lhs: simple_identifier "x" - op: < - rhs: integer_literal "0" - statements - control_transfer_statement - if_statement - condition: - if_condition - comparison_expression - lhs: simple_identifier "x" - op: > - rhs: integer_literal "100" - statements - control_transfer_statement - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "x" + statement: + for_statement + body: + block + statement: + if_statement + body: + block + statement: + control_transfer_statement + kind: continue + condition: + if_condition + kind: + comparison_expression + lhs: simple_identifier "x" + op: < + rhs: integer_literal "0" + if_statement + body: + block + statement: + control_transfer_statement + kind: break + condition: + if_condition + kind: + comparison_expression + lhs: simple_identifier "x" + op: > + rhs: integer_literal "100" + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "x" + collection: simple_identifier "xs" + item: + pattern + bound_identifier: simple_identifier "x" --- top_level - body: unsupported_node "for x in xs {\n if x < 0 { continue }\n if x > 100 { break }\n print(x)\n}" + body: diff --git a/unified/extractor/tests/corpus/swift/operators.txt b/unified/extractor/tests/corpus/swift/operators.txt index 173f6e92976..f1a4a5fcdb2 100644 --- a/unified/extractor/tests/corpus/swift/operators.txt +++ b/unified/extractor/tests/corpus/swift/operators.txt @@ -7,23 +7,16 @@ a + b --- source_file - additive_expression - lhs: simple_identifier "a" - op: + - rhs: simple_identifier "b" + statement: + additive_expression + lhs: simple_identifier "a" + op: + + rhs: simple_identifier "b" --- top_level body: - binary_expr - operator: operator "+" - left: - name_expr - identifier: identifier "a" - right: - name_expr - identifier: identifier "b" === Subtraction @@ -34,23 +27,16 @@ a - b --- source_file - additive_expression - lhs: simple_identifier "a" - op: - - rhs: simple_identifier "b" + statement: + additive_expression + lhs: simple_identifier "a" + op: - + rhs: simple_identifier "b" --- top_level body: - binary_expr - operator: operator "-" - left: - name_expr - identifier: identifier "a" - right: - name_expr - identifier: identifier "b" === Multiplication @@ -61,23 +47,16 @@ a * b --- source_file - multiplicative_expression - lhs: simple_identifier "a" - op: * - rhs: simple_identifier "b" + statement: + multiplicative_expression + lhs: simple_identifier "a" + op: * + rhs: simple_identifier "b" --- top_level body: - binary_expr - operator: operator "*" - left: - name_expr - identifier: identifier "a" - right: - name_expr - identifier: identifier "b" === Division @@ -88,23 +67,16 @@ a / b --- source_file - multiplicative_expression - lhs: simple_identifier "a" - op: / - rhs: simple_identifier "b" + statement: + multiplicative_expression + lhs: simple_identifier "a" + op: / + rhs: simple_identifier "b" --- top_level body: - binary_expr - operator: operator "/" - left: - name_expr - identifier: identifier "a" - right: - name_expr - identifier: identifier "b" === Operator precedence: addition and multiplication @@ -115,33 +87,20 @@ a + b * c --- source_file - additive_expression - lhs: simple_identifier "a" - op: + - rhs: - multiplicative_expression - lhs: simple_identifier "b" - op: * - rhs: simple_identifier "c" + statement: + additive_expression + lhs: simple_identifier "a" + op: + + rhs: + multiplicative_expression + lhs: simple_identifier "b" + op: * + rhs: simple_identifier "c" --- top_level body: - binary_expr - operator: operator "+" - left: - name_expr - identifier: identifier "a" - right: - binary_expr - operator: operator "*" - left: - name_expr - identifier: identifier "b" - right: - name_expr - identifier: identifier "c" === Parenthesised expression @@ -152,27 +111,24 @@ Parenthesised expression --- source_file - multiplicative_expression - lhs: - tuple_expression - value: - additive_expression - lhs: simple_identifier "a" - op: + - rhs: simple_identifier "b" - op: * - rhs: simple_identifier "c" + statement: + multiplicative_expression + lhs: + tuple_expression + element: + tuple_expression_item + value: + additive_expression + lhs: simple_identifier "a" + op: + + rhs: simple_identifier "b" + op: * + rhs: simple_identifier "c" --- top_level body: - binary_expr - operator: operator "*" - left: unsupported_node "(a + b)" - right: - name_expr - identifier: identifier "c" === Comparison @@ -183,23 +139,16 @@ a < b --- source_file - comparison_expression - lhs: simple_identifier "a" - op: < - rhs: simple_identifier "b" + statement: + comparison_expression + lhs: simple_identifier "a" + op: < + rhs: simple_identifier "b" --- top_level body: - binary_expr - operator: operator "<" - left: - name_expr - identifier: identifier "a" - right: - name_expr - identifier: identifier "b" === Equality @@ -210,23 +159,16 @@ a == b --- source_file - equality_expression - lhs: simple_identifier "a" - op: == - rhs: simple_identifier "b" + statement: + equality_expression + lhs: simple_identifier "a" + op: == + rhs: simple_identifier "b" --- top_level body: - binary_expr - operator: operator "==" - left: - name_expr - identifier: identifier "a" - right: - name_expr - identifier: identifier "b" === Logical and @@ -237,23 +179,16 @@ a && b --- source_file - conjunction_expression - lhs: simple_identifier "a" - op: && - rhs: simple_identifier "b" + statement: + conjunction_expression + lhs: simple_identifier "a" + op: && + rhs: simple_identifier "b" --- top_level body: - binary_expr - operator: operator "&&" - left: - name_expr - identifier: identifier "a" - right: - name_expr - identifier: identifier "b" === Logical or @@ -264,23 +199,16 @@ a || b --- source_file - disjunction_expression - lhs: simple_identifier "a" - op: || - rhs: simple_identifier "b" + statement: + disjunction_expression + lhs: simple_identifier "a" + op: || + rhs: simple_identifier "b" --- top_level body: - binary_expr - operator: operator "||" - left: - name_expr - identifier: identifier "a" - right: - name_expr - identifier: identifier "b" === Logical not @@ -291,19 +219,15 @@ Logical not --- source_file - prefix_expression - operation: bang "!" - target: simple_identifier "a" + statement: + prefix_expression + operation: bang "!" + target: simple_identifier "a" --- top_level body: - unary_expr - operator: operator "!" - operand: - name_expr - identifier: identifier "a" === Range operator @@ -314,16 +238,13 @@ Range operator --- source_file - range_expression - end: integer_literal "10" - op: ... - start: integer_literal "1" + statement: + range_expression + end: integer_literal "10" + op: ... + start: integer_literal "1" --- top_level body: - binary_expr - operator: operator "..." - left: int_literal "1" - right: int_literal "10" diff --git a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt index c4f9118eedc..572e9181a68 100644 --- a/unified/extractor/tests/corpus/swift/optionals-and-errors.txt +++ b/unified/extractor/tests/corpus/swift/optionals-and-errors.txt @@ -7,32 +7,33 @@ let x: Int? = nil --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "x" - value: nil - value_binding_pattern - mutability: let - type_annotation - type: - type + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding name: - optional_type - wrapped: - user_type - type_identifier "Int" + pattern + bound_identifier: simple_identifier "x" + type: + type_annotation + type: + type + name: + optional_type + wrapped: + user_type + part: + simple_user_type + name: type_identifier "Int" + value: nil --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - pattern: - var_pattern - identifier: identifier "x" === Optional chaining @@ -43,41 +44,36 @@ let n = obj?.foo?.bar --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "n" - value: - navigation_expression - suffix: - navigation_suffix - suffix: simple_identifier "bar" - target: - optional_chain_marker + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "n" + value: navigation_expression suffix: navigation_suffix - suffix: simple_identifier "foo" + suffix: simple_identifier "bar" target: optional_chain_marker - simple_identifier "obj" - value_binding_pattern - mutability: let + expr: + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "foo" + target: + optional_chain_marker + expr: simple_identifier "obj" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: - member_access_expr - target: unsupported_node "obj?.foo?" - member: identifier "bar" - pattern: - var_pattern - identifier: identifier "n" === Force unwrap @@ -88,28 +84,25 @@ let n = opt! --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "n" - value: - postfix_expression - operation: bang "!" - target: simple_identifier "opt" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "n" + value: + postfix_expression + operation: bang "!" + target: simple_identifier "opt" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "opt!" - pattern: - var_pattern - identifier: identifier "n" === Nil-coalescing @@ -120,28 +113,25 @@ let n = opt ?? 0 --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "n" - value: - nil_coalescing_expression - if_nil: integer_literal "0" - value: simple_identifier "opt" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "n" + value: + nil_coalescing_expression + if_nil: integer_literal "0" + value: simple_identifier "opt" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "opt ?? 0" - pattern: - var_pattern - identifier: identifier "n" === Throwing function @@ -154,25 +144,29 @@ func read() throws -> String { --- source_file - function_declaration - body: - function_body - statements - control_transfer_statement - result: - line_string_literal - name: simple_identifier "read" - return_type: - type - name: - user_type - type_identifier "String" - throws "throws" + statement: + function_declaration + body: + block + statement: + control_transfer_statement + kind: return + result: + line_string_literal + name: simple_identifier "read" + return_type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "String" + throws: throws "throws" --- top_level - body: unsupported_node "func read() throws -> String {\n return \"\"\n}" + body: === Do-catch @@ -187,29 +181,41 @@ do { --- source_file - do_statement - statements - try_expression - expr: - call_expression - simple_identifier "foo" - call_suffix - value_arguments - try_operator - catch_block - catch_keyword "catch" - statements - call_expression - simple_identifier "print" - call_suffix - value_arguments - value_argument - value: simple_identifier "error" + statement: + do_statement + body: + block + statement: + try_expression + expr: + call_expression + function: simple_identifier "foo" + suffix: + call_suffix + arguments: + value_arguments + operator: + try_operator + catch: + catch_block + body: + block + statement: + call_expression + function: simple_identifier "print" + suffix: + call_suffix + arguments: + value_arguments + argument: + value_argument + value: simple_identifier "error" + keyword: catch_keyword "catch" --- top_level - body: unsupported_node "do {\n try foo()\n} catch {\n print(error)\n}" + body: === Try? expression @@ -220,32 +226,32 @@ let result = try? foo() --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "result" - value: - try_expression - expr: - call_expression - simple_identifier "foo" - call_suffix - value_arguments - try_operator - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "result" + value: + try_expression + expr: + call_expression + function: simple_identifier "foo" + suffix: + call_suffix + arguments: + value_arguments + operator: + try_operator --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "try? foo()" - pattern: - var_pattern - identifier: identifier "result" === Try! expression @@ -256,29 +262,29 @@ let result = try! foo() --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "result" - value: - try_expression - expr: - call_expression - simple_identifier "foo" - call_suffix - value_arguments - try_operator - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "result" + value: + try_expression + expr: + call_expression + function: simple_identifier "foo" + suffix: + call_suffix + arguments: + value_arguments + operator: + try_operator --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: unsupported_node "try! foo()" - pattern: - var_pattern - identifier: identifier "result" diff --git a/unified/extractor/tests/corpus/swift/types.txt b/unified/extractor/tests/corpus/swift/types.txt index 873749aa6ce..0bebaa1238f 100644 --- a/unified/extractor/tests/corpus/swift/types.txt +++ b/unified/extractor/tests/corpus/swift/types.txt @@ -7,16 +7,17 @@ class Foo {} --- source_file - class_declaration - body: - class_body - declaration_kind: class - name: type_identifier "Foo" + statement: + class_declaration + body: + class_body + declaration_kind: class + name: type_identifier "Foo" --- top_level - body: unsupported_node "class Foo {}" + body: === Class with stored properties @@ -30,40 +31,54 @@ class Point { --- source_file - class_declaration - body: - class_body - property_declaration - name: - pattern - bound_identifier: simple_identifier "x" - value_binding_pattern - mutability: var - type_annotation - type: - type - name: - user_type - type_identifier "Int" - property_declaration - name: - pattern - bound_identifier: simple_identifier "y" - value_binding_pattern - mutability: var - type_annotation - type: - type - name: - user_type - type_identifier "Int" - declaration_kind: class - name: type_identifier "Point" + statement: + class_declaration + body: + class_body + member: + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "x" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "y" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + declaration_kind: class + name: type_identifier "Point" --- top_level - body: unsupported_node "class Point {\n var x: Int\n var y: Int\n}" + body: === Class with initializer @@ -79,51 +94,64 @@ class Point { --- source_file - class_declaration - body: - class_body - property_declaration - name: - pattern - bound_identifier: simple_identifier "x" - value_binding_pattern - mutability: var - type_annotation - type: - type - name: - user_type - type_identifier "Int" - init_declaration - body: - function_body - statements - assignment - operator: = - result: simple_identifier "x" - target: - directly_assignable_expression - navigation_expression - suffix: - navigation_suffix - suffix: simple_identifier "x" - target: - self_expression - name: init - parameter - name: simple_identifier "x" - type: - type - name: - user_type - type_identifier "Int" - declaration_kind: class - name: type_identifier "Point" + statement: + class_declaration + body: + class_body + member: + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "x" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + init_declaration + body: + block + statement: + assignment + operator: = + result: simple_identifier "x" + target: + directly_assignable_expression + expr: + navigation_expression + suffix: + navigation_suffix + suffix: simple_identifier "x" + target: + self_expression + parameter: + function_parameter + parameter: + parameter + name: simple_identifier "x" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + declaration_kind: class + name: type_identifier "Point" --- top_level - body: unsupported_node "class Point {\n var x: Int\n init(x: Int) {\n self.x = x\n }\n}" + body: === Class with method @@ -139,34 +167,39 @@ class Counter { --- source_file - class_declaration - body: - class_body - property_declaration - name: - pattern - bound_identifier: simple_identifier "n" - value: integer_literal "0" - value_binding_pattern - mutability: var - function_declaration - body: - function_body - statements - assignment - operator: += - result: integer_literal "1" - target: - directly_assignable_expression - simple_identifier "n" - name: simple_identifier "bump" - declaration_kind: class - name: type_identifier "Counter" + statement: + class_declaration + body: + class_body + member: + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "n" + value: integer_literal "0" + function_declaration + body: + block + statement: + assignment + operator: += + result: integer_literal "1" + target: + directly_assignable_expression + expr: simple_identifier "n" + name: simple_identifier "bump" + declaration_kind: class + name: type_identifier "Counter" --- top_level - body: unsupported_node "class Counter {\n var n = 0\n func bump() {\n n += 1\n }\n}" + body: === Class inheritance @@ -177,20 +210,24 @@ class Dog: Animal {} --- source_file - class_declaration - body: - class_body - declaration_kind: class - name: type_identifier "Dog" - inheritance_specifier - inherits_from: - user_type - type_identifier "Animal" + statement: + class_declaration + body: + class_body + declaration_kind: class + inherits: + inheritance_specifier + inherits_from: + user_type + part: + simple_user_type + name: type_identifier "Animal" + name: type_identifier "Dog" --- top_level - body: unsupported_node "class Dog: Animal {}" + body: === Struct @@ -204,40 +241,54 @@ struct Point { --- source_file - class_declaration - body: - class_body - property_declaration - name: - pattern - bound_identifier: simple_identifier "x" - value_binding_pattern - mutability: let - type_annotation - type: - type - name: - user_type - type_identifier "Int" - property_declaration - name: - pattern - bound_identifier: simple_identifier "y" - value_binding_pattern - mutability: let - type_annotation - type: - type - name: - user_type - type_identifier "Int" - declaration_kind: struct - name: type_identifier "Point" + statement: + class_declaration + body: + class_body + member: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "x" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "y" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + declaration_kind: struct + name: type_identifier "Point" --- top_level - body: unsupported_node "struct Point {\n let x: Int\n let y: Int\n}" + body: === Enum with cases @@ -253,24 +304,34 @@ enum Direction { --- source_file - class_declaration - body: - enum_class_body - enum_entry - name: simple_identifier "north" - enum_entry - name: simple_identifier "south" - enum_entry - name: simple_identifier "east" - enum_entry - name: simple_identifier "west" - declaration_kind: enum - name: type_identifier "Direction" + statement: + class_declaration + body: + enum_class_body + member: + enum_entry + case: + enum_case_entry + name: simple_identifier "north" + enum_entry + case: + enum_case_entry + name: simple_identifier "south" + enum_entry + case: + enum_case_entry + name: simple_identifier "east" + enum_entry + case: + enum_case_entry + name: simple_identifier "west" + declaration_kind: enum + name: type_identifier "Direction" --- top_level - body: unsupported_node "enum Direction {\n case north\n case south\n case east\n case west\n}" + body: === Enum with associated values @@ -284,34 +345,50 @@ enum Shape { --- source_file - class_declaration - body: - enum_class_body - enum_entry - data_contents: - enum_type_parameters - simple_identifier "radius" - type - name: - user_type - type_identifier "Double" - name: simple_identifier "circle" - enum_entry - data_contents: - enum_type_parameters - simple_identifier "side" - type - name: - user_type - type_identifier "Double" - name: simple_identifier "square" - declaration_kind: enum - name: type_identifier "Shape" + statement: + class_declaration + body: + enum_class_body + member: + enum_entry + case: + enum_case_entry + data_contents: + enum_type_parameters + parameter: + enum_type_parameter + name: simple_identifier "radius" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Double" + name: simple_identifier "circle" + enum_entry + case: + enum_case_entry + data_contents: + enum_type_parameters + parameter: + enum_type_parameter + name: simple_identifier "side" + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Double" + name: simple_identifier "square" + declaration_kind: enum + name: type_identifier "Shape" --- top_level - body: unsupported_node "enum Shape {\n case circle(radius: Double)\n case square(side: Double)\n}" + body: === Protocol declaration @@ -324,18 +401,19 @@ protocol Drawable { --- source_file - protocol_declaration - body: - protocol_body - protocol_function_declaration - name: simple_identifier "draw" - declaration_kind: protocol - name: type_identifier "Drawable" + statement: + protocol_declaration + body: + protocol_body + member: + protocol_function_declaration + name: simple_identifier "draw" + name: type_identifier "Drawable" --- top_level - body: unsupported_node "protocol Drawable {\n func draw()\n}" + body: === Extension @@ -348,36 +426,43 @@ extension Int { --- source_file - class_declaration - body: - class_body - function_declaration - body: - function_body - statements - control_transfer_statement - result: - multiplicative_expression - lhs: - self_expression - op: * - rhs: - self_expression - name: simple_identifier "squared" - return_type: - type - name: - user_type - type_identifier "Int" - declaration_kind: extension - name: - user_type - type_identifier "Int" + statement: + class_declaration + body: + class_body + member: + function_declaration + body: + block + statement: + control_transfer_statement + kind: return + result: + multiplicative_expression + lhs: + self_expression + op: * + rhs: + self_expression + name: simple_identifier "squared" + return_type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + declaration_kind: extension + name: + user_type + part: + simple_user_type + name: type_identifier "Int" --- top_level - body: unsupported_node "extension Int {\n func squared() -> Int { return self * self }\n}" + body: === Computed property @@ -394,61 +479,82 @@ class Rect { --- source_file - class_declaration - body: - class_body - property_declaration - name: - pattern - bound_identifier: simple_identifier "w" - value_binding_pattern - mutability: var - type_annotation - type: - type - name: - user_type - type_identifier "Double" - property_declaration - name: - pattern - bound_identifier: simple_identifier "h" - value_binding_pattern - mutability: var - type_annotation - type: - type - name: - user_type - type_identifier "Double" - property_declaration - computed_value: - computed_property - statements - control_transfer_statement - result: - multiplicative_expression - lhs: simple_identifier "w" - op: * - rhs: simple_identifier "h" - name: - pattern - bound_identifier: simple_identifier "area" - value_binding_pattern - mutability: var - type_annotation - type: - type - name: - user_type - type_identifier "Double" - declaration_kind: class - name: type_identifier "Rect" + statement: + class_declaration + body: + class_body + member: + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "w" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Double" + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "h" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Double" + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + computed_value: + computed_property + statement: + control_transfer_statement + kind: return + result: + multiplicative_expression + lhs: simple_identifier "w" + op: * + rhs: simple_identifier "h" + name: + pattern + bound_identifier: simple_identifier "area" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Double" + declaration_kind: class + name: type_identifier "Rect" --- top_level - body: unsupported_node "class Rect {\n var w: Double\n var h: Double\n var area: Double {\n return w * h\n }\n}" + body: === Property with getter and setter @@ -465,50 +571,71 @@ class Box { --- source_file - class_declaration - body: - class_body - property_declaration - name: - pattern - bound_identifier: simple_identifier "_v" - value: integer_literal "0" - modifiers - visibility_modifier - value_binding_pattern - mutability: var - property_declaration - computed_value: - computed_property - computed_getter - getter_specifier - statements - control_transfer_statement - result: simple_identifier "_v" - computed_setter - setter_specifier - statements - assignment - operator: = - result: simple_identifier "newValue" - target: - directly_assignable_expression - simple_identifier "_v" - name: - pattern - bound_identifier: simple_identifier "v" - value_binding_pattern - mutability: var - type_annotation - type: - type - name: - user_type - type_identifier "Int" - declaration_kind: class - name: type_identifier "Box" + statement: + class_declaration + body: + class_body + member: + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "_v" + value: integer_literal "0" + modifiers: + modifiers + modifier: + visibility_modifier + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + computed_value: + computed_property + accessor: + computed_getter + body: + block + statement: + control_transfer_statement + kind: return + result: simple_identifier "_v" + specifier: + getter_specifier + computed_setter + body: + block + statement: + assignment + operator: = + result: simple_identifier "newValue" + target: + directly_assignable_expression + expr: simple_identifier "_v" + specifier: + setter_specifier + name: + pattern + bound_identifier: simple_identifier "v" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + declaration_kind: class + name: type_identifier "Box" --- top_level - body: unsupported_node "class Box {\n private var _v = 0\n var v: Int {\n get { return _v }\n set { _v = newValue }\n }\n}" + body: diff --git a/unified/extractor/tests/corpus/swift/variables.txt b/unified/extractor/tests/corpus/swift/variables.txt index 3fe7686a8c3..1911ddd02b1 100644 --- a/unified/extractor/tests/corpus/swift/variables.txt +++ b/unified/extractor/tests/corpus/swift/variables.txt @@ -7,25 +7,22 @@ let x = 1 --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "x" - value: integer_literal "1" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "x" + value: integer_literal "1" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: int_literal "1" - pattern: - var_pattern - identifier: identifier "x" === Var binding @@ -36,25 +33,22 @@ var x = 1 --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "x" - value: integer_literal "1" - value_binding_pattern - mutability: var + statement: + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "x" + value: integer_literal "1" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: int_literal "1" - pattern: - var_pattern - identifier: identifier "x" === Let with type annotation @@ -65,31 +59,31 @@ let x: Int = 1 --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "x" - value: integer_literal "1" - value_binding_pattern - mutability: let - type_annotation - type: - type + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding name: - user_type - type_identifier "Int" + pattern + bound_identifier: simple_identifier "x" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" + value: integer_literal "1" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: int_literal "1" - pattern: - var_pattern - identifier: identifier "x" === Var without initialiser @@ -100,29 +94,30 @@ var x: Int --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "x" - value_binding_pattern - mutability: var - type_annotation - type: - type + statement: + property_declaration + binding: + value_binding_pattern + mutability: var + declarator: + property_binding name: - user_type - type_identifier "Int" + pattern + bound_identifier: simple_identifier "x" + type: + type_annotation + type: + type + name: + user_type + part: + simple_user_type + name: type_identifier "Int" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - pattern: - var_pattern - identifier: identifier "x" === Tuple destructuring binding @@ -133,34 +128,32 @@ let (a, b) = pair --- source_file - property_declaration - name: - pattern - pattern - simple_identifier "a" - pattern - simple_identifier "b" - value: simple_identifier "pair" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + kind: + tuple_pattern + item: + tuple_pattern_item + pattern: + pattern + kind: simple_identifier "a" + tuple_pattern_item + pattern: + pattern + kind: simple_identifier "b" + value: simple_identifier "pair" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: - name_expr - identifier: identifier "pair" - pattern: - tuple_pattern - element: - var_pattern - identifier: identifier "a" - var_pattern - identifier: identifier "b" === Multiple bindings on one line @@ -171,34 +164,27 @@ let x = 1, y = 2 --- source_file - property_declaration - name: - pattern - bound_identifier: simple_identifier "x" - pattern - bound_identifier: simple_identifier "y" - value: - integer_literal "1" - integer_literal "2" - value_binding_pattern - mutability: let + statement: + property_declaration + binding: + value_binding_pattern + mutability: let + declarator: + property_binding + name: + pattern + bound_identifier: simple_identifier "x" + value: integer_literal "1" + property_binding + name: + pattern + bound_identifier: simple_identifier "y" + value: integer_literal "2" --- top_level body: - variable_declaration_stmt - variable_declarator: - variable_declarator - value: int_literal "1" - pattern: - var_pattern - identifier: identifier "x" - variable_declarator - value: int_literal "2" - pattern: - var_pattern - identifier: identifier "y" === Assignment @@ -209,17 +195,18 @@ x = 1 --- source_file - assignment - operator: = - result: integer_literal "1" - target: - directly_assignable_expression - simple_identifier "x" + statement: + assignment + operator: = + result: integer_literal "1" + target: + directly_assignable_expression + expr: simple_identifier "x" --- top_level - body: unsupported_node "x = 1" + body: === Compound assignment @@ -230,14 +217,15 @@ x += 1 --- source_file - assignment - operator: += - result: integer_literal "1" - target: - directly_assignable_expression - simple_identifier "x" + statement: + assignment + operator: += + result: integer_literal "1" + target: + directly_assignable_expression + expr: simple_identifier "x" --- top_level - body: unsupported_node "x += 1" + body: From 3e09961662ff851a482b9b58166d28bf5cc236dd Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 27 May 2026 09:08:53 +0200 Subject: [PATCH 129/226] Shared: Add local name binding library --- .../codeql/namebinding/LocalNameBinding.qll | 450 ++++++++++++++++++ shared/namebinding/qlpack.yml | 7 + 2 files changed, 457 insertions(+) create mode 100644 shared/namebinding/codeql/namebinding/LocalNameBinding.qll create mode 100644 shared/namebinding/qlpack.yml diff --git a/shared/namebinding/codeql/namebinding/LocalNameBinding.qll b/shared/namebinding/codeql/namebinding/LocalNameBinding.qll new file mode 100644 index 00000000000..55f4fa13ba1 --- /dev/null +++ b/shared/namebinding/codeql/namebinding/LocalNameBinding.qll @@ -0,0 +1,450 @@ +/** + * Provides a library for resolving local names based on syntactic scopes, including + * handling of shadowing sibling declarations. + */ +overlay[local?] +module; + +private import codeql.util.DenseRank +private import codeql.util.Location + +/** Provides the input to `LocalNameBinding`. */ +signature module LocalNameBindingInputSig { + /** + * Reverse references to the cached predicates that reference + * `CachedStage::ref()`. + */ + default predicate cacheRevRef() { none() } + + /** An AST node. */ + class AstNode { + /** Gets a textual representation of this element. */ + string toString(); + + /** Gets the location of this element. */ + Location getLocation(); + } + + /** + * Gets the child of AST node `n` at the specified index. + * + * The order of the children is only relevant for determining nearest preceding + * shadowing sibling declarations. + */ + AstNode getChild(AstNode n, int index); + + /** + * A conditional where any local declarations in the condition are in scope + * in the then-branch but not the else-branch. + * + * Example: + * + * ```rust + * if let Some(x) = opt { + * // x is in scope here + * } else { + * // x is not in scope here + * } + * ``` + */ + class Conditional extends AstNode { + /** Gets the condition of this conditional. */ + AstNode getCondition(); + + /** Gets the then-branch of this conditional. */ + AstNode getThen(); + + /** Gets the else-branch of this conditional. */ + AstNode getElse(); + } + + /** + * A declaration where all local declarations in the left-hand side are in + * scope _after_ the declaration, and where any sibling declarations with + * the same name and syntactic scope preceding it are shadowed. + * + * Example: + * + * ```rust + * fn f() { + * let x = 1; + * // this declaration of `x` shadows the previous one (in the syntactic scope + * // being the body of `f`), but the `x` in the right-hand side still refers + * // to the first declaration + * let x = x + 1; + * // this access of `x` refers to the second declaration + * println!("{}", x); + * } + * ``` + */ + class SiblingShadowingDecl extends AstNode { + /** Gets the left-hand side of this declaration. */ + AstNode getLhs(); + + /** + * Gets the right-hand side of this declaration. + * + * Any local declared in the left-hand side of this declaration is _not_ in scope + * in the right-hand side. + */ + AstNode getRhs(); + + /** + * Gets the else-branch of this declaration, if any. + * + * Any local declared in the left-hand side of this declaration is _not_ in scope + * in the else-branch. + */ + AstNode getElse(); + } + + /** + * Holds if a local declaration named `name` exists at `definingNode` inside + * the syntactic scope `scope`. + * + * Note that declarations with a `definingNode` in the left-hand side of a + * shadowing sibling declaration `decl` should use `scope = decl`. + */ + predicate declInScope(AstNode definingNode, string name, AstNode scope); + + /** + * Holds if a local declaration named `name` is implicitly in scope in the given `scope`. + */ + default predicate implicitDeclInScope(string name, AstNode scope) { none() } + + /** + * Holds if `scope` is a top scope, meaning that names may not be looked up + * in ancestor scopes. + */ + default predicate isTopScope(AstNode scope) { none() } + + /** + * Holds if `n` is a node that may access a local named `name`. + */ + predicate accessCand(AstNode n, string name); + + /** + * Holds if the access candidate `n` should begin its lookup in `scope` instead + * of its immediately enclosing scope. + * + * For example, the `this` variable in an instance field initializer might need + * to be resolved relative to a constructor body. + * + * If `scope` declares a local with the name of `n`, then `scope` is guaranteed + * to be the scope that `n` ultimately resolves to. This can thus be used to take + * full control of scope resolution for for specific types of references. + */ + default predicate lookupStartsAt(AstNode n, AstNode scope) { none() } +} + +/** + * Provides logic for resolving local names based on syntactic scopes, including + * handling of shadowing sibling declarations. + */ +module LocalNameBinding Input> { + private import Input + + final private class AstNodeFinal = AstNode; + + private class Scope extends AstNodeFinal { + Scope() { + declInScope(_, _, this) + or + implicitDeclInScope(_, this) + or + isTopScope(this) + or + lookupStartsAt(_, this) + } + } + + pragma[nomagic] + private predicate conditionHasChildAt(Conditional conditional, AstNode condition, int index) { + condition = conditional.getCondition() and + ( + exists(getChild(condition, index)) + or + // safeguard against empty conditions + not exists(getChild(condition, _)) and index = 0 + ) + } + + /** + * An adjusted version of `getChild` from the `Input` module where in conditionals like + * `if cond body`, instead of letting `body` be a child of `if`, we make it the last + * child of `cond`. This ensures that shadowing sibling declarations inside `cond` are + * properly handled inside `body`. + * + * Example: + * + * ```rust + * if let Some(x) = opt && let x = x + 1 { + * // the second declaration of `x` is in scope here + * } + * ``` + * + * We also move any `else` branch _before_ the condition to ensure that shadowing sibling + * declarations inside the condition are not in scope. + */ + private AstNode getChildAdj(AstNode parent, int index) { + result = getChild(parent, index) and + not exists(Conditional cond | result = [cond.getElse(), cond.getThen()]) + or + exists(Conditional cond | + parent = cond and + result = cond.getElse() and + index = -1 + or + exists(int last | + result = cond.getThen() and + last = max(int i | conditionHasChildAt(cond, parent, i)) and + index = last + 1 + ) + ) + } + + private module DenseRankInput implements DenseRankInputSig1 { + class C = AstNode; + + class Ranked = AstNode; + + int getRank(C parent, Ranked child) { + child = getChildAdj(parent, result) and + getChildAdj(parent, _) instanceof SiblingShadowingDecl + } + } + + private predicate getRankedChild = DenseRank1::denseRank/2; + + /** + * Holds if `n` is the `i`th child of `parent`, but should instead be considered + * a child of a shadowing sibling declaration `decl` when resolving accesses. + * + * This is the case when `decl` is the nearest shadowing sibling declaration + * preceding `n` amongst all the children of `parent`. + * + * Note that `decl` may itself also have to be nested under another shadowing + * sibling declaration. + */ + private predicate shouldBeShadowingDeclChild( + AstNode parent, SiblingShadowingDecl decl, int i, AstNode n + ) { + n = getRankedChild(parent, i) and + ( + decl = getRankedChild(parent, i - 1) + or + shouldBeShadowingDeclChild(parent, decl, i - 1, + any(AstNode prev | not prev instanceof SiblingShadowingDecl)) + ) + } + + /** + * Gets the AST parent of `n` with respect to determining enclosing scopes. + * + * For example, in + * + * ```rust + * let x = 1; + * let x = x + 1; + * println!("{}", x); + * ``` + * + * we will have (eliding leaf nodes) + * + * ```text + * let x = 1; + * / \ + * x + 1 let x = x + 1 + * | + * println!("{}", x); + * ``` + * + * and in + * + * ```rust + * if let Some(x) = opt && let x = x + 1 { + * println!("{}", x); + * } + * ``` + * + * we will have (again eliding leaf nodes) + * + * ```text + * if ... + * | + * ... && ... + * / \ + * let Some(x) = opt opt + * / \ + * let x = x + 1 x + 1 + * | + * println!("{}", x); + * ``` + */ + private AstNode getParentForScoping(AstNode n) { + not shouldBeShadowingDeclChild(_, _, _, n) and + not exists(SiblingShadowingDecl decl | n = [decl.getRhs(), decl.getElse()]) and + n = getChildAdj(result, _) + or + shouldBeShadowingDeclChild(_, result, _, n) + or + exists(SiblingShadowingDecl decl | + result = getParentForScoping(decl) and + n = [decl.getRhs(), decl.getElse()] + ) + } + + /** Gets the immediately enclosing variable scope of `n`. */ + private Scope getEnclosingScope(AstNode n) { + result = getParentForScoping(n) + or + exists(AstNode mid | + result = getEnclosingScope(mid) and + mid = getParentForScoping(n) and + not mid instanceof Scope + ) + } + + private predicate accessCandInLookupScope(AstNode n, string name, Scope lookup) { + accessCand(n, name) and + ( + lookupStartsAt(n, lookup) + or + not lookupStartsAt(n, _) and + lookup = getEnclosingScope(n) + ) + } + + pragma[nomagic] + private predicate lookupInScope(string name, Scope lookup, Scope scope) { + accessCandInLookupScope(_, name, lookup) and + scope = lookup + or + exists(Scope mid | + lookupInScope(name, lookup, mid) and + not declInScope(_, name, mid) and + not implicitDeclInScope(name, mid) and + not isTopScope(mid) and + scope = getEnclosingScope(mid) + ) + } + + cached + private newtype TLocal = + TExplicitLocal(AstNode definingNode, string name, AstNode scope) { + CachedStage::ref() and + declInScope(definingNode, name, scope) + } or + TImplicitLocal(string name, AstNode scope) { implicitDeclInScope(name, scope) } + + /** A locally declared entity, for example a variable or a parameter. */ + abstract private class LocalImpl extends TLocal { + /** Gets the AST node that defines this local entity, if any. */ + abstract AstNode getDefiningNode(); + + /** Gets the AST node that defines the scope of this local entity. */ + abstract AstNode getScope(); + + /** Gets the name of this local entity. */ + abstract string getName(); + + /** Gets the location of this local entity. */ + abstract Location getLocation(); + + /** Gets an access to this local entity. */ + LocalAccess getAnAccess() { result.getLocal() = this } + + /** Gets a textual representation of this local entity. */ + string toString() { result = this.getName() } + } + + final class Local = LocalImpl; + + /** An explicitly locally declared entity, for example a variable or a parameter. */ + class ExplicitLocal extends LocalImpl, TExplicitLocal { + private AstNode definingNode; + private string name; + private AstNode scope; + + ExplicitLocal() { this = TExplicitLocal(definingNode, name, scope) } + + override AstNode getDefiningNode() { result = definingNode } + + override AstNode getScope() { result = scope } + + override string getName() { result = name } + + override Location getLocation() { result = definingNode.getLocation() } + } + + /** An implicitly locally declared entity, for example a `self` parameter. */ + class ImplicitLocal extends LocalImpl, TImplicitLocal { + private string name; + private AstNode scope; + + ImplicitLocal() { this = TImplicitLocal(name, scope) } + + override AstNode getDefiningNode() { none() } + + override AstNode getScope() { result = scope } + + override string getName() { result = name } + + override Location getLocation() { result = scope.getLocation() } + } + + pragma[nomagic] + private predicate resolveInScope(string name, Scope lookup, Local l) { + exists(Scope scope | lookupInScope(name, lookup, scope) | + l = TExplicitLocal(_, name, scope) or + l = TImplicitLocal(name, scope) + ) + } + + cached + private predicate access(AstNode access, Local l) { + CachedStage::ref() and + exists(Scope lookup, string name | + accessCandInLookupScope(access, name, lookup) and + resolveInScope(name, lookup, l) + ) + } + + /** A local access. */ + final class LocalAccess extends AstNodeFinal { + private Local l; + + LocalAccess() { access(this, l) } + + /** Gets the local entity being accessed. */ + Local getLocal() { result = l } + } + + /** + * The cached stage of this module. + * + * Should not be exposed. + */ + cached + module CachedStage { + /** Reference to the cached stage of this module. */ + cached + predicate ref() { any() } + + /** + * DO NOT USE! + * + * Reverse references to the cached predicates that reference `ref()`. + */ + cached + predicate revRef() { + any() + or + cacheRevRef() + or + (exists(Local l) implies any()) + or + (exists(LocalAccess a) implies any()) + } + } +} diff --git a/shared/namebinding/qlpack.yml b/shared/namebinding/qlpack.yml new file mode 100644 index 00000000000..1bd12ee05dd --- /dev/null +++ b/shared/namebinding/qlpack.yml @@ -0,0 +1,7 @@ +name: codeql/namebinding +version: 0.0.1-dev +groups: shared +library: true +dependencies: + codeql/util: ${workspace} +warnOnImplicitThis: true From e06158629e241e0439962dcfb912feb2820f1ae2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 21 May 2026 11:05:14 +0200 Subject: [PATCH 130/226] Rust: More local variable tests --- .../test/library-tests/variables/Cfg.expected | 3589 +++++++++-------- .../test/library-tests/variables/Ssa.expected | 1434 +++---- rust/ql/test/library-tests/variables/main.rs | 61 +- .../variables/variables.expected | 1234 +++--- 4 files changed, 3302 insertions(+), 3016 deletions(-) diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index d3297eb8c30..b64d4ad7559 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -272,1742 +272,1875 @@ edges | main.rs:109:5:109:16 | print_str(...) | main.rs:99:19:110:1 | { ... } | | | main.rs:109:5:109:17 | ExprStmt | main.rs:109:5:109:13 | print_str | | | main.rs:109:15:109:15 | x | main.rs:109:5:109:16 | print_str(...) | | -| main.rs:112:1:119:1 | enter fn let_pattern5 | main.rs:113:5:113:42 | let ... = ... | | +| main.rs:112:1:119:1 | enter fn let_pattern5 | main.rs:113:5:113:41 | let ... = ... | | | main.rs:112:1:119:1 | exit fn let_pattern5 (normal) | main.rs:112:1:119:1 | exit fn let_pattern5 | | | main.rs:112:19:119:1 | { ... } | main.rs:112:1:119:1 | exit fn let_pattern5 (normal) | | -| main.rs:113:5:113:42 | let ... = ... | main.rs:113:14:113:17 | Some | | -| main.rs:113:9:113:10 | s1 | main.rs:113:9:113:10 | s1 | | -| main.rs:113:9:113:10 | s1 | main.rs:116:11:116:12 | s1 | match | -| main.rs:113:14:113:17 | Some | main.rs:113:19:113:30 | ...::from | | -| main.rs:113:14:113:41 | Some(...) | main.rs:113:9:113:10 | s1 | | -| main.rs:113:19:113:30 | ...::from | main.rs:113:32:113:39 | "Hello!" | | -| main.rs:113:19:113:40 | ...::from(...) | main.rs:113:14:113:41 | Some(...) | | -| main.rs:113:32:113:39 | "Hello!" | main.rs:113:19:113:40 | ...::from(...) | | +| main.rs:113:5:113:41 | let ... = ... | main.rs:113:13:113:16 | Some | | +| main.rs:113:9:113:9 | s | main.rs:113:9:113:9 | s | | +| main.rs:113:9:113:9 | s | main.rs:116:11:116:11 | s | match | +| main.rs:113:13:113:16 | Some | main.rs:113:18:113:29 | ...::from | | +| main.rs:113:13:113:40 | Some(...) | main.rs:113:9:113:9 | s | | +| main.rs:113:18:113:29 | ...::from | main.rs:113:31:113:38 | "Hello!" | | +| main.rs:113:18:113:39 | ...::from(...) | main.rs:113:13:113:40 | Some(...) | | +| main.rs:113:31:113:38 | "Hello!" | main.rs:113:18:113:39 | ...::from(...) | | | main.rs:115:5:118:5 | while ... { ... } | main.rs:112:19:119:1 | { ... } | | -| main.rs:115:11:116:12 | [boolean(false)] let ... = s1 | main.rs:115:5:118:5 | while ... { ... } | false | -| main.rs:115:11:116:12 | [boolean(true)] let ... = s1 | main.rs:117:9:117:22 | ExprStmt | true | -| main.rs:115:15:115:26 | Some(...) | main.rs:115:11:116:12 | [boolean(false)] let ... = s1 | no-match | -| main.rs:115:15:115:26 | Some(...) | main.rs:115:24:115:25 | s2 | match | -| main.rs:115:20:115:25 | ref s2 | main.rs:115:11:116:12 | [boolean(true)] let ... = s1 | match | -| main.rs:115:24:115:25 | s2 | main.rs:115:20:115:25 | ref s2 | | -| main.rs:116:11:116:12 | s1 | main.rs:115:15:115:26 | Some(...) | | -| main.rs:116:14:118:5 | { ... } | main.rs:116:11:116:12 | s1 | | -| main.rs:117:9:117:17 | print_str | main.rs:117:19:117:20 | s2 | | -| main.rs:117:9:117:21 | print_str(...) | main.rs:116:14:118:5 | { ... } | | -| main.rs:117:9:117:22 | ExprStmt | main.rs:117:9:117:17 | print_str | | -| main.rs:117:19:117:20 | s2 | main.rs:117:9:117:21 | print_str(...) | | -| main.rs:121:1:136:1 | enter fn match_pattern1 | main.rs:122:5:122:21 | let ... = ... | | -| main.rs:121:1:136:1 | exit fn match_pattern1 (normal) | main.rs:121:1:136:1 | exit fn match_pattern1 | | -| main.rs:121:21:136:1 | { ... } | main.rs:121:1:136:1 | exit fn match_pattern1 (normal) | | -| main.rs:122:5:122:21 | let ... = ... | main.rs:122:14:122:17 | Some | | -| main.rs:122:9:122:10 | x6 | main.rs:122:9:122:10 | x6 | | -| main.rs:122:9:122:10 | x6 | main.rs:123:5:123:16 | let ... = 10 | match | -| main.rs:122:14:122:17 | Some | main.rs:122:19:122:19 | 5 | | -| main.rs:122:14:122:20 | Some(...) | main.rs:122:9:122:10 | x6 | | -| main.rs:122:19:122:19 | 5 | main.rs:122:14:122:20 | Some(...) | | -| main.rs:123:5:123:16 | let ... = 10 | main.rs:123:14:123:15 | 10 | | -| main.rs:123:9:123:10 | y1 | main.rs:123:9:123:10 | y1 | | -| main.rs:123:9:123:10 | y1 | main.rs:125:5:133:5 | ExprStmt | match | -| main.rs:123:14:123:15 | 10 | main.rs:123:9:123:10 | y1 | | -| main.rs:125:5:133:5 | ExprStmt | main.rs:125:11:125:12 | x6 | | -| main.rs:125:5:133:5 | match x6 { ... } | main.rs:135:5:135:18 | ExprStmt | | -| main.rs:125:11:125:12 | x6 | main.rs:126:9:126:16 | Some(...) | | -| main.rs:126:9:126:16 | Some(...) | main.rs:126:14:126:15 | 50 | match | -| main.rs:126:9:126:16 | Some(...) | main.rs:127:9:127:16 | Some(...) | no-match | -| main.rs:126:14:126:15 | 50 | main.rs:126:14:126:15 | 50 | | -| main.rs:126:14:126:15 | 50 | main.rs:126:21:126:29 | print_str | match | -| main.rs:126:14:126:15 | 50 | main.rs:127:9:127:16 | Some(...) | no-match | -| main.rs:126:21:126:29 | print_str | main.rs:126:31:126:38 | "Got 50" | | -| main.rs:126:21:126:39 | print_str(...) | main.rs:125:5:133:5 | match x6 { ... } | | -| main.rs:126:31:126:38 | "Got 50" | main.rs:126:21:126:39 | print_str(...) | | -| main.rs:127:9:127:16 | Some(...) | main.rs:127:14:127:15 | y1 | match | -| main.rs:127:9:127:16 | Some(...) | main.rs:132:9:132:12 | None | no-match | -| main.rs:127:14:127:15 | y1 | main.rs:127:14:127:15 | y1 | | -| main.rs:127:14:127:15 | y1 | main.rs:130:13:130:21 | print_i64 | match | -| main.rs:129:9:131:9 | { ... } | main.rs:125:5:133:5 | match x6 { ... } | | -| main.rs:130:13:130:21 | print_i64 | main.rs:130:23:130:24 | y1 | | -| main.rs:130:13:130:25 | print_i64(...) | main.rs:129:9:131:9 | { ... } | | -| main.rs:130:23:130:24 | y1 | main.rs:130:13:130:25 | print_i64(...) | | -| main.rs:132:9:132:12 | None | main.rs:132:9:132:12 | None | | -| main.rs:132:9:132:12 | None | main.rs:132:17:132:25 | print_str | match | -| main.rs:132:17:132:25 | print_str | main.rs:132:27:132:32 | "NONE" | | -| main.rs:132:17:132:33 | print_str(...) | main.rs:125:5:133:5 | match x6 { ... } | | -| main.rs:132:27:132:32 | "NONE" | main.rs:132:17:132:33 | print_str(...) | | -| main.rs:135:5:135:13 | print_i64 | main.rs:135:15:135:16 | y1 | | -| main.rs:135:5:135:17 | print_i64(...) | main.rs:121:21:136:1 | { ... } | | -| main.rs:135:5:135:18 | ExprStmt | main.rs:135:5:135:13 | print_i64 | | -| main.rs:135:15:135:16 | y1 | main.rs:135:5:135:17 | print_i64(...) | | -| main.rs:138:1:167:1 | enter fn match_pattern2 | main.rs:139:5:139:36 | let ... = ... | | -| main.rs:138:1:167:1 | exit fn match_pattern2 (normal) | main.rs:138:1:167:1 | exit fn match_pattern2 | | -| main.rs:138:21:167:1 | { ... } | main.rs:138:1:167:1 | exit fn match_pattern2 (normal) | | -| main.rs:139:5:139:36 | let ... = ... | main.rs:139:20:139:20 | 2 | | -| main.rs:139:9:139:15 | numbers | main.rs:139:9:139:15 | numbers | | -| main.rs:139:9:139:15 | numbers | main.rs:141:5:154:5 | ExprStmt | match | -| main.rs:139:19:139:35 | TupleExpr | main.rs:139:9:139:15 | numbers | | -| main.rs:139:20:139:20 | 2 | main.rs:139:23:139:23 | 4 | | -| main.rs:139:23:139:23 | 4 | main.rs:139:26:139:26 | 8 | | -| main.rs:139:26:139:26 | 8 | main.rs:139:29:139:30 | 16 | | -| main.rs:139:29:139:30 | 16 | main.rs:139:33:139:34 | 32 | | -| main.rs:139:33:139:34 | 32 | main.rs:139:19:139:35 | TupleExpr | | -| main.rs:141:5:154:5 | ExprStmt | main.rs:141:11:141:17 | numbers | | -| main.rs:141:5:154:5 | match numbers { ... } | main.rs:156:11:156:17 | numbers | | -| main.rs:141:11:141:17 | numbers | main.rs:143:9:149:9 | TuplePat | | -| main.rs:143:9:149:9 | TuplePat | main.rs:144:13:144:17 | first | match | -| main.rs:144:13:144:17 | first | main.rs:144:13:144:17 | first | | -| main.rs:144:13:144:17 | first | main.rs:145:13:145:13 | _ | match | -| main.rs:145:13:145:13 | _ | main.rs:146:13:146:17 | third | match | -| main.rs:146:13:146:17 | third | main.rs:146:13:146:17 | third | | -| main.rs:146:13:146:17 | third | main.rs:147:13:147:13 | _ | match | -| main.rs:147:13:147:13 | _ | main.rs:148:13:148:17 | fifth | match | -| main.rs:148:13:148:17 | fifth | main.rs:148:13:148:17 | fifth | | -| main.rs:148:13:148:17 | fifth | main.rs:150:13:150:29 | ExprStmt | match | -| main.rs:149:14:153:9 | { ... } | main.rs:141:5:154:5 | match numbers { ... } | | -| main.rs:150:13:150:21 | print_i64 | main.rs:150:23:150:27 | first | | -| main.rs:150:13:150:28 | print_i64(...) | main.rs:151:13:151:29 | ExprStmt | | -| main.rs:150:13:150:29 | ExprStmt | main.rs:150:13:150:21 | print_i64 | | -| main.rs:150:23:150:27 | first | main.rs:150:13:150:28 | print_i64(...) | | -| main.rs:151:13:151:21 | print_i64 | main.rs:151:23:151:27 | third | | -| main.rs:151:13:151:28 | print_i64(...) | main.rs:152:13:152:29 | ExprStmt | | -| main.rs:151:13:151:29 | ExprStmt | main.rs:151:13:151:21 | print_i64 | | -| main.rs:151:23:151:27 | third | main.rs:151:13:151:28 | print_i64(...) | | -| main.rs:152:13:152:21 | print_i64 | main.rs:152:23:152:27 | fifth | | -| main.rs:152:13:152:28 | print_i64(...) | main.rs:149:14:153:9 | { ... } | | -| main.rs:152:13:152:29 | ExprStmt | main.rs:152:13:152:21 | print_i64 | | -| main.rs:152:23:152:27 | fifth | main.rs:152:13:152:28 | print_i64(...) | | -| main.rs:156:5:166:5 | match numbers { ... } | main.rs:138:21:167:1 | { ... } | | -| main.rs:156:11:156:17 | numbers | main.rs:158:9:162:9 | TuplePat | | -| main.rs:158:9:162:9 | TuplePat | main.rs:159:13:159:17 | first | match | -| main.rs:159:13:159:17 | first | main.rs:159:13:159:17 | first | | -| main.rs:159:13:159:17 | first | main.rs:160:13:160:14 | .. | match | -| main.rs:160:13:160:14 | .. | main.rs:161:13:161:16 | last | match | -| main.rs:161:13:161:16 | last | main.rs:161:13:161:16 | last | | -| main.rs:161:13:161:16 | last | main.rs:163:13:163:29 | ExprStmt | match | -| main.rs:162:14:165:9 | { ... } | main.rs:156:5:166:5 | match numbers { ... } | | -| main.rs:163:13:163:21 | print_i64 | main.rs:163:23:163:27 | first | | -| main.rs:163:13:163:28 | print_i64(...) | main.rs:164:13:164:28 | ExprStmt | | -| main.rs:163:13:163:29 | ExprStmt | main.rs:163:13:163:21 | print_i64 | | -| main.rs:163:23:163:27 | first | main.rs:163:13:163:28 | print_i64(...) | | -| main.rs:164:13:164:21 | print_i64 | main.rs:164:23:164:26 | last | | -| main.rs:164:13:164:27 | print_i64(...) | main.rs:162:14:165:9 | { ... } | | -| main.rs:164:13:164:28 | ExprStmt | main.rs:164:13:164:21 | print_i64 | | -| main.rs:164:23:164:26 | last | main.rs:164:13:164:27 | print_i64(...) | | -| main.rs:169:1:177:1 | enter fn match_pattern3 | main.rs:170:5:170:38 | let ... = ... | | -| main.rs:169:1:177:1 | exit fn match_pattern3 (normal) | main.rs:169:1:177:1 | exit fn match_pattern3 | | -| main.rs:169:21:177:1 | { ... } | main.rs:169:1:177:1 | exit fn match_pattern3 (normal) | | -| main.rs:170:5:170:38 | let ... = ... | main.rs:170:25:170:27 | "x" | | -| main.rs:170:9:170:10 | p2 | main.rs:170:9:170:10 | p2 | | -| main.rs:170:9:170:10 | p2 | main.rs:172:11:172:12 | p2 | match | -| main.rs:170:14:170:37 | Point {...} | main.rs:170:9:170:10 | p2 | | -| main.rs:170:25:170:27 | "x" | main.rs:170:33:170:35 | "y" | | -| main.rs:170:33:170:35 | "y" | main.rs:170:14:170:37 | Point {...} | | -| main.rs:172:5:176:5 | match p2 { ... } | main.rs:169:21:177:1 | { ... } | | -| main.rs:172:11:172:12 | p2 | main.rs:173:9:175:9 | Point {...} | | -| main.rs:173:9:175:9 | Point {...} | main.rs:174:16:174:17 | x7 | match | -| main.rs:174:16:174:17 | x7 | main.rs:174:16:174:17 | x7 | | -| main.rs:174:16:174:17 | x7 | main.rs:174:20:174:21 | .. | match | -| main.rs:174:20:174:21 | .. | main.rs:175:14:175:22 | print_str | match | -| main.rs:175:14:175:22 | print_str | main.rs:175:24:175:25 | x7 | | -| main.rs:175:14:175:26 | print_str(...) | main.rs:172:5:176:5 | match p2 { ... } | | -| main.rs:175:24:175:25 | x7 | main.rs:175:14:175:26 | print_str(...) | | -| main.rs:183:1:200:1 | enter fn match_pattern4 | main.rs:184:5:184:39 | let ... = ... | | -| main.rs:183:1:200:1 | exit fn match_pattern4 (normal) | main.rs:183:1:200:1 | exit fn match_pattern4 | | -| main.rs:183:21:200:1 | { ... } | main.rs:183:1:200:1 | exit fn match_pattern4 (normal) | | -| main.rs:184:5:184:39 | let ... = ... | main.rs:184:36:184:36 | 0 | | -| main.rs:184:9:184:11 | msg | main.rs:184:9:184:11 | msg | | -| main.rs:184:9:184:11 | msg | main.rs:186:11:186:13 | msg | match | -| main.rs:184:15:184:38 | ...::Hello {...} | main.rs:184:9:184:11 | msg | | -| main.rs:184:36:184:36 | 0 | main.rs:184:15:184:38 | ...::Hello {...} | | -| main.rs:186:5:199:5 | match msg { ... } | main.rs:183:21:200:1 | { ... } | | -| main.rs:186:11:186:13 | msg | main.rs:188:9:190:9 | ...::Hello {...} | | -| main.rs:188:9:190:9 | ...::Hello {...} | main.rs:189:31:189:35 | RangePat | match | -| main.rs:188:9:190:9 | ...::Hello {...} | main.rs:191:9:191:38 | ...::Hello {...} | no-match | -| main.rs:189:17:189:27 | id_variable | main.rs:189:17:189:35 | id_variable @ ... | | -| main.rs:189:17:189:35 | id_variable @ ... | main.rs:190:14:190:22 | print_i64 | match | -| main.rs:189:31:189:31 | 3 | main.rs:189:31:189:31 | 3 | | -| main.rs:189:31:189:31 | 3 | main.rs:189:35:189:35 | 7 | match | -| main.rs:189:31:189:31 | 3 | main.rs:191:9:191:38 | ...::Hello {...} | no-match | -| main.rs:189:31:189:35 | RangePat | main.rs:189:31:189:31 | 3 | match | -| main.rs:189:35:189:35 | 7 | main.rs:189:17:189:27 | id_variable | match | -| main.rs:189:35:189:35 | 7 | main.rs:189:35:189:35 | 7 | | -| main.rs:189:35:189:35 | 7 | main.rs:191:9:191:38 | ...::Hello {...} | no-match | -| main.rs:190:14:190:22 | print_i64 | main.rs:190:24:190:34 | id_variable | | -| main.rs:190:14:190:35 | print_i64(...) | main.rs:186:5:199:5 | match msg { ... } | | -| main.rs:190:24:190:34 | id_variable | main.rs:190:14:190:35 | print_i64(...) | | -| main.rs:191:9:191:38 | ...::Hello {...} | main.rs:191:30:191:36 | RangePat | match | -| main.rs:191:9:191:38 | ...::Hello {...} | main.rs:194:9:194:29 | ...::Hello {...} | no-match | -| main.rs:191:30:191:31 | 10 | main.rs:191:30:191:31 | 10 | | -| main.rs:191:30:191:31 | 10 | main.rs:191:35:191:36 | 12 | match | -| main.rs:191:30:191:31 | 10 | main.rs:194:9:194:29 | ...::Hello {...} | no-match | -| main.rs:191:30:191:36 | RangePat | main.rs:191:30:191:31 | 10 | match | -| main.rs:191:35:191:36 | 12 | main.rs:191:35:191:36 | 12 | | -| main.rs:191:35:191:36 | 12 | main.rs:192:22:192:51 | ExprStmt | match | -| main.rs:191:35:191:36 | 12 | main.rs:194:9:194:29 | ...::Hello {...} | no-match | -| main.rs:191:43:193:9 | { ... } | main.rs:186:5:199:5 | match msg { ... } | | -| main.rs:192:13:192:20 | ...::_print | main.rs:192:22:192:51 | "Found an id in another range\\... | | -| main.rs:192:13:192:52 | MacroExpr | main.rs:191:43:193:9 | { ... } | | -| main.rs:192:13:192:52 | println!... | main.rs:192:13:192:52 | MacroExpr | | -| main.rs:192:22:192:51 | "Found an id in another range\\... | main.rs:192:22:192:51 | FormatArgsExpr | | -| main.rs:192:22:192:51 | ...::_print(...) | main.rs:192:22:192:51 | { ... } | | -| main.rs:192:22:192:51 | ...::format_args_nl!... | main.rs:192:22:192:51 | MacroExpr | | -| main.rs:192:22:192:51 | ExprStmt | main.rs:192:13:192:20 | ...::_print | | -| main.rs:192:22:192:51 | FormatArgsExpr | main.rs:192:22:192:51 | ...::format_args_nl!... | | -| main.rs:192:22:192:51 | MacroExpr | main.rs:192:22:192:51 | ...::_print(...) | | -| main.rs:192:22:192:51 | { ... } | main.rs:192:13:192:52 | println!... | | -| main.rs:192:22:192:51 | { ... } | main.rs:192:22:192:51 | { ... } | | -| main.rs:194:9:194:29 | ...::Hello {...} | main.rs:194:26:194:27 | id | match | -| main.rs:194:26:194:27 | id | main.rs:194:26:194:27 | id | | -| main.rs:194:26:194:27 | id | main.rs:197:13:197:21 | print_i64 | match | -| main.rs:196:9:198:9 | { ... } | main.rs:186:5:199:5 | match msg { ... } | | -| main.rs:197:13:197:21 | print_i64 | main.rs:197:23:197:24 | id | | -| main.rs:197:13:197:25 | print_i64(...) | main.rs:196:9:198:9 | { ... } | | -| main.rs:197:23:197:24 | id | main.rs:197:13:197:25 | print_i64(...) | | -| main.rs:207:1:213:1 | enter fn match_pattern5 | main.rs:208:5:208:34 | let ... = ... | | -| main.rs:207:1:213:1 | exit fn match_pattern5 (normal) | main.rs:207:1:213:1 | exit fn match_pattern5 | | -| main.rs:207:21:213:1 | { ... } | main.rs:207:1:213:1 | exit fn match_pattern5 (normal) | | -| main.rs:208:5:208:34 | let ... = ... | main.rs:208:18:208:29 | ...::Left | | -| main.rs:208:9:208:14 | either | main.rs:208:9:208:14 | either | | -| main.rs:208:9:208:14 | either | main.rs:209:11:209:16 | either | match | -| main.rs:208:18:208:29 | ...::Left | main.rs:208:31:208:32 | 32 | | -| main.rs:208:18:208:33 | ...::Left(...) | main.rs:208:9:208:14 | either | | -| main.rs:208:31:208:32 | 32 | main.rs:208:18:208:33 | ...::Left(...) | | -| main.rs:209:5:212:5 | match either { ... } | main.rs:207:21:213:1 | { ... } | | -| main.rs:209:11:209:16 | either | main.rs:210:9:210:24 | ...::Left(...) | | -| main.rs:210:9:210:24 | ...::Left(...) | main.rs:210:22:210:23 | a3 | match | -| main.rs:210:9:210:24 | ...::Left(...) | main.rs:210:28:210:44 | ...::Right(...) | no-match | -| main.rs:210:9:210:44 | ... \| ... | main.rs:211:16:211:24 | print_i64 | match | -| main.rs:210:22:210:23 | a3 | main.rs:210:9:210:44 | ... \| ... | match | -| main.rs:210:22:210:23 | a3 | main.rs:210:22:210:23 | a3 | | -| main.rs:210:28:210:44 | ...::Right(...) | main.rs:210:42:210:43 | a3 | match | -| main.rs:210:42:210:43 | a3 | main.rs:210:9:210:44 | ... \| ... | match | -| main.rs:210:42:210:43 | a3 | main.rs:210:42:210:43 | a3 | | -| main.rs:211:16:211:24 | print_i64 | main.rs:211:26:211:27 | a3 | | -| main.rs:211:16:211:28 | print_i64(...) | main.rs:209:5:212:5 | match either { ... } | | -| main.rs:211:26:211:27 | a3 | main.rs:211:16:211:28 | print_i64(...) | | -| main.rs:221:1:235:1 | enter fn match_pattern6 | main.rs:222:5:222:37 | let ... = ... | | -| main.rs:221:1:235:1 | exit fn match_pattern6 (normal) | main.rs:221:1:235:1 | exit fn match_pattern6 | | -| main.rs:221:21:235:1 | { ... } | main.rs:221:1:235:1 | exit fn match_pattern6 (normal) | | -| main.rs:222:5:222:37 | let ... = ... | main.rs:222:14:222:32 | ...::Second | | -| main.rs:222:9:222:10 | tv | main.rs:222:9:222:10 | tv | | -| main.rs:222:9:222:10 | tv | main.rs:223:5:226:5 | ExprStmt | match | -| main.rs:222:14:222:32 | ...::Second | main.rs:222:34:222:35 | 62 | | -| main.rs:222:14:222:36 | ...::Second(...) | main.rs:222:9:222:10 | tv | | -| main.rs:222:34:222:35 | 62 | main.rs:222:14:222:36 | ...::Second(...) | | -| main.rs:223:5:226:5 | ExprStmt | main.rs:223:11:223:12 | tv | | -| main.rs:223:5:226:5 | match tv { ... } | main.rs:227:5:230:5 | ExprStmt | | -| main.rs:223:11:223:12 | tv | main.rs:224:9:224:30 | ...::First(...) | | -| main.rs:224:9:224:30 | ...::First(...) | main.rs:224:28:224:29 | a4 | match | -| main.rs:224:9:224:30 | ...::First(...) | main.rs:224:34:224:56 | ...::Second(...) | no-match | -| main.rs:224:9:224:81 | ... \| ... \| ... | main.rs:225:16:225:24 | print_i64 | match | -| main.rs:224:28:224:29 | a4 | main.rs:224:9:224:81 | ... \| ... \| ... | match | -| main.rs:224:28:224:29 | a4 | main.rs:224:28:224:29 | a4 | | -| main.rs:224:34:224:56 | ...::Second(...) | main.rs:224:54:224:55 | a4 | match | -| main.rs:224:34:224:56 | ...::Second(...) | main.rs:224:60:224:81 | ...::Third(...) | no-match | -| main.rs:224:54:224:55 | a4 | main.rs:224:9:224:81 | ... \| ... \| ... | match | -| main.rs:224:54:224:55 | a4 | main.rs:224:54:224:55 | a4 | | -| main.rs:224:60:224:81 | ...::Third(...) | main.rs:224:79:224:80 | a4 | match | -| main.rs:224:79:224:80 | a4 | main.rs:224:9:224:81 | ... \| ... \| ... | match | -| main.rs:224:79:224:80 | a4 | main.rs:224:79:224:80 | a4 | | -| main.rs:225:16:225:24 | print_i64 | main.rs:225:26:225:27 | a4 | | -| main.rs:225:16:225:28 | print_i64(...) | main.rs:223:5:226:5 | match tv { ... } | | -| main.rs:225:26:225:27 | a4 | main.rs:225:16:225:28 | print_i64(...) | | -| main.rs:227:5:230:5 | ExprStmt | main.rs:227:11:227:12 | tv | | -| main.rs:227:5:230:5 | match tv { ... } | main.rs:231:11:231:12 | tv | | -| main.rs:227:11:227:12 | tv | main.rs:228:10:228:31 | ...::First(...) | | -| main.rs:228:9:228:83 | ... \| ... | main.rs:229:16:229:24 | print_i64 | match | -| main.rs:228:10:228:31 | ...::First(...) | main.rs:228:29:228:30 | a5 | match | -| main.rs:228:10:228:31 | ...::First(...) | main.rs:228:35:228:57 | ...::Second(...) | no-match | -| main.rs:228:10:228:57 | [match(false)] ... \| ... | main.rs:228:62:228:83 | ...::Third(...) | no-match | -| main.rs:228:10:228:57 | [match(true)] ... \| ... | main.rs:228:9:228:83 | ... \| ... | match | -| main.rs:228:29:228:30 | a5 | main.rs:228:10:228:57 | [match(true)] ... \| ... | match | -| main.rs:228:29:228:30 | a5 | main.rs:228:29:228:30 | a5 | | -| main.rs:228:35:228:57 | ...::Second(...) | main.rs:228:10:228:57 | [match(false)] ... \| ... | no-match | -| main.rs:228:35:228:57 | ...::Second(...) | main.rs:228:55:228:56 | a5 | match | -| main.rs:228:55:228:56 | a5 | main.rs:228:10:228:57 | [match(true)] ... \| ... | match | -| main.rs:228:55:228:56 | a5 | main.rs:228:55:228:56 | a5 | | -| main.rs:228:62:228:83 | ...::Third(...) | main.rs:228:81:228:82 | a5 | match | -| main.rs:228:81:228:82 | a5 | main.rs:228:9:228:83 | ... \| ... | match | -| main.rs:228:81:228:82 | a5 | main.rs:228:81:228:82 | a5 | | -| main.rs:229:16:229:24 | print_i64 | main.rs:229:26:229:27 | a5 | | -| main.rs:229:16:229:28 | print_i64(...) | main.rs:227:5:230:5 | match tv { ... } | | -| main.rs:229:26:229:27 | a5 | main.rs:229:16:229:28 | print_i64(...) | | -| main.rs:231:5:234:5 | match tv { ... } | main.rs:221:21:235:1 | { ... } | | -| main.rs:231:11:231:12 | tv | main.rs:232:9:232:30 | ...::First(...) | | -| main.rs:232:9:232:30 | ...::First(...) | main.rs:232:28:232:29 | a6 | match | -| main.rs:232:9:232:30 | ...::First(...) | main.rs:232:35:232:57 | ...::Second(...) | no-match | -| main.rs:232:9:232:83 | ... \| ... | main.rs:233:16:233:24 | print_i64 | match | -| main.rs:232:28:232:29 | a6 | main.rs:232:9:232:83 | ... \| ... | match | -| main.rs:232:28:232:29 | a6 | main.rs:232:28:232:29 | a6 | | -| main.rs:232:35:232:57 | ...::Second(...) | main.rs:232:55:232:56 | a6 | match | -| main.rs:232:35:232:57 | ...::Second(...) | main.rs:232:61:232:82 | ...::Third(...) | no-match | -| main.rs:232:35:232:82 | ... \| ... | main.rs:232:9:232:83 | ... \| ... | match | -| main.rs:232:55:232:56 | a6 | main.rs:232:35:232:82 | ... \| ... | match | -| main.rs:232:55:232:56 | a6 | main.rs:232:55:232:56 | a6 | | -| main.rs:232:61:232:82 | ...::Third(...) | main.rs:232:80:232:81 | a6 | match | -| main.rs:232:80:232:81 | a6 | main.rs:232:35:232:82 | ... \| ... | match | -| main.rs:232:80:232:81 | a6 | main.rs:232:80:232:81 | a6 | | -| main.rs:233:16:233:24 | print_i64 | main.rs:233:26:233:27 | a6 | | -| main.rs:233:16:233:28 | print_i64(...) | main.rs:231:5:234:5 | match tv { ... } | | -| main.rs:233:26:233:27 | a6 | main.rs:233:16:233:28 | print_i64(...) | | -| main.rs:237:1:245:1 | enter fn match_pattern7 | main.rs:238:5:238:34 | let ... = ... | | -| main.rs:237:1:245:1 | exit fn match_pattern7 (normal) | main.rs:237:1:245:1 | exit fn match_pattern7 | | -| main.rs:237:21:245:1 | { ... } | main.rs:237:1:245:1 | exit fn match_pattern7 (normal) | | -| main.rs:238:5:238:34 | let ... = ... | main.rs:238:18:238:29 | ...::Left | | -| main.rs:238:9:238:14 | either | main.rs:238:9:238:14 | either | | -| main.rs:238:9:238:14 | either | main.rs:239:11:239:16 | either | match | -| main.rs:238:18:238:29 | ...::Left | main.rs:238:31:238:32 | 32 | | -| main.rs:238:18:238:33 | ...::Left(...) | main.rs:238:9:238:14 | either | | -| main.rs:238:31:238:32 | 32 | main.rs:238:18:238:33 | ...::Left(...) | | -| main.rs:239:5:244:5 | match either { ... } | main.rs:237:21:245:1 | { ... } | | -| main.rs:239:11:239:16 | either | main.rs:240:9:240:24 | ...::Left(...) | | -| main.rs:240:9:240:24 | ...::Left(...) | main.rs:240:22:240:23 | a7 | match | -| main.rs:240:9:240:24 | ...::Left(...) | main.rs:240:28:240:44 | ...::Right(...) | no-match | -| main.rs:240:9:240:44 | [match(false)] ... \| ... | main.rs:243:9:243:9 | _ | no-match | -| main.rs:240:9:240:44 | [match(true)] ... \| ... | main.rs:241:16:241:17 | a7 | match | -| main.rs:240:22:240:23 | a7 | main.rs:240:9:240:44 | [match(true)] ... \| ... | match | -| main.rs:240:22:240:23 | a7 | main.rs:240:22:240:23 | a7 | | -| main.rs:240:28:240:44 | ...::Right(...) | main.rs:240:9:240:44 | [match(false)] ... \| ... | no-match | -| main.rs:240:28:240:44 | ...::Right(...) | main.rs:240:42:240:43 | a7 | match | -| main.rs:240:42:240:43 | a7 | main.rs:240:9:240:44 | [match(true)] ... \| ... | match | -| main.rs:240:42:240:43 | a7 | main.rs:240:42:240:43 | a7 | | -| main.rs:241:16:241:17 | a7 | main.rs:241:21:241:21 | 0 | | -| main.rs:241:16:241:21 | ... > ... | main.rs:242:16:242:24 | print_i64 | true | -| main.rs:241:16:241:21 | ... > ... | main.rs:243:9:243:9 | _ | false | -| main.rs:241:21:241:21 | 0 | main.rs:241:16:241:21 | ... > ... | | -| main.rs:242:16:242:24 | print_i64 | main.rs:242:26:242:27 | a7 | | -| main.rs:242:16:242:28 | print_i64(...) | main.rs:239:5:244:5 | match either { ... } | | -| main.rs:242:26:242:27 | a7 | main.rs:242:16:242:28 | print_i64(...) | | -| main.rs:243:9:243:9 | _ | main.rs:243:14:243:15 | TupleExpr | match | -| main.rs:243:14:243:15 | TupleExpr | main.rs:239:5:244:5 | match either { ... } | | -| main.rs:247:1:262:1 | enter fn match_pattern8 | main.rs:248:5:248:34 | let ... = ... | | -| main.rs:247:1:262:1 | exit fn match_pattern8 (normal) | main.rs:247:1:262:1 | exit fn match_pattern8 | | -| main.rs:247:21:262:1 | { ... } | main.rs:247:1:262:1 | exit fn match_pattern8 (normal) | | -| main.rs:248:5:248:34 | let ... = ... | main.rs:248:18:248:29 | ...::Left | | -| main.rs:248:9:248:14 | either | main.rs:248:9:248:14 | either | | -| main.rs:248:9:248:14 | either | main.rs:250:11:250:16 | either | match | -| main.rs:248:18:248:29 | ...::Left | main.rs:248:31:248:32 | 32 | | -| main.rs:248:18:248:33 | ...::Left(...) | main.rs:248:9:248:14 | either | | -| main.rs:248:31:248:32 | 32 | main.rs:248:18:248:33 | ...::Left(...) | | -| main.rs:250:5:261:5 | match either { ... } | main.rs:247:21:262:1 | { ... } | | -| main.rs:250:11:250:16 | either | main.rs:252:14:252:30 | ...::Left(...) | | -| main.rs:251:9:252:52 | ref e @ ... | main.rs:254:13:254:27 | ExprStmt | match | -| main.rs:251:13:251:13 | e | main.rs:251:9:252:52 | ref e @ ... | | -| main.rs:252:14:252:30 | ...::Left(...) | main.rs:252:27:252:29 | a11 | match | -| main.rs:252:14:252:30 | ...::Left(...) | main.rs:252:34:252:51 | ...::Right(...) | no-match | -| main.rs:252:14:252:51 | [match(false)] ... \| ... | main.rs:260:9:260:9 | _ | no-match | -| main.rs:252:14:252:51 | [match(true)] ... \| ... | main.rs:251:13:251:13 | e | match | -| main.rs:252:27:252:29 | a11 | main.rs:252:14:252:51 | [match(true)] ... \| ... | match | -| main.rs:252:27:252:29 | a11 | main.rs:252:27:252:29 | a11 | | -| main.rs:252:34:252:51 | ...::Right(...) | main.rs:252:14:252:51 | [match(false)] ... \| ... | no-match | -| main.rs:252:34:252:51 | ...::Right(...) | main.rs:252:48:252:50 | a11 | match | -| main.rs:252:48:252:50 | a11 | main.rs:252:14:252:51 | [match(true)] ... \| ... | match | -| main.rs:252:48:252:50 | a11 | main.rs:252:48:252:50 | a11 | | -| main.rs:253:12:259:9 | { ... } | main.rs:250:5:261:5 | match either { ... } | | -| main.rs:254:13:254:21 | print_i64 | main.rs:254:23:254:25 | a11 | | -| main.rs:254:13:254:26 | print_i64(...) | main.rs:256:15:256:15 | e | | -| main.rs:254:13:254:27 | ExprStmt | main.rs:254:13:254:21 | print_i64 | | -| main.rs:254:23:254:25 | a11 | main.rs:254:13:254:26 | print_i64(...) | | -| main.rs:255:13:258:13 | if ... {...} | main.rs:253:12:259:9 | { ... } | | -| main.rs:255:16:256:15 | [boolean(false)] let ... = e | main.rs:255:13:258:13 | if ... {...} | false | -| main.rs:255:16:256:15 | [boolean(true)] let ... = e | main.rs:257:17:257:32 | ExprStmt | true | -| main.rs:255:20:255:36 | ...::Left(...) | main.rs:255:16:256:15 | [boolean(false)] let ... = e | no-match | -| main.rs:255:20:255:36 | ...::Left(...) | main.rs:255:33:255:35 | a12 | match | -| main.rs:255:33:255:35 | a12 | main.rs:255:16:256:15 | [boolean(true)] let ... = e | match | -| main.rs:255:33:255:35 | a12 | main.rs:255:33:255:35 | a12 | | -| main.rs:256:15:256:15 | e | main.rs:255:20:255:36 | ...::Left(...) | | -| main.rs:256:17:258:13 | { ... } | main.rs:255:13:258:13 | if ... {...} | | -| main.rs:257:17:257:25 | print_i64 | main.rs:257:28:257:30 | a12 | | -| main.rs:257:17:257:31 | print_i64(...) | main.rs:256:17:258:13 | { ... } | | -| main.rs:257:17:257:32 | ExprStmt | main.rs:257:17:257:25 | print_i64 | | -| main.rs:257:27:257:30 | * ... | main.rs:257:17:257:31 | print_i64(...) | | -| main.rs:257:28:257:30 | a12 | main.rs:257:27:257:30 | * ... | | -| main.rs:260:9:260:9 | _ | main.rs:260:14:260:15 | TupleExpr | match | -| main.rs:260:14:260:15 | TupleExpr | main.rs:250:5:261:5 | match either { ... } | | -| main.rs:271:1:277:1 | enter fn match_pattern9 | main.rs:272:5:272:36 | let ... = ... | | -| main.rs:271:1:277:1 | exit fn match_pattern9 (normal) | main.rs:271:1:277:1 | exit fn match_pattern9 | | -| main.rs:271:21:277:1 | { ... } | main.rs:271:1:277:1 | exit fn match_pattern9 (normal) | | -| main.rs:272:5:272:36 | let ... = ... | main.rs:272:14:272:31 | ...::Second | | -| main.rs:272:9:272:10 | fv | main.rs:272:9:272:10 | fv | | -| main.rs:272:9:272:10 | fv | main.rs:273:11:273:12 | fv | match | -| main.rs:272:14:272:31 | ...::Second | main.rs:272:33:272:34 | 62 | | -| main.rs:272:14:272:35 | ...::Second(...) | main.rs:272:9:272:10 | fv | | -| main.rs:272:33:272:34 | 62 | main.rs:272:14:272:35 | ...::Second(...) | | -| main.rs:273:5:276:5 | match fv { ... } | main.rs:271:21:277:1 | { ... } | | -| main.rs:273:11:273:12 | fv | main.rs:274:9:274:30 | ...::First(...) | | -| main.rs:274:9:274:30 | ...::First(...) | main.rs:274:27:274:29 | a13 | match | -| main.rs:274:9:274:30 | ...::First(...) | main.rs:274:35:274:57 | ...::Second(...) | no-match | -| main.rs:274:9:274:109 | ... \| ... \| ... | main.rs:275:16:275:24 | print_i64 | match | -| main.rs:274:27:274:29 | a13 | main.rs:274:9:274:109 | ... \| ... \| ... | match | -| main.rs:274:27:274:29 | a13 | main.rs:274:27:274:29 | a13 | | -| main.rs:274:35:274:57 | ...::Second(...) | main.rs:274:54:274:56 | a13 | match | -| main.rs:274:35:274:57 | ...::Second(...) | main.rs:274:61:274:82 | ...::Third(...) | no-match | -| main.rs:274:35:274:82 | [match(false)] ... \| ... | main.rs:274:87:274:109 | ...::Fourth(...) | no-match | -| main.rs:274:35:274:82 | [match(true)] ... \| ... | main.rs:274:9:274:109 | ... \| ... \| ... | match | -| main.rs:274:54:274:56 | a13 | main.rs:274:35:274:82 | [match(true)] ... \| ... | match | -| main.rs:274:54:274:56 | a13 | main.rs:274:54:274:56 | a13 | | -| main.rs:274:61:274:82 | ...::Third(...) | main.rs:274:35:274:82 | [match(false)] ... \| ... | no-match | -| main.rs:274:61:274:82 | ...::Third(...) | main.rs:274:79:274:81 | a13 | match | -| main.rs:274:79:274:81 | a13 | main.rs:274:35:274:82 | [match(true)] ... \| ... | match | -| main.rs:274:79:274:81 | a13 | main.rs:274:79:274:81 | a13 | | -| main.rs:274:87:274:109 | ...::Fourth(...) | main.rs:274:106:274:108 | a13 | match | -| main.rs:274:106:274:108 | a13 | main.rs:274:9:274:109 | ... \| ... \| ... | match | -| main.rs:274:106:274:108 | a13 | main.rs:274:106:274:108 | a13 | | -| main.rs:275:16:275:24 | print_i64 | main.rs:275:26:275:28 | a13 | | -| main.rs:275:16:275:29 | print_i64(...) | main.rs:273:5:276:5 | match fv { ... } | | -| main.rs:275:26:275:28 | a13 | main.rs:275:16:275:29 | print_i64(...) | | -| main.rs:279:1:293:1 | enter fn match_pattern10 | main.rs:281:5:281:20 | let ... = ... | | -| main.rs:279:1:293:1 | exit fn match_pattern10 (normal) | main.rs:279:1:293:1 | exit fn match_pattern10 | | -| main.rs:280:22:293:1 | { ... } | main.rs:279:1:293:1 | exit fn match_pattern10 (normal) | | -| main.rs:281:5:281:20 | let ... = ... | main.rs:281:12:281:15 | Some | | -| main.rs:281:9:281:9 | x | main.rs:281:9:281:9 | x | | -| main.rs:281:9:281:9 | x | main.rs:283:7:283:7 | x | match | -| main.rs:281:12:281:15 | Some | main.rs:281:17:281:18 | 42 | | -| main.rs:281:12:281:19 | Some(...) | main.rs:281:9:281:9 | x | | -| main.rs:281:17:281:18 | 42 | main.rs:281:12:281:19 | Some(...) | | -| main.rs:282:5:292:5 | if ... {...} else {...} | main.rs:280:22:293:1 | { ... } | | -| main.rs:282:8:283:7 | [boolean(false)] let ... = x | main.rs:282:8:285:9 | [boolean(false)] ... && ... | false | -| main.rs:282:8:283:7 | [boolean(true)] let ... = x | main.rs:285:5:285:5 | x | true | -| main.rs:282:8:285:9 | [boolean(false)] ... && ... | main.rs:289:9:290:14 | let ... = x | false | -| main.rs:282:8:285:9 | [boolean(true)] ... && ... | main.rs:287:9:287:21 | ExprStmt | true | -| main.rs:282:12:282:18 | Some(...) | main.rs:282:8:283:7 | [boolean(false)] let ... = x | no-match | -| main.rs:282:12:282:18 | Some(...) | main.rs:282:17:282:17 | x | match | -| main.rs:282:17:282:17 | x | main.rs:282:8:283:7 | [boolean(true)] let ... = x | match | -| main.rs:282:17:282:17 | x | main.rs:282:17:282:17 | x | | -| main.rs:283:7:283:7 | x | main.rs:282:12:282:18 | Some(...) | | -| main.rs:285:5:285:5 | x | main.rs:285:9:285:9 | 0 | | -| main.rs:285:5:285:9 | ... > ... | main.rs:282:8:285:9 | [boolean(false)] ... && ... | false | -| main.rs:285:5:285:9 | ... > ... | main.rs:282:8:285:9 | [boolean(true)] ... && ... | true | -| main.rs:285:9:285:9 | 0 | main.rs:285:5:285:9 | ... > ... | | -| main.rs:286:5:288:5 | { ... } | main.rs:282:5:292:5 | if ... {...} else {...} | | -| main.rs:287:9:287:17 | print_i64 | main.rs:287:19:287:19 | x | | -| main.rs:287:9:287:20 | print_i64(...) | main.rs:286:5:288:5 | { ... } | | -| main.rs:287:9:287:21 | ExprStmt | main.rs:287:9:287:17 | print_i64 | | -| main.rs:287:19:287:19 | x | main.rs:287:9:287:20 | print_i64(...) | | -| main.rs:288:12:292:5 | { ... } | main.rs:282:5:292:5 | if ... {...} else {...} | | -| main.rs:289:9:290:14 | let ... = x | main.rs:290:13:290:13 | x | | -| main.rs:289:13:289:13 | x | main.rs:289:13:289:13 | x | | -| main.rs:289:13:289:13 | x | main.rs:291:9:291:30 | ExprStmt | match | -| main.rs:290:13:290:13 | x | main.rs:289:13:289:13 | x | | -| main.rs:291:9:291:17 | print_i64 | main.rs:291:19:291:19 | x | | -| main.rs:291:9:291:29 | print_i64(...) | main.rs:288:12:292:5 | { ... } | | -| main.rs:291:9:291:30 | ExprStmt | main.rs:291:9:291:17 | print_i64 | | -| main.rs:291:19:291:19 | x | main.rs:291:19:291:28 | x.unwrap() | | -| main.rs:291:19:291:28 | x.unwrap() | main.rs:291:9:291:29 | print_i64(...) | | -| main.rs:295:1:312:1 | enter fn match_pattern11 | main.rs:297:5:297:21 | let ... = ... | | -| main.rs:295:1:312:1 | exit fn match_pattern11 (normal) | main.rs:295:1:312:1 | exit fn match_pattern11 | | -| main.rs:296:22:312:1 | { ... } | main.rs:295:1:312:1 | exit fn match_pattern11 (normal) | | -| main.rs:297:5:297:21 | let ... = ... | main.rs:297:13:297:16 | Some | | -| main.rs:297:9:297:9 | x | main.rs:297:9:297:9 | x | | -| main.rs:297:9:297:9 | x | main.rs:299:7:299:7 | x | match | -| main.rs:297:13:297:16 | Some | main.rs:297:18:297:19 | 42 | | -| main.rs:297:13:297:20 | Some(...) | main.rs:297:9:297:9 | x | | -| main.rs:297:18:297:19 | 42 | main.rs:297:13:297:20 | Some(...) | | -| main.rs:298:5:311:5 | if ... {...} else {...} | main.rs:296:22:312:1 | { ... } | | -| main.rs:298:8:299:7 | [boolean(false)] let ... = x | main.rs:298:8:302:13 | [boolean(false)] ... && ... | false | -| main.rs:298:8:299:7 | [boolean(true)] let ... = x | main.rs:302:7:302:10 | Some | true | -| main.rs:298:8:302:13 | [boolean(false)] ... && ... | main.rs:298:8:304:9 | [boolean(false)] ... && ... | false | -| main.rs:298:8:302:13 | [boolean(true)] ... && ... | main.rs:304:5:304:5 | x | true | -| main.rs:298:8:304:9 | [boolean(false)] ... && ... | main.rs:308:9:309:14 | let ... = x | false | -| main.rs:298:8:304:9 | [boolean(true)] ... && ... | main.rs:306:9:306:21 | ExprStmt | true | -| main.rs:298:12:298:18 | Some(...) | main.rs:298:8:299:7 | [boolean(false)] let ... = x | no-match | -| main.rs:298:12:298:18 | Some(...) | main.rs:298:17:298:17 | x | match | -| main.rs:298:17:298:17 | x | main.rs:298:8:299:7 | [boolean(true)] let ... = x | match | -| main.rs:298:17:298:17 | x | main.rs:298:17:298:17 | x | | -| main.rs:299:7:299:7 | x | main.rs:298:12:298:18 | Some(...) | | -| main.rs:301:5:302:13 | [boolean(false)] let ... = ... | main.rs:298:8:302:13 | [boolean(false)] ... && ... | false | -| main.rs:301:5:302:13 | [boolean(true)] let ... = ... | main.rs:298:8:302:13 | [boolean(true)] ... && ... | true | -| main.rs:301:9:301:15 | Some(...) | main.rs:301:5:302:13 | [boolean(false)] let ... = ... | no-match | -| main.rs:301:9:301:15 | Some(...) | main.rs:301:14:301:14 | x | match | -| main.rs:301:14:301:14 | x | main.rs:301:5:302:13 | [boolean(true)] let ... = ... | match | -| main.rs:301:14:301:14 | x | main.rs:301:14:301:14 | x | | -| main.rs:302:7:302:10 | Some | main.rs:302:12:302:12 | x | | -| main.rs:302:7:302:13 | Some(...) | main.rs:301:9:301:15 | Some(...) | | -| main.rs:302:12:302:12 | x | main.rs:302:7:302:13 | Some(...) | | -| main.rs:304:5:304:5 | x | main.rs:304:9:304:9 | 0 | | -| main.rs:304:5:304:9 | ... > ... | main.rs:298:8:304:9 | [boolean(false)] ... && ... | false | -| main.rs:304:5:304:9 | ... > ... | main.rs:298:8:304:9 | [boolean(true)] ... && ... | true | -| main.rs:304:9:304:9 | 0 | main.rs:304:5:304:9 | ... > ... | | -| main.rs:305:5:307:5 | { ... } | main.rs:298:5:311:5 | if ... {...} else {...} | | -| main.rs:306:9:306:17 | print_i64 | main.rs:306:19:306:19 | x | | -| main.rs:306:9:306:20 | print_i64(...) | main.rs:305:5:307:5 | { ... } | | -| main.rs:306:9:306:21 | ExprStmt | main.rs:306:9:306:17 | print_i64 | | -| main.rs:306:19:306:19 | x | main.rs:306:9:306:20 | print_i64(...) | | -| main.rs:307:12:311:5 | { ... } | main.rs:298:5:311:5 | if ... {...} else {...} | | -| main.rs:308:9:309:14 | let ... = x | main.rs:309:13:309:13 | x | | -| main.rs:308:13:308:13 | x | main.rs:308:13:308:13 | x | | -| main.rs:308:13:308:13 | x | main.rs:310:9:310:30 | ExprStmt | match | -| main.rs:309:13:309:13 | x | main.rs:308:13:308:13 | x | | -| main.rs:310:9:310:17 | print_i64 | main.rs:310:19:310:19 | x | | -| main.rs:310:9:310:29 | print_i64(...) | main.rs:307:12:311:5 | { ... } | | -| main.rs:310:9:310:30 | ExprStmt | main.rs:310:9:310:17 | print_i64 | | -| main.rs:310:19:310:19 | x | main.rs:310:19:310:28 | x.unwrap() | | -| main.rs:310:19:310:28 | x.unwrap() | main.rs:310:9:310:29 | print_i64(...) | | -| main.rs:314:1:330:1 | enter fn match_pattern12 | main.rs:316:5:316:21 | let ... = ... | | -| main.rs:314:1:330:1 | exit fn match_pattern12 (normal) | main.rs:314:1:330:1 | exit fn match_pattern12 | | -| main.rs:315:22:330:1 | { ... } | main.rs:314:1:330:1 | exit fn match_pattern12 (normal) | | -| main.rs:316:5:316:21 | let ... = ... | main.rs:316:13:316:16 | Some | | +| main.rs:115:11:116:11 | [boolean(false)] let ... = s | main.rs:115:5:118:5 | while ... { ... } | false | +| main.rs:115:11:116:11 | [boolean(true)] let ... = s | main.rs:117:9:117:21 | ExprStmt | true | +| main.rs:115:15:115:25 | Some(...) | main.rs:115:11:116:11 | [boolean(false)] let ... = s | no-match | +| main.rs:115:15:115:25 | Some(...) | main.rs:115:24:115:24 | s | match | +| main.rs:115:20:115:24 | ref s | main.rs:115:11:116:11 | [boolean(true)] let ... = s | match | +| main.rs:115:24:115:24 | s | main.rs:115:20:115:24 | ref s | | +| main.rs:116:11:116:11 | s | main.rs:115:15:115:25 | Some(...) | | +| main.rs:116:13:118:5 | { ... } | main.rs:116:11:116:11 | s | | +| main.rs:117:9:117:17 | print_str | main.rs:117:19:117:19 | s | | +| main.rs:117:9:117:20 | print_str(...) | main.rs:116:13:118:5 | { ... } | | +| main.rs:117:9:117:21 | ExprStmt | main.rs:117:9:117:17 | print_str | | +| main.rs:117:19:117:19 | s | main.rs:117:9:117:20 | print_str(...) | | +| main.rs:121:1:129:1 | enter fn let_pattern6 | main.rs:123:22:123:25 | Some | | +| main.rs:121:1:129:1 | exit fn let_pattern6 (normal) | main.rs:121:1:129:1 | exit fn let_pattern6 | | +| main.rs:122:19:129:1 | { ... } | main.rs:121:1:129:1 | exit fn let_pattern6 (normal) | | +| main.rs:123:5:128:5 | if ... {...} | main.rs:122:19:129:1 | { ... } | | +| main.rs:123:8:123:29 | [boolean(false)] let ... = ... | main.rs:123:8:125:26 | [boolean(false)] ... && ... | false | +| main.rs:123:8:123:29 | [boolean(true)] let ... = ... | main.rs:125:13:125:23 | Ok::<...> | true | +| main.rs:123:8:125:26 | [boolean(false)] ... && ... | main.rs:123:5:128:5 | if ... {...} | false | +| main.rs:123:8:125:26 | [boolean(true)] ... && ... | main.rs:127:9:127:21 | ExprStmt | true | +| main.rs:123:12:123:18 | Some(...) | main.rs:123:8:123:29 | [boolean(false)] let ... = ... | no-match | +| main.rs:123:12:123:18 | Some(...) | main.rs:123:17:123:17 | x | match | +| main.rs:123:17:123:17 | x | main.rs:123:8:123:29 | [boolean(true)] let ... = ... | match | +| main.rs:123:17:123:17 | x | main.rs:123:17:123:17 | x | | +| main.rs:123:22:123:25 | Some | main.rs:123:27:123:28 | 43 | | +| main.rs:123:22:123:29 | Some(...) | main.rs:123:12:123:18 | Some(...) | | +| main.rs:123:27:123:28 | 43 | main.rs:123:22:123:29 | Some(...) | | +| main.rs:124:12:125:26 | [boolean(false)] let ... = ... | main.rs:123:8:125:26 | [boolean(false)] ... && ... | false | +| main.rs:124:12:125:26 | [boolean(true)] let ... = ... | main.rs:123:8:125:26 | [boolean(true)] ... && ... | true | +| main.rs:124:16:124:20 | Ok(...) | main.rs:124:12:125:26 | [boolean(false)] let ... = ... | no-match | +| main.rs:124:16:124:20 | Ok(...) | main.rs:124:19:124:19 | x | match | +| main.rs:124:19:124:19 | x | main.rs:124:12:125:26 | [boolean(true)] let ... = ... | match | +| main.rs:124:19:124:19 | x | main.rs:124:19:124:19 | x | | +| main.rs:125:13:125:23 | Ok::<...> | main.rs:125:25:125:25 | x | | +| main.rs:125:13:125:26 | Ok::<...>(...) | main.rs:124:16:124:20 | Ok(...) | | +| main.rs:125:25:125:25 | x | main.rs:125:13:125:26 | Ok::<...>(...) | | +| main.rs:126:5:128:5 | { ... } | main.rs:123:5:128:5 | if ... {...} | | +| main.rs:127:9:127:17 | print_i64 | main.rs:127:19:127:19 | x | | +| main.rs:127:9:127:20 | print_i64(...) | main.rs:126:5:128:5 | { ... } | | +| main.rs:127:9:127:21 | ExprStmt | main.rs:127:9:127:17 | print_i64 | | +| main.rs:127:19:127:19 | x | main.rs:127:9:127:20 | print_i64(...) | | +| main.rs:131:1:154:1 | enter fn let_pattern7 | main.rs:133:5:133:14 | let ... = 1 | | +| main.rs:131:1:154:1 | exit fn let_pattern7 (normal) | main.rs:131:1:154:1 | exit fn let_pattern7 | | +| main.rs:132:19:154:1 | { ... } | main.rs:131:1:154:1 | exit fn let_pattern7 (normal) | | +| main.rs:133:5:133:14 | let ... = 1 | main.rs:133:13:133:13 | 1 | | +| main.rs:133:9:133:9 | x | main.rs:133:9:133:9 | x | | +| main.rs:133:9:133:9 | x | main.rs:135:9:135:9 | x | match | +| main.rs:133:13:133:13 | 1 | main.rs:133:9:133:9 | x | | +| main.rs:134:5:153:5 | if ... {...} else {...} | main.rs:132:19:154:1 | { ... } | | +| main.rs:134:8:135:13 | [boolean(true)] let ... = ... | main.rs:137:9:137:9 | x | true | +| main.rs:134:8:137:13 | [boolean(true)] ... && ... | main.rs:139:9:139:9 | x | true | +| main.rs:134:8:139:13 | [boolean(true)] ... && ... | main.rs:141:9:141:9 | x | true | +| main.rs:134:8:141:13 | [boolean(true)] ... && ... | main.rs:143:9:143:9 | x | true | +| main.rs:134:8:143:13 | [boolean(true)] ... && ... | main.rs:145:9:145:9 | x | true | +| main.rs:134:8:145:13 | [boolean(true)] ... && ... | main.rs:147:9:147:9 | x | true | +| main.rs:134:8:147:13 | [boolean(true)] ... && ... | main.rs:149:9:149:21 | ExprStmt | true | +| main.rs:134:12:134:12 | x | main.rs:134:8:135:13 | [boolean(true)] let ... = ... | match | +| main.rs:134:12:134:12 | x | main.rs:134:12:134:12 | x | | +| main.rs:135:9:135:9 | x | main.rs:135:13:135:13 | 1 | | +| main.rs:135:9:135:13 | ... + ... | main.rs:134:12:134:12 | x | | +| main.rs:135:13:135:13 | 1 | main.rs:135:9:135:13 | ... + ... | | +| main.rs:136:8:137:13 | [boolean(true)] let ... = ... | main.rs:134:8:137:13 | [boolean(true)] ... && ... | true | +| main.rs:136:12:136:12 | x | main.rs:136:8:137:13 | [boolean(true)] let ... = ... | match | +| main.rs:136:12:136:12 | x | main.rs:136:12:136:12 | x | | +| main.rs:137:9:137:9 | x | main.rs:137:13:137:13 | 1 | | +| main.rs:137:9:137:13 | ... + ... | main.rs:136:12:136:12 | x | | +| main.rs:137:13:137:13 | 1 | main.rs:137:9:137:13 | ... + ... | | +| main.rs:138:8:139:13 | [boolean(true)] let ... = ... | main.rs:134:8:139:13 | [boolean(true)] ... && ... | true | +| main.rs:138:12:138:12 | x | main.rs:138:8:139:13 | [boolean(true)] let ... = ... | match | +| main.rs:138:12:138:12 | x | main.rs:138:12:138:12 | x | | +| main.rs:139:9:139:9 | x | main.rs:139:13:139:13 | 1 | | +| main.rs:139:9:139:13 | ... + ... | main.rs:138:12:138:12 | x | | +| main.rs:139:13:139:13 | 1 | main.rs:139:9:139:13 | ... + ... | | +| main.rs:140:8:141:13 | [boolean(true)] let ... = ... | main.rs:134:8:141:13 | [boolean(true)] ... && ... | true | +| main.rs:140:12:140:12 | x | main.rs:140:8:141:13 | [boolean(true)] let ... = ... | match | +| main.rs:140:12:140:12 | x | main.rs:140:12:140:12 | x | | +| main.rs:141:9:141:9 | x | main.rs:141:13:141:13 | 1 | | +| main.rs:141:9:141:13 | ... + ... | main.rs:140:12:140:12 | x | | +| main.rs:141:13:141:13 | 1 | main.rs:141:9:141:13 | ... + ... | | +| main.rs:142:8:143:13 | [boolean(true)] let ... = ... | main.rs:134:8:143:13 | [boolean(true)] ... && ... | true | +| main.rs:142:12:142:12 | x | main.rs:142:8:143:13 | [boolean(true)] let ... = ... | match | +| main.rs:142:12:142:12 | x | main.rs:142:12:142:12 | x | | +| main.rs:143:9:143:9 | x | main.rs:143:13:143:13 | 1 | | +| main.rs:143:9:143:13 | ... + ... | main.rs:142:12:142:12 | x | | +| main.rs:143:13:143:13 | 1 | main.rs:143:9:143:13 | ... + ... | | +| main.rs:144:8:145:13 | [boolean(true)] let ... = ... | main.rs:134:8:145:13 | [boolean(true)] ... && ... | true | +| main.rs:144:12:144:12 | x | main.rs:144:8:145:13 | [boolean(true)] let ... = ... | match | +| main.rs:144:12:144:12 | x | main.rs:144:12:144:12 | x | | +| main.rs:145:9:145:9 | x | main.rs:145:13:145:13 | 1 | | +| main.rs:145:9:145:13 | ... + ... | main.rs:144:12:144:12 | x | | +| main.rs:145:13:145:13 | 1 | main.rs:145:9:145:13 | ... + ... | | +| main.rs:146:8:147:13 | [boolean(true)] let ... = ... | main.rs:134:8:147:13 | [boolean(true)] ... && ... | true | +| main.rs:146:12:146:12 | x | main.rs:146:8:147:13 | [boolean(true)] let ... = ... | match | +| main.rs:146:12:146:12 | x | main.rs:146:12:146:12 | x | | +| main.rs:147:9:147:9 | x | main.rs:147:13:147:13 | 1 | | +| main.rs:147:9:147:13 | ... + ... | main.rs:146:12:146:12 | x | | +| main.rs:147:13:147:13 | 1 | main.rs:147:9:147:13 | ... + ... | | +| main.rs:148:5:150:5 | { ... } | main.rs:134:5:153:5 | if ... {...} else {...} | | +| main.rs:149:9:149:17 | print_i64 | main.rs:149:19:149:19 | x | | +| main.rs:149:9:149:20 | print_i64(...) | main.rs:148:5:150:5 | { ... } | | +| main.rs:149:9:149:21 | ExprStmt | main.rs:149:9:149:17 | print_i64 | | +| main.rs:149:19:149:19 | x | main.rs:149:9:149:20 | print_i64(...) | | +| main.rs:156:1:171:1 | enter fn match_pattern1 | main.rs:157:5:157:21 | let ... = ... | | +| main.rs:156:1:171:1 | exit fn match_pattern1 (normal) | main.rs:156:1:171:1 | exit fn match_pattern1 | | +| main.rs:156:21:171:1 | { ... } | main.rs:156:1:171:1 | exit fn match_pattern1 (normal) | | +| main.rs:157:5:157:21 | let ... = ... | main.rs:157:14:157:17 | Some | | +| main.rs:157:9:157:10 | x6 | main.rs:157:9:157:10 | x6 | | +| main.rs:157:9:157:10 | x6 | main.rs:158:5:158:16 | let ... = 10 | match | +| main.rs:157:14:157:17 | Some | main.rs:157:19:157:19 | 5 | | +| main.rs:157:14:157:20 | Some(...) | main.rs:157:9:157:10 | x6 | | +| main.rs:157:19:157:19 | 5 | main.rs:157:14:157:20 | Some(...) | | +| main.rs:158:5:158:16 | let ... = 10 | main.rs:158:14:158:15 | 10 | | +| main.rs:158:9:158:10 | y1 | main.rs:158:9:158:10 | y1 | | +| main.rs:158:9:158:10 | y1 | main.rs:160:5:168:5 | ExprStmt | match | +| main.rs:158:14:158:15 | 10 | main.rs:158:9:158:10 | y1 | | +| main.rs:160:5:168:5 | ExprStmt | main.rs:160:11:160:12 | x6 | | +| main.rs:160:5:168:5 | match x6 { ... } | main.rs:170:5:170:18 | ExprStmt | | +| main.rs:160:11:160:12 | x6 | main.rs:161:9:161:16 | Some(...) | | +| main.rs:161:9:161:16 | Some(...) | main.rs:161:14:161:15 | 50 | match | +| main.rs:161:9:161:16 | Some(...) | main.rs:162:9:162:16 | Some(...) | no-match | +| main.rs:161:14:161:15 | 50 | main.rs:161:14:161:15 | 50 | | +| main.rs:161:14:161:15 | 50 | main.rs:161:21:161:29 | print_str | match | +| main.rs:161:14:161:15 | 50 | main.rs:162:9:162:16 | Some(...) | no-match | +| main.rs:161:21:161:29 | print_str | main.rs:161:31:161:38 | "Got 50" | | +| main.rs:161:21:161:39 | print_str(...) | main.rs:160:5:168:5 | match x6 { ... } | | +| main.rs:161:31:161:38 | "Got 50" | main.rs:161:21:161:39 | print_str(...) | | +| main.rs:162:9:162:16 | Some(...) | main.rs:162:14:162:15 | y1 | match | +| main.rs:162:9:162:16 | Some(...) | main.rs:167:9:167:12 | None | no-match | +| main.rs:162:14:162:15 | y1 | main.rs:162:14:162:15 | y1 | | +| main.rs:162:14:162:15 | y1 | main.rs:165:13:165:21 | print_i64 | match | +| main.rs:164:9:166:9 | { ... } | main.rs:160:5:168:5 | match x6 { ... } | | +| main.rs:165:13:165:21 | print_i64 | main.rs:165:23:165:24 | y1 | | +| main.rs:165:13:165:25 | print_i64(...) | main.rs:164:9:166:9 | { ... } | | +| main.rs:165:23:165:24 | y1 | main.rs:165:13:165:25 | print_i64(...) | | +| main.rs:167:9:167:12 | None | main.rs:167:9:167:12 | None | | +| main.rs:167:9:167:12 | None | main.rs:167:17:167:25 | print_str | match | +| main.rs:167:17:167:25 | print_str | main.rs:167:27:167:32 | "NONE" | | +| main.rs:167:17:167:33 | print_str(...) | main.rs:160:5:168:5 | match x6 { ... } | | +| main.rs:167:27:167:32 | "NONE" | main.rs:167:17:167:33 | print_str(...) | | +| main.rs:170:5:170:13 | print_i64 | main.rs:170:15:170:16 | y1 | | +| main.rs:170:5:170:17 | print_i64(...) | main.rs:156:21:171:1 | { ... } | | +| main.rs:170:5:170:18 | ExprStmt | main.rs:170:5:170:13 | print_i64 | | +| main.rs:170:15:170:16 | y1 | main.rs:170:5:170:17 | print_i64(...) | | +| main.rs:173:1:202:1 | enter fn match_pattern2 | main.rs:174:5:174:36 | let ... = ... | | +| main.rs:173:1:202:1 | exit fn match_pattern2 (normal) | main.rs:173:1:202:1 | exit fn match_pattern2 | | +| main.rs:173:21:202:1 | { ... } | main.rs:173:1:202:1 | exit fn match_pattern2 (normal) | | +| main.rs:174:5:174:36 | let ... = ... | main.rs:174:20:174:20 | 2 | | +| main.rs:174:9:174:15 | numbers | main.rs:174:9:174:15 | numbers | | +| main.rs:174:9:174:15 | numbers | main.rs:176:5:189:5 | ExprStmt | match | +| main.rs:174:19:174:35 | TupleExpr | main.rs:174:9:174:15 | numbers | | +| main.rs:174:20:174:20 | 2 | main.rs:174:23:174:23 | 4 | | +| main.rs:174:23:174:23 | 4 | main.rs:174:26:174:26 | 8 | | +| main.rs:174:26:174:26 | 8 | main.rs:174:29:174:30 | 16 | | +| main.rs:174:29:174:30 | 16 | main.rs:174:33:174:34 | 32 | | +| main.rs:174:33:174:34 | 32 | main.rs:174:19:174:35 | TupleExpr | | +| main.rs:176:5:189:5 | ExprStmt | main.rs:176:11:176:17 | numbers | | +| main.rs:176:5:189:5 | match numbers { ... } | main.rs:191:11:191:17 | numbers | | +| main.rs:176:11:176:17 | numbers | main.rs:178:9:184:9 | TuplePat | | +| main.rs:178:9:184:9 | TuplePat | main.rs:179:13:179:17 | first | match | +| main.rs:179:13:179:17 | first | main.rs:179:13:179:17 | first | | +| main.rs:179:13:179:17 | first | main.rs:180:13:180:13 | _ | match | +| main.rs:180:13:180:13 | _ | main.rs:181:13:181:17 | third | match | +| main.rs:181:13:181:17 | third | main.rs:181:13:181:17 | third | | +| main.rs:181:13:181:17 | third | main.rs:182:13:182:13 | _ | match | +| main.rs:182:13:182:13 | _ | main.rs:183:13:183:17 | fifth | match | +| main.rs:183:13:183:17 | fifth | main.rs:183:13:183:17 | fifth | | +| main.rs:183:13:183:17 | fifth | main.rs:185:13:185:29 | ExprStmt | match | +| main.rs:184:14:188:9 | { ... } | main.rs:176:5:189:5 | match numbers { ... } | | +| main.rs:185:13:185:21 | print_i64 | main.rs:185:23:185:27 | first | | +| main.rs:185:13:185:28 | print_i64(...) | main.rs:186:13:186:29 | ExprStmt | | +| main.rs:185:13:185:29 | ExprStmt | main.rs:185:13:185:21 | print_i64 | | +| main.rs:185:23:185:27 | first | main.rs:185:13:185:28 | print_i64(...) | | +| main.rs:186:13:186:21 | print_i64 | main.rs:186:23:186:27 | third | | +| main.rs:186:13:186:28 | print_i64(...) | main.rs:187:13:187:29 | ExprStmt | | +| main.rs:186:13:186:29 | ExprStmt | main.rs:186:13:186:21 | print_i64 | | +| main.rs:186:23:186:27 | third | main.rs:186:13:186:28 | print_i64(...) | | +| main.rs:187:13:187:21 | print_i64 | main.rs:187:23:187:27 | fifth | | +| main.rs:187:13:187:28 | print_i64(...) | main.rs:184:14:188:9 | { ... } | | +| main.rs:187:13:187:29 | ExprStmt | main.rs:187:13:187:21 | print_i64 | | +| main.rs:187:23:187:27 | fifth | main.rs:187:13:187:28 | print_i64(...) | | +| main.rs:191:5:201:5 | match numbers { ... } | main.rs:173:21:202:1 | { ... } | | +| main.rs:191:11:191:17 | numbers | main.rs:193:9:197:9 | TuplePat | | +| main.rs:193:9:197:9 | TuplePat | main.rs:194:13:194:17 | first | match | +| main.rs:194:13:194:17 | first | main.rs:194:13:194:17 | first | | +| main.rs:194:13:194:17 | first | main.rs:195:13:195:14 | .. | match | +| main.rs:195:13:195:14 | .. | main.rs:196:13:196:16 | last | match | +| main.rs:196:13:196:16 | last | main.rs:196:13:196:16 | last | | +| main.rs:196:13:196:16 | last | main.rs:198:13:198:29 | ExprStmt | match | +| main.rs:197:14:200:9 | { ... } | main.rs:191:5:201:5 | match numbers { ... } | | +| main.rs:198:13:198:21 | print_i64 | main.rs:198:23:198:27 | first | | +| main.rs:198:13:198:28 | print_i64(...) | main.rs:199:13:199:28 | ExprStmt | | +| main.rs:198:13:198:29 | ExprStmt | main.rs:198:13:198:21 | print_i64 | | +| main.rs:198:23:198:27 | first | main.rs:198:13:198:28 | print_i64(...) | | +| main.rs:199:13:199:21 | print_i64 | main.rs:199:23:199:26 | last | | +| main.rs:199:13:199:27 | print_i64(...) | main.rs:197:14:200:9 | { ... } | | +| main.rs:199:13:199:28 | ExprStmt | main.rs:199:13:199:21 | print_i64 | | +| main.rs:199:23:199:26 | last | main.rs:199:13:199:27 | print_i64(...) | | +| main.rs:204:1:212:1 | enter fn match_pattern3 | main.rs:205:5:205:38 | let ... = ... | | +| main.rs:204:1:212:1 | exit fn match_pattern3 (normal) | main.rs:204:1:212:1 | exit fn match_pattern3 | | +| main.rs:204:21:212:1 | { ... } | main.rs:204:1:212:1 | exit fn match_pattern3 (normal) | | +| main.rs:205:5:205:38 | let ... = ... | main.rs:205:25:205:27 | "x" | | +| main.rs:205:9:205:10 | p2 | main.rs:205:9:205:10 | p2 | | +| main.rs:205:9:205:10 | p2 | main.rs:207:11:207:12 | p2 | match | +| main.rs:205:14:205:37 | Point {...} | main.rs:205:9:205:10 | p2 | | +| main.rs:205:25:205:27 | "x" | main.rs:205:33:205:35 | "y" | | +| main.rs:205:33:205:35 | "y" | main.rs:205:14:205:37 | Point {...} | | +| main.rs:207:5:211:5 | match p2 { ... } | main.rs:204:21:212:1 | { ... } | | +| main.rs:207:11:207:12 | p2 | main.rs:208:9:210:9 | Point {...} | | +| main.rs:208:9:210:9 | Point {...} | main.rs:209:16:209:17 | x7 | match | +| main.rs:209:16:209:17 | x7 | main.rs:209:16:209:17 | x7 | | +| main.rs:209:16:209:17 | x7 | main.rs:209:20:209:21 | .. | match | +| main.rs:209:20:209:21 | .. | main.rs:210:14:210:22 | print_str | match | +| main.rs:210:14:210:22 | print_str | main.rs:210:24:210:25 | x7 | | +| main.rs:210:14:210:26 | print_str(...) | main.rs:207:5:211:5 | match p2 { ... } | | +| main.rs:210:24:210:25 | x7 | main.rs:210:14:210:26 | print_str(...) | | +| main.rs:218:1:235:1 | enter fn match_pattern4 | main.rs:219:5:219:39 | let ... = ... | | +| main.rs:218:1:235:1 | exit fn match_pattern4 (normal) | main.rs:218:1:235:1 | exit fn match_pattern4 | | +| main.rs:218:21:235:1 | { ... } | main.rs:218:1:235:1 | exit fn match_pattern4 (normal) | | +| main.rs:219:5:219:39 | let ... = ... | main.rs:219:36:219:36 | 0 | | +| main.rs:219:9:219:11 | msg | main.rs:219:9:219:11 | msg | | +| main.rs:219:9:219:11 | msg | main.rs:221:11:221:13 | msg | match | +| main.rs:219:15:219:38 | ...::Hello {...} | main.rs:219:9:219:11 | msg | | +| main.rs:219:36:219:36 | 0 | main.rs:219:15:219:38 | ...::Hello {...} | | +| main.rs:221:5:234:5 | match msg { ... } | main.rs:218:21:235:1 | { ... } | | +| main.rs:221:11:221:13 | msg | main.rs:223:9:225:9 | ...::Hello {...} | | +| main.rs:223:9:225:9 | ...::Hello {...} | main.rs:224:31:224:35 | RangePat | match | +| main.rs:223:9:225:9 | ...::Hello {...} | main.rs:226:9:226:38 | ...::Hello {...} | no-match | +| main.rs:224:17:224:27 | id_variable | main.rs:224:17:224:35 | id_variable @ ... | | +| main.rs:224:17:224:35 | id_variable @ ... | main.rs:225:14:225:22 | print_i64 | match | +| main.rs:224:31:224:31 | 3 | main.rs:224:31:224:31 | 3 | | +| main.rs:224:31:224:31 | 3 | main.rs:224:35:224:35 | 7 | match | +| main.rs:224:31:224:31 | 3 | main.rs:226:9:226:38 | ...::Hello {...} | no-match | +| main.rs:224:31:224:35 | RangePat | main.rs:224:31:224:31 | 3 | match | +| main.rs:224:35:224:35 | 7 | main.rs:224:17:224:27 | id_variable | match | +| main.rs:224:35:224:35 | 7 | main.rs:224:35:224:35 | 7 | | +| main.rs:224:35:224:35 | 7 | main.rs:226:9:226:38 | ...::Hello {...} | no-match | +| main.rs:225:14:225:22 | print_i64 | main.rs:225:24:225:34 | id_variable | | +| main.rs:225:14:225:35 | print_i64(...) | main.rs:221:5:234:5 | match msg { ... } | | +| main.rs:225:24:225:34 | id_variable | main.rs:225:14:225:35 | print_i64(...) | | +| main.rs:226:9:226:38 | ...::Hello {...} | main.rs:226:30:226:36 | RangePat | match | +| main.rs:226:9:226:38 | ...::Hello {...} | main.rs:229:9:229:29 | ...::Hello {...} | no-match | +| main.rs:226:30:226:31 | 10 | main.rs:226:30:226:31 | 10 | | +| main.rs:226:30:226:31 | 10 | main.rs:226:35:226:36 | 12 | match | +| main.rs:226:30:226:31 | 10 | main.rs:229:9:229:29 | ...::Hello {...} | no-match | +| main.rs:226:30:226:36 | RangePat | main.rs:226:30:226:31 | 10 | match | +| main.rs:226:35:226:36 | 12 | main.rs:226:35:226:36 | 12 | | +| main.rs:226:35:226:36 | 12 | main.rs:227:22:227:51 | ExprStmt | match | +| main.rs:226:35:226:36 | 12 | main.rs:229:9:229:29 | ...::Hello {...} | no-match | +| main.rs:226:43:228:9 | { ... } | main.rs:221:5:234:5 | match msg { ... } | | +| main.rs:227:13:227:20 | ...::_print | main.rs:227:22:227:51 | "Found an id in another range\\... | | +| main.rs:227:13:227:52 | MacroExpr | main.rs:226:43:228:9 | { ... } | | +| main.rs:227:13:227:52 | println!... | main.rs:227:13:227:52 | MacroExpr | | +| main.rs:227:22:227:51 | "Found an id in another range\\... | main.rs:227:22:227:51 | FormatArgsExpr | | +| main.rs:227:22:227:51 | ...::_print(...) | main.rs:227:22:227:51 | { ... } | | +| main.rs:227:22:227:51 | ...::format_args_nl!... | main.rs:227:22:227:51 | MacroExpr | | +| main.rs:227:22:227:51 | ExprStmt | main.rs:227:13:227:20 | ...::_print | | +| main.rs:227:22:227:51 | FormatArgsExpr | main.rs:227:22:227:51 | ...::format_args_nl!... | | +| main.rs:227:22:227:51 | MacroExpr | main.rs:227:22:227:51 | ...::_print(...) | | +| main.rs:227:22:227:51 | { ... } | main.rs:227:13:227:52 | println!... | | +| main.rs:227:22:227:51 | { ... } | main.rs:227:22:227:51 | { ... } | | +| main.rs:229:9:229:29 | ...::Hello {...} | main.rs:229:26:229:27 | id | match | +| main.rs:229:26:229:27 | id | main.rs:229:26:229:27 | id | | +| main.rs:229:26:229:27 | id | main.rs:232:13:232:21 | print_i64 | match | +| main.rs:231:9:233:9 | { ... } | main.rs:221:5:234:5 | match msg { ... } | | +| main.rs:232:13:232:21 | print_i64 | main.rs:232:23:232:24 | id | | +| main.rs:232:13:232:25 | print_i64(...) | main.rs:231:9:233:9 | { ... } | | +| main.rs:232:23:232:24 | id | main.rs:232:13:232:25 | print_i64(...) | | +| main.rs:242:1:248:1 | enter fn match_pattern5 | main.rs:243:5:243:34 | let ... = ... | | +| main.rs:242:1:248:1 | exit fn match_pattern5 (normal) | main.rs:242:1:248:1 | exit fn match_pattern5 | | +| main.rs:242:21:248:1 | { ... } | main.rs:242:1:248:1 | exit fn match_pattern5 (normal) | | +| main.rs:243:5:243:34 | let ... = ... | main.rs:243:18:243:29 | ...::Left | | +| main.rs:243:9:243:14 | either | main.rs:243:9:243:14 | either | | +| main.rs:243:9:243:14 | either | main.rs:244:11:244:16 | either | match | +| main.rs:243:18:243:29 | ...::Left | main.rs:243:31:243:32 | 32 | | +| main.rs:243:18:243:33 | ...::Left(...) | main.rs:243:9:243:14 | either | | +| main.rs:243:31:243:32 | 32 | main.rs:243:18:243:33 | ...::Left(...) | | +| main.rs:244:5:247:5 | match either { ... } | main.rs:242:21:248:1 | { ... } | | +| main.rs:244:11:244:16 | either | main.rs:245:9:245:24 | ...::Left(...) | | +| main.rs:245:9:245:24 | ...::Left(...) | main.rs:245:22:245:23 | a3 | match | +| main.rs:245:9:245:24 | ...::Left(...) | main.rs:245:28:245:44 | ...::Right(...) | no-match | +| main.rs:245:9:245:44 | ... \| ... | main.rs:246:16:246:24 | print_i64 | match | +| main.rs:245:22:245:23 | a3 | main.rs:245:9:245:44 | ... \| ... | match | +| main.rs:245:22:245:23 | a3 | main.rs:245:22:245:23 | a3 | | +| main.rs:245:28:245:44 | ...::Right(...) | main.rs:245:42:245:43 | a3 | match | +| main.rs:245:42:245:43 | a3 | main.rs:245:9:245:44 | ... \| ... | match | +| main.rs:245:42:245:43 | a3 | main.rs:245:42:245:43 | a3 | | +| main.rs:246:16:246:24 | print_i64 | main.rs:246:26:246:27 | a3 | | +| main.rs:246:16:246:28 | print_i64(...) | main.rs:244:5:247:5 | match either { ... } | | +| main.rs:246:26:246:27 | a3 | main.rs:246:16:246:28 | print_i64(...) | | +| main.rs:256:1:270:1 | enter fn match_pattern6 | main.rs:257:5:257:37 | let ... = ... | | +| main.rs:256:1:270:1 | exit fn match_pattern6 (normal) | main.rs:256:1:270:1 | exit fn match_pattern6 | | +| main.rs:256:21:270:1 | { ... } | main.rs:256:1:270:1 | exit fn match_pattern6 (normal) | | +| main.rs:257:5:257:37 | let ... = ... | main.rs:257:14:257:32 | ...::Second | | +| main.rs:257:9:257:10 | tv | main.rs:257:9:257:10 | tv | | +| main.rs:257:9:257:10 | tv | main.rs:258:5:261:5 | ExprStmt | match | +| main.rs:257:14:257:32 | ...::Second | main.rs:257:34:257:35 | 62 | | +| main.rs:257:14:257:36 | ...::Second(...) | main.rs:257:9:257:10 | tv | | +| main.rs:257:34:257:35 | 62 | main.rs:257:14:257:36 | ...::Second(...) | | +| main.rs:258:5:261:5 | ExprStmt | main.rs:258:11:258:12 | tv | | +| main.rs:258:5:261:5 | match tv { ... } | main.rs:262:5:265:5 | ExprStmt | | +| main.rs:258:11:258:12 | tv | main.rs:259:9:259:30 | ...::First(...) | | +| main.rs:259:9:259:30 | ...::First(...) | main.rs:259:28:259:29 | a4 | match | +| main.rs:259:9:259:30 | ...::First(...) | main.rs:259:34:259:56 | ...::Second(...) | no-match | +| main.rs:259:9:259:81 | ... \| ... \| ... | main.rs:260:16:260:24 | print_i64 | match | +| main.rs:259:28:259:29 | a4 | main.rs:259:9:259:81 | ... \| ... \| ... | match | +| main.rs:259:28:259:29 | a4 | main.rs:259:28:259:29 | a4 | | +| main.rs:259:34:259:56 | ...::Second(...) | main.rs:259:54:259:55 | a4 | match | +| main.rs:259:34:259:56 | ...::Second(...) | main.rs:259:60:259:81 | ...::Third(...) | no-match | +| main.rs:259:54:259:55 | a4 | main.rs:259:9:259:81 | ... \| ... \| ... | match | +| main.rs:259:54:259:55 | a4 | main.rs:259:54:259:55 | a4 | | +| main.rs:259:60:259:81 | ...::Third(...) | main.rs:259:79:259:80 | a4 | match | +| main.rs:259:79:259:80 | a4 | main.rs:259:9:259:81 | ... \| ... \| ... | match | +| main.rs:259:79:259:80 | a4 | main.rs:259:79:259:80 | a4 | | +| main.rs:260:16:260:24 | print_i64 | main.rs:260:26:260:27 | a4 | | +| main.rs:260:16:260:28 | print_i64(...) | main.rs:258:5:261:5 | match tv { ... } | | +| main.rs:260:26:260:27 | a4 | main.rs:260:16:260:28 | print_i64(...) | | +| main.rs:262:5:265:5 | ExprStmt | main.rs:262:11:262:12 | tv | | +| main.rs:262:5:265:5 | match tv { ... } | main.rs:266:11:266:12 | tv | | +| main.rs:262:11:262:12 | tv | main.rs:263:10:263:31 | ...::First(...) | | +| main.rs:263:9:263:83 | ... \| ... | main.rs:264:16:264:24 | print_i64 | match | +| main.rs:263:10:263:31 | ...::First(...) | main.rs:263:29:263:30 | a5 | match | +| main.rs:263:10:263:31 | ...::First(...) | main.rs:263:35:263:57 | ...::Second(...) | no-match | +| main.rs:263:10:263:57 | [match(false)] ... \| ... | main.rs:263:62:263:83 | ...::Third(...) | no-match | +| main.rs:263:10:263:57 | [match(true)] ... \| ... | main.rs:263:9:263:83 | ... \| ... | match | +| main.rs:263:29:263:30 | a5 | main.rs:263:10:263:57 | [match(true)] ... \| ... | match | +| main.rs:263:29:263:30 | a5 | main.rs:263:29:263:30 | a5 | | +| main.rs:263:35:263:57 | ...::Second(...) | main.rs:263:10:263:57 | [match(false)] ... \| ... | no-match | +| main.rs:263:35:263:57 | ...::Second(...) | main.rs:263:55:263:56 | a5 | match | +| main.rs:263:55:263:56 | a5 | main.rs:263:10:263:57 | [match(true)] ... \| ... | match | +| main.rs:263:55:263:56 | a5 | main.rs:263:55:263:56 | a5 | | +| main.rs:263:62:263:83 | ...::Third(...) | main.rs:263:81:263:82 | a5 | match | +| main.rs:263:81:263:82 | a5 | main.rs:263:9:263:83 | ... \| ... | match | +| main.rs:263:81:263:82 | a5 | main.rs:263:81:263:82 | a5 | | +| main.rs:264:16:264:24 | print_i64 | main.rs:264:26:264:27 | a5 | | +| main.rs:264:16:264:28 | print_i64(...) | main.rs:262:5:265:5 | match tv { ... } | | +| main.rs:264:26:264:27 | a5 | main.rs:264:16:264:28 | print_i64(...) | | +| main.rs:266:5:269:5 | match tv { ... } | main.rs:256:21:270:1 | { ... } | | +| main.rs:266:11:266:12 | tv | main.rs:267:9:267:30 | ...::First(...) | | +| main.rs:267:9:267:30 | ...::First(...) | main.rs:267:28:267:29 | a6 | match | +| main.rs:267:9:267:30 | ...::First(...) | main.rs:267:35:267:57 | ...::Second(...) | no-match | +| main.rs:267:9:267:83 | ... \| ... | main.rs:268:16:268:24 | print_i64 | match | +| main.rs:267:28:267:29 | a6 | main.rs:267:9:267:83 | ... \| ... | match | +| main.rs:267:28:267:29 | a6 | main.rs:267:28:267:29 | a6 | | +| main.rs:267:35:267:57 | ...::Second(...) | main.rs:267:55:267:56 | a6 | match | +| main.rs:267:35:267:57 | ...::Second(...) | main.rs:267:61:267:82 | ...::Third(...) | no-match | +| main.rs:267:35:267:82 | ... \| ... | main.rs:267:9:267:83 | ... \| ... | match | +| main.rs:267:55:267:56 | a6 | main.rs:267:35:267:82 | ... \| ... | match | +| main.rs:267:55:267:56 | a6 | main.rs:267:55:267:56 | a6 | | +| main.rs:267:61:267:82 | ...::Third(...) | main.rs:267:80:267:81 | a6 | match | +| main.rs:267:80:267:81 | a6 | main.rs:267:35:267:82 | ... \| ... | match | +| main.rs:267:80:267:81 | a6 | main.rs:267:80:267:81 | a6 | | +| main.rs:268:16:268:24 | print_i64 | main.rs:268:26:268:27 | a6 | | +| main.rs:268:16:268:28 | print_i64(...) | main.rs:266:5:269:5 | match tv { ... } | | +| main.rs:268:26:268:27 | a6 | main.rs:268:16:268:28 | print_i64(...) | | +| main.rs:272:1:280:1 | enter fn match_pattern7 | main.rs:273:5:273:34 | let ... = ... | | +| main.rs:272:1:280:1 | exit fn match_pattern7 (normal) | main.rs:272:1:280:1 | exit fn match_pattern7 | | +| main.rs:272:21:280:1 | { ... } | main.rs:272:1:280:1 | exit fn match_pattern7 (normal) | | +| main.rs:273:5:273:34 | let ... = ... | main.rs:273:18:273:29 | ...::Left | | +| main.rs:273:9:273:14 | either | main.rs:273:9:273:14 | either | | +| main.rs:273:9:273:14 | either | main.rs:274:11:274:16 | either | match | +| main.rs:273:18:273:29 | ...::Left | main.rs:273:31:273:32 | 32 | | +| main.rs:273:18:273:33 | ...::Left(...) | main.rs:273:9:273:14 | either | | +| main.rs:273:31:273:32 | 32 | main.rs:273:18:273:33 | ...::Left(...) | | +| main.rs:274:5:279:5 | match either { ... } | main.rs:272:21:280:1 | { ... } | | +| main.rs:274:11:274:16 | either | main.rs:275:9:275:24 | ...::Left(...) | | +| main.rs:275:9:275:24 | ...::Left(...) | main.rs:275:22:275:23 | a7 | match | +| main.rs:275:9:275:24 | ...::Left(...) | main.rs:275:28:275:44 | ...::Right(...) | no-match | +| main.rs:275:9:275:44 | [match(false)] ... \| ... | main.rs:278:9:278:9 | _ | no-match | +| main.rs:275:9:275:44 | [match(true)] ... \| ... | main.rs:276:16:276:17 | a7 | match | +| main.rs:275:22:275:23 | a7 | main.rs:275:9:275:44 | [match(true)] ... \| ... | match | +| main.rs:275:22:275:23 | a7 | main.rs:275:22:275:23 | a7 | | +| main.rs:275:28:275:44 | ...::Right(...) | main.rs:275:9:275:44 | [match(false)] ... \| ... | no-match | +| main.rs:275:28:275:44 | ...::Right(...) | main.rs:275:42:275:43 | a7 | match | +| main.rs:275:42:275:43 | a7 | main.rs:275:9:275:44 | [match(true)] ... \| ... | match | +| main.rs:275:42:275:43 | a7 | main.rs:275:42:275:43 | a7 | | +| main.rs:276:16:276:17 | a7 | main.rs:276:21:276:21 | 0 | | +| main.rs:276:16:276:21 | ... > ... | main.rs:277:16:277:24 | print_i64 | true | +| main.rs:276:16:276:21 | ... > ... | main.rs:278:9:278:9 | _ | false | +| main.rs:276:21:276:21 | 0 | main.rs:276:16:276:21 | ... > ... | | +| main.rs:277:16:277:24 | print_i64 | main.rs:277:26:277:27 | a7 | | +| main.rs:277:16:277:28 | print_i64(...) | main.rs:274:5:279:5 | match either { ... } | | +| main.rs:277:26:277:27 | a7 | main.rs:277:16:277:28 | print_i64(...) | | +| main.rs:278:9:278:9 | _ | main.rs:278:14:278:15 | TupleExpr | match | +| main.rs:278:14:278:15 | TupleExpr | main.rs:274:5:279:5 | match either { ... } | | +| main.rs:282:1:297:1 | enter fn match_pattern8 | main.rs:283:5:283:34 | let ... = ... | | +| main.rs:282:1:297:1 | exit fn match_pattern8 (normal) | main.rs:282:1:297:1 | exit fn match_pattern8 | | +| main.rs:282:21:297:1 | { ... } | main.rs:282:1:297:1 | exit fn match_pattern8 (normal) | | +| main.rs:283:5:283:34 | let ... = ... | main.rs:283:18:283:29 | ...::Left | | +| main.rs:283:9:283:14 | either | main.rs:283:9:283:14 | either | | +| main.rs:283:9:283:14 | either | main.rs:285:11:285:16 | either | match | +| main.rs:283:18:283:29 | ...::Left | main.rs:283:31:283:32 | 32 | | +| main.rs:283:18:283:33 | ...::Left(...) | main.rs:283:9:283:14 | either | | +| main.rs:283:31:283:32 | 32 | main.rs:283:18:283:33 | ...::Left(...) | | +| main.rs:285:5:296:5 | match either { ... } | main.rs:282:21:297:1 | { ... } | | +| main.rs:285:11:285:16 | either | main.rs:287:14:287:30 | ...::Left(...) | | +| main.rs:286:9:287:52 | ref e @ ... | main.rs:289:13:289:27 | ExprStmt | match | +| main.rs:286:13:286:13 | e | main.rs:286:9:287:52 | ref e @ ... | | +| main.rs:287:14:287:30 | ...::Left(...) | main.rs:287:27:287:29 | a11 | match | +| main.rs:287:14:287:30 | ...::Left(...) | main.rs:287:34:287:51 | ...::Right(...) | no-match | +| main.rs:287:14:287:51 | [match(false)] ... \| ... | main.rs:295:9:295:9 | _ | no-match | +| main.rs:287:14:287:51 | [match(true)] ... \| ... | main.rs:286:13:286:13 | e | match | +| main.rs:287:27:287:29 | a11 | main.rs:287:14:287:51 | [match(true)] ... \| ... | match | +| main.rs:287:27:287:29 | a11 | main.rs:287:27:287:29 | a11 | | +| main.rs:287:34:287:51 | ...::Right(...) | main.rs:287:14:287:51 | [match(false)] ... \| ... | no-match | +| main.rs:287:34:287:51 | ...::Right(...) | main.rs:287:48:287:50 | a11 | match | +| main.rs:287:48:287:50 | a11 | main.rs:287:14:287:51 | [match(true)] ... \| ... | match | +| main.rs:287:48:287:50 | a11 | main.rs:287:48:287:50 | a11 | | +| main.rs:288:12:294:9 | { ... } | main.rs:285:5:296:5 | match either { ... } | | +| main.rs:289:13:289:21 | print_i64 | main.rs:289:23:289:25 | a11 | | +| main.rs:289:13:289:26 | print_i64(...) | main.rs:291:15:291:15 | e | | +| main.rs:289:13:289:27 | ExprStmt | main.rs:289:13:289:21 | print_i64 | | +| main.rs:289:23:289:25 | a11 | main.rs:289:13:289:26 | print_i64(...) | | +| main.rs:290:13:293:13 | if ... {...} | main.rs:288:12:294:9 | { ... } | | +| main.rs:290:16:291:15 | [boolean(false)] let ... = e | main.rs:290:13:293:13 | if ... {...} | false | +| main.rs:290:16:291:15 | [boolean(true)] let ... = e | main.rs:292:17:292:32 | ExprStmt | true | +| main.rs:290:20:290:36 | ...::Left(...) | main.rs:290:16:291:15 | [boolean(false)] let ... = e | no-match | +| main.rs:290:20:290:36 | ...::Left(...) | main.rs:290:33:290:35 | a12 | match | +| main.rs:290:33:290:35 | a12 | main.rs:290:16:291:15 | [boolean(true)] let ... = e | match | +| main.rs:290:33:290:35 | a12 | main.rs:290:33:290:35 | a12 | | +| main.rs:291:15:291:15 | e | main.rs:290:20:290:36 | ...::Left(...) | | +| main.rs:291:17:293:13 | { ... } | main.rs:290:13:293:13 | if ... {...} | | +| main.rs:292:17:292:25 | print_i64 | main.rs:292:28:292:30 | a12 | | +| main.rs:292:17:292:31 | print_i64(...) | main.rs:291:17:293:13 | { ... } | | +| main.rs:292:17:292:32 | ExprStmt | main.rs:292:17:292:25 | print_i64 | | +| main.rs:292:27:292:30 | * ... | main.rs:292:17:292:31 | print_i64(...) | | +| main.rs:292:28:292:30 | a12 | main.rs:292:27:292:30 | * ... | | +| main.rs:295:9:295:9 | _ | main.rs:295:14:295:15 | TupleExpr | match | +| main.rs:295:14:295:15 | TupleExpr | main.rs:285:5:296:5 | match either { ... } | | +| main.rs:306:1:312:1 | enter fn match_pattern9 | main.rs:307:5:307:36 | let ... = ... | | +| main.rs:306:1:312:1 | exit fn match_pattern9 (normal) | main.rs:306:1:312:1 | exit fn match_pattern9 | | +| main.rs:306:21:312:1 | { ... } | main.rs:306:1:312:1 | exit fn match_pattern9 (normal) | | +| main.rs:307:5:307:36 | let ... = ... | main.rs:307:14:307:31 | ...::Second | | +| main.rs:307:9:307:10 | fv | main.rs:307:9:307:10 | fv | | +| main.rs:307:9:307:10 | fv | main.rs:308:11:308:12 | fv | match | +| main.rs:307:14:307:31 | ...::Second | main.rs:307:33:307:34 | 62 | | +| main.rs:307:14:307:35 | ...::Second(...) | main.rs:307:9:307:10 | fv | | +| main.rs:307:33:307:34 | 62 | main.rs:307:14:307:35 | ...::Second(...) | | +| main.rs:308:5:311:5 | match fv { ... } | main.rs:306:21:312:1 | { ... } | | +| main.rs:308:11:308:12 | fv | main.rs:309:9:309:30 | ...::First(...) | | +| main.rs:309:9:309:30 | ...::First(...) | main.rs:309:27:309:29 | a13 | match | +| main.rs:309:9:309:30 | ...::First(...) | main.rs:309:35:309:57 | ...::Second(...) | no-match | +| main.rs:309:9:309:109 | ... \| ... \| ... | main.rs:310:16:310:24 | print_i64 | match | +| main.rs:309:27:309:29 | a13 | main.rs:309:9:309:109 | ... \| ... \| ... | match | +| main.rs:309:27:309:29 | a13 | main.rs:309:27:309:29 | a13 | | +| main.rs:309:35:309:57 | ...::Second(...) | main.rs:309:54:309:56 | a13 | match | +| main.rs:309:35:309:57 | ...::Second(...) | main.rs:309:61:309:82 | ...::Third(...) | no-match | +| main.rs:309:35:309:82 | [match(false)] ... \| ... | main.rs:309:87:309:109 | ...::Fourth(...) | no-match | +| main.rs:309:35:309:82 | [match(true)] ... \| ... | main.rs:309:9:309:109 | ... \| ... \| ... | match | +| main.rs:309:54:309:56 | a13 | main.rs:309:35:309:82 | [match(true)] ... \| ... | match | +| main.rs:309:54:309:56 | a13 | main.rs:309:54:309:56 | a13 | | +| main.rs:309:61:309:82 | ...::Third(...) | main.rs:309:35:309:82 | [match(false)] ... \| ... | no-match | +| main.rs:309:61:309:82 | ...::Third(...) | main.rs:309:79:309:81 | a13 | match | +| main.rs:309:79:309:81 | a13 | main.rs:309:35:309:82 | [match(true)] ... \| ... | match | +| main.rs:309:79:309:81 | a13 | main.rs:309:79:309:81 | a13 | | +| main.rs:309:87:309:109 | ...::Fourth(...) | main.rs:309:106:309:108 | a13 | match | +| main.rs:309:106:309:108 | a13 | main.rs:309:9:309:109 | ... \| ... \| ... | match | +| main.rs:309:106:309:108 | a13 | main.rs:309:106:309:108 | a13 | | +| main.rs:310:16:310:24 | print_i64 | main.rs:310:26:310:28 | a13 | | +| main.rs:310:16:310:29 | print_i64(...) | main.rs:308:5:311:5 | match fv { ... } | | +| main.rs:310:26:310:28 | a13 | main.rs:310:16:310:29 | print_i64(...) | | +| main.rs:314:1:328:1 | enter fn match_pattern10 | main.rs:316:5:316:20 | let ... = ... | | +| main.rs:314:1:328:1 | exit fn match_pattern10 (normal) | main.rs:314:1:328:1 | exit fn match_pattern10 | | +| main.rs:315:22:328:1 | { ... } | main.rs:314:1:328:1 | exit fn match_pattern10 (normal) | | +| main.rs:316:5:316:20 | let ... = ... | main.rs:316:12:316:15 | Some | | | main.rs:316:9:316:9 | x | main.rs:316:9:316:9 | x | | -| main.rs:316:9:316:9 | x | main.rs:317:5:327:5 | ExprStmt | match | -| main.rs:316:13:316:16 | Some | main.rs:316:18:316:19 | 42 | | -| main.rs:316:13:316:20 | Some(...) | main.rs:316:9:316:9 | x | | -| main.rs:316:18:316:19 | 42 | main.rs:316:13:316:20 | Some(...) | | -| main.rs:317:5:327:5 | ExprStmt | main.rs:318:7:318:7 | x | | -| main.rs:317:5:327:5 | while ... { ... } | main.rs:329:5:329:26 | ExprStmt | | -| main.rs:317:11:318:7 | [boolean(false)] let ... = x | main.rs:317:11:321:13 | [boolean(false)] ... && ... | false | -| main.rs:317:11:318:7 | [boolean(true)] let ... = x | main.rs:321:7:321:10 | Some | true | -| main.rs:317:11:321:13 | [boolean(false)] ... && ... | main.rs:317:11:323:9 | [boolean(false)] ... && ... | false | -| main.rs:317:11:321:13 | [boolean(true)] ... && ... | main.rs:323:5:323:5 | x | true | -| main.rs:317:11:323:9 | [boolean(false)] ... && ... | main.rs:317:5:327:5 | while ... { ... } | false | -| main.rs:317:11:323:9 | [boolean(true)] ... && ... | main.rs:325:9:325:21 | ExprStmt | true | -| main.rs:317:15:317:21 | Some(...) | main.rs:317:11:318:7 | [boolean(false)] let ... = x | no-match | -| main.rs:317:15:317:21 | Some(...) | main.rs:317:20:317:20 | x | match | -| main.rs:317:20:317:20 | x | main.rs:317:11:318:7 | [boolean(true)] let ... = x | match | -| main.rs:317:20:317:20 | x | main.rs:317:20:317:20 | x | | -| main.rs:318:7:318:7 | x | main.rs:317:15:317:21 | Some(...) | | -| main.rs:320:5:321:13 | [boolean(false)] let ... = ... | main.rs:317:11:321:13 | [boolean(false)] ... && ... | false | -| main.rs:320:5:321:13 | [boolean(true)] let ... = ... | main.rs:317:11:321:13 | [boolean(true)] ... && ... | true | -| main.rs:320:9:320:15 | Some(...) | main.rs:320:5:321:13 | [boolean(false)] let ... = ... | no-match | -| main.rs:320:9:320:15 | Some(...) | main.rs:320:14:320:14 | x | match | -| main.rs:320:14:320:14 | x | main.rs:320:5:321:13 | [boolean(true)] let ... = ... | match | -| main.rs:320:14:320:14 | x | main.rs:320:14:320:14 | x | | -| main.rs:321:7:321:10 | Some | main.rs:321:12:321:12 | x | | -| main.rs:321:7:321:13 | Some(...) | main.rs:320:9:320:15 | Some(...) | | -| main.rs:321:12:321:12 | x | main.rs:321:7:321:13 | Some(...) | | -| main.rs:323:5:323:5 | x | main.rs:323:9:323:9 | 0 | | -| main.rs:323:5:323:9 | ... > ... | main.rs:317:11:323:9 | [boolean(false)] ... && ... | false | -| main.rs:323:5:323:9 | ... > ... | main.rs:317:11:323:9 | [boolean(true)] ... && ... | true | -| main.rs:323:9:323:9 | 0 | main.rs:323:5:323:9 | ... > ... | | -| main.rs:325:9:325:17 | print_i64 | main.rs:325:19:325:19 | x | | -| main.rs:325:9:325:20 | print_i64(...) | main.rs:326:9:326:14 | ExprStmt | | -| main.rs:325:9:325:21 | ExprStmt | main.rs:325:9:325:17 | print_i64 | | -| main.rs:325:19:325:19 | x | main.rs:325:9:325:20 | print_i64(...) | | -| main.rs:326:9:326:13 | break | main.rs:317:5:327:5 | while ... { ... } | break | -| main.rs:326:9:326:14 | ExprStmt | main.rs:326:9:326:13 | break | | -| main.rs:329:5:329:13 | print_i64 | main.rs:329:15:329:15 | x | | -| main.rs:329:5:329:25 | print_i64(...) | main.rs:315:22:330:1 | { ... } | | -| main.rs:329:5:329:26 | ExprStmt | main.rs:329:5:329:13 | print_i64 | | -| main.rs:329:15:329:15 | x | main.rs:329:15:329:24 | x.unwrap() | | -| main.rs:329:15:329:24 | x.unwrap() | main.rs:329:5:329:25 | print_i64(...) | | -| main.rs:332:1:344:1 | enter fn match_pattern13 | main.rs:334:5:334:21 | let ... = ... | | -| main.rs:332:1:344:1 | exit fn match_pattern13 (normal) | main.rs:332:1:344:1 | exit fn match_pattern13 | | -| main.rs:333:22:344:1 | { ... } | main.rs:332:1:344:1 | exit fn match_pattern13 (normal) | | -| main.rs:334:5:334:21 | let ... = ... | main.rs:334:13:334:16 | Some | | -| main.rs:334:9:334:9 | x | main.rs:334:9:334:9 | x | | -| main.rs:334:9:334:9 | x | main.rs:335:5:341:5 | ExprStmt | match | -| main.rs:334:13:334:16 | Some | main.rs:334:18:334:19 | 42 | | -| main.rs:334:13:334:20 | Some(...) | main.rs:334:9:334:9 | x | | -| main.rs:334:18:334:19 | 42 | main.rs:334:13:334:20 | Some(...) | | -| main.rs:335:5:341:5 | ExprStmt | main.rs:335:11:335:11 | x | | -| main.rs:335:5:341:5 | match x { ... } | main.rs:343:5:343:26 | ExprStmt | | -| main.rs:335:11:335:11 | x | main.rs:336:9:336:15 | Some(...) | | +| main.rs:316:9:316:9 | x | main.rs:318:7:318:7 | x | match | +| main.rs:316:12:316:15 | Some | main.rs:316:17:316:18 | 42 | | +| main.rs:316:12:316:19 | Some(...) | main.rs:316:9:316:9 | x | | +| main.rs:316:17:316:18 | 42 | main.rs:316:12:316:19 | Some(...) | | +| main.rs:317:5:327:5 | if ... {...} else {...} | main.rs:315:22:328:1 | { ... } | | +| main.rs:317:8:318:7 | [boolean(false)] let ... = x | main.rs:317:8:320:9 | [boolean(false)] ... && ... | false | +| main.rs:317:8:318:7 | [boolean(true)] let ... = x | main.rs:320:5:320:5 | x | true | +| main.rs:317:8:320:9 | [boolean(false)] ... && ... | main.rs:324:9:325:14 | let ... = x | false | +| main.rs:317:8:320:9 | [boolean(true)] ... && ... | main.rs:322:9:322:21 | ExprStmt | true | +| main.rs:317:12:317:18 | Some(...) | main.rs:317:8:318:7 | [boolean(false)] let ... = x | no-match | +| main.rs:317:12:317:18 | Some(...) | main.rs:317:17:317:17 | x | match | +| main.rs:317:17:317:17 | x | main.rs:317:8:318:7 | [boolean(true)] let ... = x | match | +| main.rs:317:17:317:17 | x | main.rs:317:17:317:17 | x | | +| main.rs:318:7:318:7 | x | main.rs:317:12:317:18 | Some(...) | | +| main.rs:320:5:320:5 | x | main.rs:320:9:320:9 | 0 | | +| main.rs:320:5:320:9 | ... > ... | main.rs:317:8:320:9 | [boolean(false)] ... && ... | false | +| main.rs:320:5:320:9 | ... > ... | main.rs:317:8:320:9 | [boolean(true)] ... && ... | true | +| main.rs:320:9:320:9 | 0 | main.rs:320:5:320:9 | ... > ... | | +| main.rs:321:5:323:5 | { ... } | main.rs:317:5:327:5 | if ... {...} else {...} | | +| main.rs:322:9:322:17 | print_i64 | main.rs:322:19:322:19 | x | | +| main.rs:322:9:322:20 | print_i64(...) | main.rs:321:5:323:5 | { ... } | | +| main.rs:322:9:322:21 | ExprStmt | main.rs:322:9:322:17 | print_i64 | | +| main.rs:322:19:322:19 | x | main.rs:322:9:322:20 | print_i64(...) | | +| main.rs:323:12:327:5 | { ... } | main.rs:317:5:327:5 | if ... {...} else {...} | | +| main.rs:324:9:325:14 | let ... = x | main.rs:325:13:325:13 | x | | +| main.rs:324:13:324:13 | x | main.rs:324:13:324:13 | x | | +| main.rs:324:13:324:13 | x | main.rs:326:9:326:30 | ExprStmt | match | +| main.rs:325:13:325:13 | x | main.rs:324:13:324:13 | x | | +| main.rs:326:9:326:17 | print_i64 | main.rs:326:19:326:19 | x | | +| main.rs:326:9:326:29 | print_i64(...) | main.rs:323:12:327:5 | { ... } | | +| main.rs:326:9:326:30 | ExprStmt | main.rs:326:9:326:17 | print_i64 | | +| main.rs:326:19:326:19 | x | main.rs:326:19:326:28 | x.unwrap() | | +| main.rs:326:19:326:28 | x.unwrap() | main.rs:326:9:326:29 | print_i64(...) | | +| main.rs:330:1:347:1 | enter fn match_pattern11 | main.rs:332:5:332:21 | let ... = ... | | +| main.rs:330:1:347:1 | exit fn match_pattern11 (normal) | main.rs:330:1:347:1 | exit fn match_pattern11 | | +| main.rs:331:22:347:1 | { ... } | main.rs:330:1:347:1 | exit fn match_pattern11 (normal) | | +| main.rs:332:5:332:21 | let ... = ... | main.rs:332:13:332:16 | Some | | +| main.rs:332:9:332:9 | x | main.rs:332:9:332:9 | x | | +| main.rs:332:9:332:9 | x | main.rs:334:7:334:7 | x | match | +| main.rs:332:13:332:16 | Some | main.rs:332:18:332:19 | 42 | | +| main.rs:332:13:332:20 | Some(...) | main.rs:332:9:332:9 | x | | +| main.rs:332:18:332:19 | 42 | main.rs:332:13:332:20 | Some(...) | | +| main.rs:333:5:346:5 | if ... {...} else {...} | main.rs:331:22:347:1 | { ... } | | +| main.rs:333:8:334:7 | [boolean(false)] let ... = x | main.rs:333:8:337:13 | [boolean(false)] ... && ... | false | +| main.rs:333:8:334:7 | [boolean(true)] let ... = x | main.rs:337:7:337:10 | Some | true | +| main.rs:333:8:337:13 | [boolean(false)] ... && ... | main.rs:333:8:339:9 | [boolean(false)] ... && ... | false | +| main.rs:333:8:337:13 | [boolean(true)] ... && ... | main.rs:339:5:339:5 | x | true | +| main.rs:333:8:339:9 | [boolean(false)] ... && ... | main.rs:343:9:344:14 | let ... = x | false | +| main.rs:333:8:339:9 | [boolean(true)] ... && ... | main.rs:341:9:341:21 | ExprStmt | true | +| main.rs:333:12:333:18 | Some(...) | main.rs:333:8:334:7 | [boolean(false)] let ... = x | no-match | +| main.rs:333:12:333:18 | Some(...) | main.rs:333:17:333:17 | x | match | +| main.rs:333:17:333:17 | x | main.rs:333:8:334:7 | [boolean(true)] let ... = x | match | +| main.rs:333:17:333:17 | x | main.rs:333:17:333:17 | x | | +| main.rs:334:7:334:7 | x | main.rs:333:12:333:18 | Some(...) | | +| main.rs:336:5:337:13 | [boolean(false)] let ... = ... | main.rs:333:8:337:13 | [boolean(false)] ... && ... | false | +| main.rs:336:5:337:13 | [boolean(true)] let ... = ... | main.rs:333:8:337:13 | [boolean(true)] ... && ... | true | +| main.rs:336:9:336:15 | Some(...) | main.rs:336:5:337:13 | [boolean(false)] let ... = ... | no-match | | main.rs:336:9:336:15 | Some(...) | main.rs:336:14:336:14 | x | match | -| main.rs:336:9:336:15 | Some(...) | main.rs:340:9:340:9 | _ | no-match | +| main.rs:336:14:336:14 | x | main.rs:336:5:337:13 | [boolean(true)] let ... = ... | match | | main.rs:336:14:336:14 | x | main.rs:336:14:336:14 | x | | -| main.rs:336:14:336:14 | x | main.rs:338:18:338:18 | x | match | -| main.rs:337:16:338:18 | [boolean(true)] let ... = x | main.rs:339:19:339:19 | x | true | -| main.rs:337:16:339:23 | [boolean(false)] ... && ... | main.rs:340:9:340:9 | _ | false | -| main.rs:337:16:339:23 | [boolean(true)] ... && ... | main.rs:339:28:339:29 | TupleExpr | true | -| main.rs:337:20:337:20 | x | main.rs:337:16:338:18 | [boolean(true)] let ... = x | match | -| main.rs:337:20:337:20 | x | main.rs:337:20:337:20 | x | | -| main.rs:338:18:338:18 | x | main.rs:337:20:337:20 | x | | -| main.rs:339:19:339:19 | x | main.rs:339:23:339:23 | 0 | | -| main.rs:339:19:339:23 | ... > ... | main.rs:337:16:339:23 | [boolean(false)] ... && ... | false | -| main.rs:339:19:339:23 | ... > ... | main.rs:337:16:339:23 | [boolean(true)] ... && ... | true | -| main.rs:339:23:339:23 | 0 | main.rs:339:19:339:23 | ... > ... | | -| main.rs:339:28:339:29 | TupleExpr | main.rs:335:5:341:5 | match x { ... } | | -| main.rs:340:9:340:9 | _ | main.rs:340:14:340:15 | TupleExpr | match | -| main.rs:340:14:340:15 | TupleExpr | main.rs:335:5:341:5 | match x { ... } | | -| main.rs:343:5:343:13 | print_i64 | main.rs:343:15:343:15 | x | | -| main.rs:343:5:343:25 | print_i64(...) | main.rs:333:22:344:1 | { ... } | | -| main.rs:343:5:343:26 | ExprStmt | main.rs:343:5:343:13 | print_i64 | | -| main.rs:343:15:343:15 | x | main.rs:343:15:343:24 | x.unwrap() | | -| main.rs:343:15:343:24 | x.unwrap() | main.rs:343:5:343:25 | print_i64(...) | | -| main.rs:346:1:361:1 | enter fn match_pattern14 | main.rs:348:5:348:19 | let ... = ... | | -| main.rs:346:1:361:1 | exit fn match_pattern14 (normal) | main.rs:346:1:361:1 | exit fn match_pattern14 | | -| main.rs:347:22:361:1 | { ... } | main.rs:346:1:361:1 | exit fn match_pattern14 (normal) | | -| main.rs:348:5:348:19 | let ... = ... | main.rs:348:13:348:14 | Ok | | -| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | | -| main.rs:348:9:348:9 | x | main.rs:350:7:350:7 | x | match | -| main.rs:348:13:348:14 | Ok | main.rs:348:16:348:17 | 42 | | -| main.rs:348:13:348:18 | Ok(...) | main.rs:348:9:348:9 | x | | -| main.rs:348:16:348:17 | 42 | main.rs:348:13:348:18 | Ok(...) | | -| main.rs:349:5:360:5 | if ... {...} else {...} | main.rs:347:22:361:1 | { ... } | | -| main.rs:349:8:350:7 | [boolean(false)] let ... = x | main.rs:355:7:355:7 | x | false | -| main.rs:349:8:350:7 | [boolean(true)] let ... = x | main.rs:352:9:352:21 | ExprStmt | true | -| main.rs:349:12:349:17 | Err(...) | main.rs:349:8:350:7 | [boolean(false)] let ... = x | no-match | -| main.rs:349:12:349:17 | Err(...) | main.rs:349:16:349:16 | x | match | -| main.rs:349:16:349:16 | x | main.rs:349:8:350:7 | [boolean(true)] let ... = x | match | -| main.rs:349:16:349:16 | x | main.rs:349:16:349:16 | x | | -| main.rs:350:7:350:7 | x | main.rs:349:12:349:17 | Err(...) | | -| main.rs:351:5:353:5 | { ... } | main.rs:349:5:360:5 | if ... {...} else {...} | | -| main.rs:352:9:352:17 | print_i64 | main.rs:352:19:352:19 | x | | -| main.rs:352:9:352:20 | print_i64(...) | main.rs:351:5:353:5 | { ... } | | -| main.rs:352:9:352:21 | ExprStmt | main.rs:352:9:352:17 | print_i64 | | -| main.rs:352:19:352:19 | x | main.rs:352:9:352:20 | print_i64(...) | | -| main.rs:354:10:360:5 | if ... {...} else {...} | main.rs:349:5:360:5 | if ... {...} else {...} | | -| main.rs:354:13:355:7 | [boolean(false)] let ... = x | main.rs:359:9:359:30 | ExprStmt | false | -| main.rs:354:13:355:7 | [boolean(true)] let ... = x | main.rs:357:9:357:21 | ExprStmt | true | -| main.rs:354:17:354:21 | Ok(...) | main.rs:354:13:355:7 | [boolean(false)] let ... = x | no-match | -| main.rs:354:17:354:21 | Ok(...) | main.rs:354:20:354:20 | x | match | -| main.rs:354:20:354:20 | x | main.rs:354:13:355:7 | [boolean(true)] let ... = x | match | -| main.rs:354:20:354:20 | x | main.rs:354:20:354:20 | x | | -| main.rs:355:7:355:7 | x | main.rs:354:17:354:21 | Ok(...) | | -| main.rs:356:5:358:5 | { ... } | main.rs:354:10:360:5 | if ... {...} else {...} | | -| main.rs:357:9:357:17 | print_i64 | main.rs:357:19:357:19 | x | | -| main.rs:357:9:357:20 | print_i64(...) | main.rs:356:5:358:5 | { ... } | | -| main.rs:357:9:357:21 | ExprStmt | main.rs:357:9:357:17 | print_i64 | | -| main.rs:357:19:357:19 | x | main.rs:357:9:357:20 | print_i64(...) | | -| main.rs:358:12:360:5 | { ... } | main.rs:354:10:360:5 | if ... {...} else {...} | | -| main.rs:359:9:359:17 | print_i64 | main.rs:359:19:359:19 | x | | -| main.rs:359:9:359:29 | print_i64(...) | main.rs:358:12:360:5 | { ... } | | -| main.rs:359:9:359:30 | ExprStmt | main.rs:359:9:359:17 | print_i64 | | -| main.rs:359:19:359:19 | x | main.rs:359:19:359:28 | x.unwrap() | | -| main.rs:359:19:359:28 | x.unwrap() | main.rs:359:9:359:29 | print_i64(...) | | -| main.rs:363:1:370:1 | enter fn match_pattern15 | main.rs:364:5:364:20 | let ... = ... | | -| main.rs:363:1:370:1 | exit fn match_pattern15 (normal) | main.rs:363:1:370:1 | exit fn match_pattern15 | | -| main.rs:363:22:370:1 | { ... } | main.rs:363:1:370:1 | exit fn match_pattern15 (normal) | | -| main.rs:364:5:364:20 | let ... = ... | main.rs:364:13:364:16 | Some | | -| main.rs:364:9:364:9 | x | main.rs:364:9:364:9 | x | | -| main.rs:364:9:364:9 | x | main.rs:365:5:369:10 | ExprStmt | match | -| main.rs:364:13:364:16 | Some | main.rs:364:18:364:18 | 0 | | -| main.rs:364:13:364:19 | Some(...) | main.rs:364:9:364:9 | x | | -| main.rs:364:18:364:18 | 0 | main.rs:364:13:364:19 | Some(...) | | -| main.rs:365:5:369:9 | match x { ... } | main.rs:363:22:370:1 | { ... } | | -| main.rs:365:5:369:10 | ExprStmt | main.rs:365:11:365:11 | x | | -| main.rs:365:11:365:11 | x | main.rs:366:13:366:19 | Some(...) | | -| main.rs:366:13:366:19 | Some(...) | main.rs:366:18:366:18 | x | match | -| main.rs:366:13:366:19 | Some(...) | main.rs:368:13:368:13 | _ | no-match | -| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | | -| main.rs:366:18:366:18 | x | main.rs:367:20:367:20 | x | match | -| main.rs:367:20:367:20 | x | main.rs:365:5:369:9 | match x { ... } | | -| main.rs:368:13:368:13 | _ | main.rs:368:18:368:18 | 0 | match | -| main.rs:368:18:368:18 | 0 | main.rs:365:5:369:9 | match x { ... } | | -| main.rs:372:1:381:1 | enter fn match_pattern16 | main.rs:373:5:373:21 | let ... = ... | | -| main.rs:372:1:381:1 | exit fn match_pattern16 (normal) | main.rs:372:1:381:1 | exit fn match_pattern16 | | -| main.rs:372:22:381:1 | { ... } | main.rs:372:1:381:1 | exit fn match_pattern16 (normal) | | -| main.rs:373:5:373:21 | let ... = ... | main.rs:373:13:373:16 | Some | | -| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | | -| main.rs:373:9:373:9 | x | main.rs:374:11:374:11 | x | match | -| main.rs:373:13:373:16 | Some | main.rs:373:18:373:19 | 32 | | -| main.rs:373:13:373:20 | Some(...) | main.rs:373:9:373:9 | x | | -| main.rs:373:18:373:19 | 32 | main.rs:373:13:373:20 | Some(...) | | -| main.rs:374:5:380:5 | match x { ... } | main.rs:372:22:381:1 | { ... } | | -| main.rs:374:11:374:11 | x | main.rs:375:9:375:15 | Some(...) | | -| main.rs:375:9:375:15 | Some(...) | main.rs:375:14:375:14 | y | match | -| main.rs:375:9:375:15 | Some(...) | main.rs:379:9:379:9 | _ | no-match | -| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | | -| main.rs:375:14:375:14 | y | main.rs:377:17:377:20 | Some | match | -| main.rs:376:16:377:23 | [boolean(false)] let ... = ... | main.rs:379:9:379:9 | _ | false | -| main.rs:376:16:377:23 | [boolean(true)] let ... = ... | main.rs:378:16:378:24 | print_i64 | true | -| main.rs:376:20:376:26 | Some(...) | main.rs:376:16:377:23 | [boolean(false)] let ... = ... | no-match | -| main.rs:376:20:376:26 | Some(...) | main.rs:376:25:376:25 | y | match | -| main.rs:376:25:376:25 | y | main.rs:376:16:377:23 | [boolean(true)] let ... = ... | match | -| main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y | | -| main.rs:377:17:377:20 | Some | main.rs:377:22:377:22 | y | | -| main.rs:377:17:377:23 | Some(...) | main.rs:376:20:376:26 | Some(...) | | -| main.rs:377:22:377:22 | y | main.rs:377:17:377:23 | Some(...) | | -| main.rs:378:16:378:24 | print_i64 | main.rs:378:26:378:26 | y | | -| main.rs:378:16:378:27 | print_i64(...) | main.rs:374:5:380:5 | match x { ... } | | -| main.rs:378:26:378:26 | y | main.rs:378:16:378:27 | print_i64(...) | | -| main.rs:379:9:379:9 | _ | main.rs:379:14:379:15 | { ... } | match | -| main.rs:379:14:379:15 | { ... } | main.rs:374:5:380:5 | match x { ... } | | -| main.rs:383:1:393:1 | enter fn param_pattern1 | main.rs:384:5:384:6 | a8 | | -| main.rs:383:1:393:1 | exit fn param_pattern1 (normal) | main.rs:383:1:393:1 | exit fn param_pattern1 | | -| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | | -| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:12 | ...: ... | match | -| main.rs:384:5:384:12 | ...: ... | main.rs:385:5:388:5 | TuplePat | | -| main.rs:385:5:388:5 | TuplePat | main.rs:386:9:386:10 | b3 | match | -| main.rs:385:5:388:19 | ...: ... | main.rs:390:5:390:18 | ExprStmt | | -| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | | -| main.rs:386:9:386:10 | b3 | main.rs:387:9:387:10 | c1 | match | -| main.rs:387:9:387:10 | c1 | main.rs:385:5:388:19 | ...: ... | match | -| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | | -| main.rs:389:9:393:1 | { ... } | main.rs:383:1:393:1 | exit fn param_pattern1 (normal) | | -| main.rs:390:5:390:13 | print_str | main.rs:390:15:390:16 | a8 | | -| main.rs:390:5:390:17 | print_str(...) | main.rs:391:5:391:18 | ExprStmt | | -| main.rs:390:5:390:18 | ExprStmt | main.rs:390:5:390:13 | print_str | | -| main.rs:390:15:390:16 | a8 | main.rs:390:5:390:17 | print_str(...) | | -| main.rs:391:5:391:13 | print_str | main.rs:391:15:391:16 | b3 | | -| main.rs:391:5:391:17 | print_str(...) | main.rs:392:5:392:18 | ExprStmt | | -| main.rs:391:5:391:18 | ExprStmt | main.rs:391:5:391:13 | print_str | | -| main.rs:391:15:391:16 | b3 | main.rs:391:5:391:17 | print_str(...) | | -| main.rs:392:5:392:13 | print_str | main.rs:392:15:392:16 | c1 | | -| main.rs:392:5:392:17 | print_str(...) | main.rs:389:9:393:1 | { ... } | | -| main.rs:392:5:392:18 | ExprStmt | main.rs:392:5:392:13 | print_str | | -| main.rs:392:15:392:16 | c1 | main.rs:392:5:392:17 | print_str(...) | | -| main.rs:395:1:398:1 | enter fn param_pattern2 | main.rs:395:20:395:35 | ...::Left(...) | | -| main.rs:395:1:398:1 | exit fn param_pattern2 (normal) | main.rs:395:1:398:1 | exit fn param_pattern2 | | -| main.rs:395:19:395:64 | ...: Either | main.rs:397:5:397:18 | ExprStmt | | -| main.rs:395:20:395:35 | ...::Left(...) | main.rs:395:33:395:34 | a9 | match | -| main.rs:395:20:395:35 | ...::Left(...) | main.rs:395:39:395:55 | ...::Right(...) | no-match | -| main.rs:395:20:395:55 | ... \| ... | main.rs:395:19:395:64 | ...: Either | match | -| main.rs:395:33:395:34 | a9 | main.rs:395:20:395:55 | ... \| ... | match | -| main.rs:395:33:395:34 | a9 | main.rs:395:33:395:34 | a9 | | -| main.rs:395:39:395:55 | ...::Right(...) | main.rs:395:53:395:54 | a9 | match | -| main.rs:395:53:395:54 | a9 | main.rs:395:20:395:55 | ... \| ... | match | -| main.rs:395:53:395:54 | a9 | main.rs:395:53:395:54 | a9 | | -| main.rs:396:9:398:1 | { ... } | main.rs:395:1:398:1 | exit fn param_pattern2 (normal) | | -| main.rs:397:5:397:13 | print_i64 | main.rs:397:15:397:16 | a9 | | -| main.rs:397:5:397:17 | print_i64(...) | main.rs:396:9:398:1 | { ... } | | -| main.rs:397:5:397:18 | ExprStmt | main.rs:397:5:397:13 | print_i64 | | -| main.rs:397:15:397:16 | a9 | main.rs:397:5:397:17 | print_i64(...) | | -| main.rs:400:1:435:1 | enter fn destruct_assignment | main.rs:401:5:405:18 | let ... = ... | | -| main.rs:400:1:435:1 | exit fn destruct_assignment (normal) | main.rs:400:1:435:1 | exit fn destruct_assignment | | -| main.rs:400:26:435:1 | { ... } | main.rs:400:1:435:1 | exit fn destruct_assignment (normal) | | -| main.rs:401:5:405:18 | let ... = ... | main.rs:405:10:405:10 | 1 | | -| main.rs:401:9:405:5 | TuplePat | main.rs:402:13:402:15 | a10 | match | -| main.rs:402:9:402:15 | mut a10 | main.rs:403:13:403:14 | b4 | match | -| main.rs:402:13:402:15 | a10 | main.rs:402:9:402:15 | mut a10 | | -| main.rs:403:9:403:14 | mut b4 | main.rs:404:13:404:14 | c2 | match | -| main.rs:403:13:403:14 | b4 | main.rs:403:9:403:14 | mut b4 | | -| main.rs:404:9:404:14 | mut c2 | main.rs:406:5:406:19 | ExprStmt | match | -| main.rs:404:13:404:14 | c2 | main.rs:404:9:404:14 | mut c2 | | -| main.rs:405:9:405:17 | TupleExpr | main.rs:401:9:405:5 | TuplePat | | -| main.rs:405:10:405:10 | 1 | main.rs:405:13:405:13 | 2 | | -| main.rs:405:13:405:13 | 2 | main.rs:405:16:405:16 | 3 | | -| main.rs:405:16:405:16 | 3 | main.rs:405:9:405:17 | TupleExpr | | -| main.rs:406:5:406:13 | print_i64 | main.rs:406:15:406:17 | a10 | | -| main.rs:406:5:406:18 | print_i64(...) | main.rs:407:5:407:18 | ExprStmt | | -| main.rs:406:5:406:19 | ExprStmt | main.rs:406:5:406:13 | print_i64 | | -| main.rs:406:15:406:17 | a10 | main.rs:406:5:406:18 | print_i64(...) | | -| main.rs:407:5:407:13 | print_i64 | main.rs:407:15:407:16 | b4 | | -| main.rs:407:5:407:17 | print_i64(...) | main.rs:408:5:408:18 | ExprStmt | | -| main.rs:407:5:407:18 | ExprStmt | main.rs:407:5:407:13 | print_i64 | | -| main.rs:407:15:407:16 | b4 | main.rs:407:5:407:17 | print_i64(...) | | -| main.rs:408:5:408:13 | print_i64 | main.rs:408:15:408:16 | c2 | | -| main.rs:408:5:408:17 | print_i64(...) | main.rs:410:5:418:6 | ExprStmt | | -| main.rs:408:5:408:18 | ExprStmt | main.rs:408:5:408:13 | print_i64 | | -| main.rs:408:15:408:16 | c2 | main.rs:408:5:408:17 | print_i64(...) | | -| main.rs:410:5:414:5 | TupleExpr | main.rs:415:9:415:11 | a10 | | -| main.rs:410:5:418:5 | ... = ... | main.rs:419:5:419:19 | ExprStmt | | -| main.rs:410:5:418:6 | ExprStmt | main.rs:411:9:411:10 | c2 | | -| main.rs:411:9:411:10 | c2 | main.rs:412:9:412:10 | b4 | | -| main.rs:412:9:412:10 | b4 | main.rs:413:9:413:11 | a10 | | -| main.rs:413:9:413:11 | a10 | main.rs:410:5:414:5 | TupleExpr | | -| main.rs:414:9:418:5 | TupleExpr | main.rs:410:5:418:5 | ... = ... | | -| main.rs:415:9:415:11 | a10 | main.rs:416:9:416:10 | b4 | | -| main.rs:416:9:416:10 | b4 | main.rs:417:9:417:10 | c2 | | -| main.rs:417:9:417:10 | c2 | main.rs:414:9:418:5 | TupleExpr | | -| main.rs:419:5:419:13 | print_i64 | main.rs:419:15:419:17 | a10 | | -| main.rs:419:5:419:18 | print_i64(...) | main.rs:420:5:420:18 | ExprStmt | | -| main.rs:419:5:419:19 | ExprStmt | main.rs:419:5:419:13 | print_i64 | | -| main.rs:419:15:419:17 | a10 | main.rs:419:5:419:18 | print_i64(...) | | -| main.rs:420:5:420:13 | print_i64 | main.rs:420:15:420:16 | b4 | | -| main.rs:420:5:420:17 | print_i64(...) | main.rs:421:5:421:18 | ExprStmt | | -| main.rs:420:5:420:18 | ExprStmt | main.rs:420:5:420:13 | print_i64 | | -| main.rs:420:15:420:16 | b4 | main.rs:420:5:420:17 | print_i64(...) | | -| main.rs:421:5:421:13 | print_i64 | main.rs:421:15:421:16 | c2 | | -| main.rs:421:5:421:17 | print_i64(...) | main.rs:423:5:431:5 | ExprStmt | | -| main.rs:421:5:421:18 | ExprStmt | main.rs:421:5:421:13 | print_i64 | | -| main.rs:421:15:421:16 | c2 | main.rs:421:5:421:17 | print_i64(...) | | -| main.rs:423:5:431:5 | ExprStmt | main.rs:423:12:423:12 | 4 | | -| main.rs:423:5:431:5 | match ... { ... } | main.rs:433:5:433:19 | ExprStmt | | -| main.rs:423:11:423:16 | TupleExpr | main.rs:424:9:427:9 | TuplePat | | -| main.rs:423:12:423:12 | 4 | main.rs:423:15:423:15 | 5 | | -| main.rs:423:15:423:15 | 5 | main.rs:423:11:423:16 | TupleExpr | | -| main.rs:424:9:427:9 | TuplePat | main.rs:425:13:425:15 | a10 | match | -| main.rs:425:13:425:15 | a10 | main.rs:425:13:425:15 | a10 | | -| main.rs:425:13:425:15 | a10 | main.rs:426:13:426:14 | b4 | match | -| main.rs:426:13:426:14 | b4 | main.rs:426:13:426:14 | b4 | | -| main.rs:426:13:426:14 | b4 | main.rs:428:13:428:27 | ExprStmt | match | -| main.rs:427:14:430:9 | { ... } | main.rs:423:5:431:5 | match ... { ... } | | -| main.rs:428:13:428:21 | print_i64 | main.rs:428:23:428:25 | a10 | | -| main.rs:428:13:428:26 | print_i64(...) | main.rs:429:13:429:26 | ExprStmt | | -| main.rs:428:13:428:27 | ExprStmt | main.rs:428:13:428:21 | print_i64 | | -| main.rs:428:23:428:25 | a10 | main.rs:428:13:428:26 | print_i64(...) | | -| main.rs:429:13:429:21 | print_i64 | main.rs:429:23:429:24 | b4 | | -| main.rs:429:13:429:25 | print_i64(...) | main.rs:427:14:430:9 | { ... } | | -| main.rs:429:13:429:26 | ExprStmt | main.rs:429:13:429:21 | print_i64 | | -| main.rs:429:23:429:24 | b4 | main.rs:429:13:429:25 | print_i64(...) | | -| main.rs:433:5:433:13 | print_i64 | main.rs:433:15:433:17 | a10 | | -| main.rs:433:5:433:18 | print_i64(...) | main.rs:434:5:434:18 | ExprStmt | | -| main.rs:433:5:433:19 | ExprStmt | main.rs:433:5:433:13 | print_i64 | | -| main.rs:433:15:433:17 | a10 | main.rs:433:5:433:18 | print_i64(...) | | -| main.rs:434:5:434:13 | print_i64 | main.rs:434:15:434:16 | b4 | | -| main.rs:434:5:434:17 | print_i64(...) | main.rs:400:26:435:1 | { ... } | | -| main.rs:434:5:434:18 | ExprStmt | main.rs:434:5:434:13 | print_i64 | | -| main.rs:434:15:434:16 | b4 | main.rs:434:5:434:17 | print_i64(...) | | -| main.rs:437:1:452:1 | enter fn closure_variable | main.rs:438:5:440:10 | let ... = ... | | -| main.rs:437:1:452:1 | exit fn closure_variable (normal) | main.rs:437:1:452:1 | exit fn closure_variable | | -| main.rs:437:23:452:1 | { ... } | main.rs:437:1:452:1 | exit fn closure_variable (normal) | | -| main.rs:438:5:440:10 | let ... = ... | main.rs:439:9:440:9 | \|...\| x | | -| main.rs:438:9:438:23 | example_closure | main.rs:438:9:438:23 | example_closure | | -| main.rs:438:9:438:23 | example_closure | main.rs:441:5:442:27 | let ... = ... | match | -| main.rs:439:9:440:9 | \|...\| x | main.rs:438:9:438:23 | example_closure | | -| main.rs:439:9:440:9 | enter \|...\| x | main.rs:439:10:439:10 | x | | -| main.rs:439:9:440:9 | exit \|...\| x (normal) | main.rs:439:9:440:9 | exit \|...\| x | | -| main.rs:439:10:439:10 | x | main.rs:439:10:439:10 | x | | -| main.rs:439:10:439:10 | x | main.rs:439:10:439:15 | ...: i64 | match | -| main.rs:439:10:439:15 | ...: i64 | main.rs:440:9:440:9 | x | | -| main.rs:440:9:440:9 | x | main.rs:439:9:440:9 | exit \|...\| x (normal) | | -| main.rs:441:5:442:27 | let ... = ... | main.rs:442:9:442:23 | example_closure | | -| main.rs:441:9:441:10 | n1 | main.rs:441:9:441:10 | n1 | | -| main.rs:441:9:441:10 | n1 | main.rs:443:5:443:18 | ExprStmt | match | -| main.rs:442:9:442:23 | example_closure | main.rs:442:25:442:25 | 5 | | -| main.rs:442:9:442:26 | example_closure(...) | main.rs:441:9:441:10 | n1 | | -| main.rs:442:25:442:25 | 5 | main.rs:442:9:442:26 | example_closure(...) | | -| main.rs:443:5:443:13 | print_i64 | main.rs:443:15:443:16 | n1 | | -| main.rs:443:5:443:17 | print_i64(...) | main.rs:445:5:445:25 | ExprStmt | | +| main.rs:337:7:337:10 | Some | main.rs:337:12:337:12 | x | | +| main.rs:337:7:337:13 | Some(...) | main.rs:336:9:336:15 | Some(...) | | +| main.rs:337:12:337:12 | x | main.rs:337:7:337:13 | Some(...) | | +| main.rs:339:5:339:5 | x | main.rs:339:9:339:9 | 0 | | +| main.rs:339:5:339:9 | ... > ... | main.rs:333:8:339:9 | [boolean(false)] ... && ... | false | +| main.rs:339:5:339:9 | ... > ... | main.rs:333:8:339:9 | [boolean(true)] ... && ... | true | +| main.rs:339:9:339:9 | 0 | main.rs:339:5:339:9 | ... > ... | | +| main.rs:340:5:342:5 | { ... } | main.rs:333:5:346:5 | if ... {...} else {...} | | +| main.rs:341:9:341:17 | print_i64 | main.rs:341:19:341:19 | x | | +| main.rs:341:9:341:20 | print_i64(...) | main.rs:340:5:342:5 | { ... } | | +| main.rs:341:9:341:21 | ExprStmt | main.rs:341:9:341:17 | print_i64 | | +| main.rs:341:19:341:19 | x | main.rs:341:9:341:20 | print_i64(...) | | +| main.rs:342:12:346:5 | { ... } | main.rs:333:5:346:5 | if ... {...} else {...} | | +| main.rs:343:9:344:14 | let ... = x | main.rs:344:13:344:13 | x | | +| main.rs:343:13:343:13 | x | main.rs:343:13:343:13 | x | | +| main.rs:343:13:343:13 | x | main.rs:345:9:345:30 | ExprStmt | match | +| main.rs:344:13:344:13 | x | main.rs:343:13:343:13 | x | | +| main.rs:345:9:345:17 | print_i64 | main.rs:345:19:345:19 | x | | +| main.rs:345:9:345:29 | print_i64(...) | main.rs:342:12:346:5 | { ... } | | +| main.rs:345:9:345:30 | ExprStmt | main.rs:345:9:345:17 | print_i64 | | +| main.rs:345:19:345:19 | x | main.rs:345:19:345:28 | x.unwrap() | | +| main.rs:345:19:345:28 | x.unwrap() | main.rs:345:9:345:29 | print_i64(...) | | +| main.rs:349:1:365:1 | enter fn match_pattern12 | main.rs:351:5:351:21 | let ... = ... | | +| main.rs:349:1:365:1 | exit fn match_pattern12 (normal) | main.rs:349:1:365:1 | exit fn match_pattern12 | | +| main.rs:350:22:365:1 | { ... } | main.rs:349:1:365:1 | exit fn match_pattern12 (normal) | | +| main.rs:351:5:351:21 | let ... = ... | main.rs:351:13:351:16 | Some | | +| main.rs:351:9:351:9 | x | main.rs:351:9:351:9 | x | | +| main.rs:351:9:351:9 | x | main.rs:352:5:362:5 | ExprStmt | match | +| main.rs:351:13:351:16 | Some | main.rs:351:18:351:19 | 42 | | +| main.rs:351:13:351:20 | Some(...) | main.rs:351:9:351:9 | x | | +| main.rs:351:18:351:19 | 42 | main.rs:351:13:351:20 | Some(...) | | +| main.rs:352:5:362:5 | ExprStmt | main.rs:353:7:353:7 | x | | +| main.rs:352:5:362:5 | while ... { ... } | main.rs:364:5:364:26 | ExprStmt | | +| main.rs:352:11:353:7 | [boolean(false)] let ... = x | main.rs:352:11:356:13 | [boolean(false)] ... && ... | false | +| main.rs:352:11:353:7 | [boolean(true)] let ... = x | main.rs:356:7:356:10 | Some | true | +| main.rs:352:11:356:13 | [boolean(false)] ... && ... | main.rs:352:11:358:9 | [boolean(false)] ... && ... | false | +| main.rs:352:11:356:13 | [boolean(true)] ... && ... | main.rs:358:5:358:5 | x | true | +| main.rs:352:11:358:9 | [boolean(false)] ... && ... | main.rs:352:5:362:5 | while ... { ... } | false | +| main.rs:352:11:358:9 | [boolean(true)] ... && ... | main.rs:360:9:360:21 | ExprStmt | true | +| main.rs:352:15:352:21 | Some(...) | main.rs:352:11:353:7 | [boolean(false)] let ... = x | no-match | +| main.rs:352:15:352:21 | Some(...) | main.rs:352:20:352:20 | x | match | +| main.rs:352:20:352:20 | x | main.rs:352:11:353:7 | [boolean(true)] let ... = x | match | +| main.rs:352:20:352:20 | x | main.rs:352:20:352:20 | x | | +| main.rs:353:7:353:7 | x | main.rs:352:15:352:21 | Some(...) | | +| main.rs:355:5:356:13 | [boolean(false)] let ... = ... | main.rs:352:11:356:13 | [boolean(false)] ... && ... | false | +| main.rs:355:5:356:13 | [boolean(true)] let ... = ... | main.rs:352:11:356:13 | [boolean(true)] ... && ... | true | +| main.rs:355:9:355:15 | Some(...) | main.rs:355:5:356:13 | [boolean(false)] let ... = ... | no-match | +| main.rs:355:9:355:15 | Some(...) | main.rs:355:14:355:14 | x | match | +| main.rs:355:14:355:14 | x | main.rs:355:5:356:13 | [boolean(true)] let ... = ... | match | +| main.rs:355:14:355:14 | x | main.rs:355:14:355:14 | x | | +| main.rs:356:7:356:10 | Some | main.rs:356:12:356:12 | x | | +| main.rs:356:7:356:13 | Some(...) | main.rs:355:9:355:15 | Some(...) | | +| main.rs:356:12:356:12 | x | main.rs:356:7:356:13 | Some(...) | | +| main.rs:358:5:358:5 | x | main.rs:358:9:358:9 | 0 | | +| main.rs:358:5:358:9 | ... > ... | main.rs:352:11:358:9 | [boolean(false)] ... && ... | false | +| main.rs:358:5:358:9 | ... > ... | main.rs:352:11:358:9 | [boolean(true)] ... && ... | true | +| main.rs:358:9:358:9 | 0 | main.rs:358:5:358:9 | ... > ... | | +| main.rs:360:9:360:17 | print_i64 | main.rs:360:19:360:19 | x | | +| main.rs:360:9:360:20 | print_i64(...) | main.rs:361:9:361:14 | ExprStmt | | +| main.rs:360:9:360:21 | ExprStmt | main.rs:360:9:360:17 | print_i64 | | +| main.rs:360:19:360:19 | x | main.rs:360:9:360:20 | print_i64(...) | | +| main.rs:361:9:361:13 | break | main.rs:352:5:362:5 | while ... { ... } | break | +| main.rs:361:9:361:14 | ExprStmt | main.rs:361:9:361:13 | break | | +| main.rs:364:5:364:13 | print_i64 | main.rs:364:15:364:15 | x | | +| main.rs:364:5:364:25 | print_i64(...) | main.rs:350:22:365:1 | { ... } | | +| main.rs:364:5:364:26 | ExprStmt | main.rs:364:5:364:13 | print_i64 | | +| main.rs:364:15:364:15 | x | main.rs:364:15:364:24 | x.unwrap() | | +| main.rs:364:15:364:24 | x.unwrap() | main.rs:364:5:364:25 | print_i64(...) | | +| main.rs:367:1:379:1 | enter fn match_pattern13 | main.rs:369:5:369:21 | let ... = ... | | +| main.rs:367:1:379:1 | exit fn match_pattern13 (normal) | main.rs:367:1:379:1 | exit fn match_pattern13 | | +| main.rs:368:22:379:1 | { ... } | main.rs:367:1:379:1 | exit fn match_pattern13 (normal) | | +| main.rs:369:5:369:21 | let ... = ... | main.rs:369:13:369:16 | Some | | +| main.rs:369:9:369:9 | x | main.rs:369:9:369:9 | x | | +| main.rs:369:9:369:9 | x | main.rs:370:5:376:5 | ExprStmt | match | +| main.rs:369:13:369:16 | Some | main.rs:369:18:369:19 | 42 | | +| main.rs:369:13:369:20 | Some(...) | main.rs:369:9:369:9 | x | | +| main.rs:369:18:369:19 | 42 | main.rs:369:13:369:20 | Some(...) | | +| main.rs:370:5:376:5 | ExprStmt | main.rs:370:11:370:11 | x | | +| main.rs:370:5:376:5 | match x { ... } | main.rs:378:5:378:26 | ExprStmt | | +| main.rs:370:11:370:11 | x | main.rs:371:9:371:15 | Some(...) | | +| main.rs:371:9:371:15 | Some(...) | main.rs:371:14:371:14 | x | match | +| main.rs:371:9:371:15 | Some(...) | main.rs:375:9:375:9 | _ | no-match | +| main.rs:371:14:371:14 | x | main.rs:371:14:371:14 | x | | +| main.rs:371:14:371:14 | x | main.rs:373:18:373:18 | x | match | +| main.rs:372:16:373:18 | [boolean(true)] let ... = x | main.rs:374:19:374:19 | x | true | +| main.rs:372:16:374:23 | [boolean(false)] ... && ... | main.rs:375:9:375:9 | _ | false | +| main.rs:372:16:374:23 | [boolean(true)] ... && ... | main.rs:374:28:374:29 | TupleExpr | true | +| main.rs:372:20:372:20 | x | main.rs:372:16:373:18 | [boolean(true)] let ... = x | match | +| main.rs:372:20:372:20 | x | main.rs:372:20:372:20 | x | | +| main.rs:373:18:373:18 | x | main.rs:372:20:372:20 | x | | +| main.rs:374:19:374:19 | x | main.rs:374:23:374:23 | 0 | | +| main.rs:374:19:374:23 | ... > ... | main.rs:372:16:374:23 | [boolean(false)] ... && ... | false | +| main.rs:374:19:374:23 | ... > ... | main.rs:372:16:374:23 | [boolean(true)] ... && ... | true | +| main.rs:374:23:374:23 | 0 | main.rs:374:19:374:23 | ... > ... | | +| main.rs:374:28:374:29 | TupleExpr | main.rs:370:5:376:5 | match x { ... } | | +| main.rs:375:9:375:9 | _ | main.rs:375:14:375:15 | TupleExpr | match | +| main.rs:375:14:375:15 | TupleExpr | main.rs:370:5:376:5 | match x { ... } | | +| main.rs:378:5:378:13 | print_i64 | main.rs:378:15:378:15 | x | | +| main.rs:378:5:378:25 | print_i64(...) | main.rs:368:22:379:1 | { ... } | | +| main.rs:378:5:378:26 | ExprStmt | main.rs:378:5:378:13 | print_i64 | | +| main.rs:378:15:378:15 | x | main.rs:378:15:378:24 | x.unwrap() | | +| main.rs:378:15:378:24 | x.unwrap() | main.rs:378:5:378:25 | print_i64(...) | | +| main.rs:381:1:396:1 | enter fn match_pattern14 | main.rs:383:5:383:19 | let ... = ... | | +| main.rs:381:1:396:1 | exit fn match_pattern14 (normal) | main.rs:381:1:396:1 | exit fn match_pattern14 | | +| main.rs:382:22:396:1 | { ... } | main.rs:381:1:396:1 | exit fn match_pattern14 (normal) | | +| main.rs:383:5:383:19 | let ... = ... | main.rs:383:13:383:14 | Ok | | +| main.rs:383:9:383:9 | x | main.rs:383:9:383:9 | x | | +| main.rs:383:9:383:9 | x | main.rs:385:7:385:7 | x | match | +| main.rs:383:13:383:14 | Ok | main.rs:383:16:383:17 | 42 | | +| main.rs:383:13:383:18 | Ok(...) | main.rs:383:9:383:9 | x | | +| main.rs:383:16:383:17 | 42 | main.rs:383:13:383:18 | Ok(...) | | +| main.rs:384:5:395:5 | if ... {...} else {...} | main.rs:382:22:396:1 | { ... } | | +| main.rs:384:8:385:7 | [boolean(false)] let ... = x | main.rs:390:7:390:7 | x | false | +| main.rs:384:8:385:7 | [boolean(true)] let ... = x | main.rs:387:9:387:21 | ExprStmt | true | +| main.rs:384:12:384:17 | Err(...) | main.rs:384:8:385:7 | [boolean(false)] let ... = x | no-match | +| main.rs:384:12:384:17 | Err(...) | main.rs:384:16:384:16 | x | match | +| main.rs:384:16:384:16 | x | main.rs:384:8:385:7 | [boolean(true)] let ... = x | match | +| main.rs:384:16:384:16 | x | main.rs:384:16:384:16 | x | | +| main.rs:385:7:385:7 | x | main.rs:384:12:384:17 | Err(...) | | +| main.rs:386:5:388:5 | { ... } | main.rs:384:5:395:5 | if ... {...} else {...} | | +| main.rs:387:9:387:17 | print_i64 | main.rs:387:19:387:19 | x | | +| main.rs:387:9:387:20 | print_i64(...) | main.rs:386:5:388:5 | { ... } | | +| main.rs:387:9:387:21 | ExprStmt | main.rs:387:9:387:17 | print_i64 | | +| main.rs:387:19:387:19 | x | main.rs:387:9:387:20 | print_i64(...) | | +| main.rs:389:10:395:5 | if ... {...} else {...} | main.rs:384:5:395:5 | if ... {...} else {...} | | +| main.rs:389:13:390:7 | [boolean(false)] let ... = x | main.rs:394:9:394:30 | ExprStmt | false | +| main.rs:389:13:390:7 | [boolean(true)] let ... = x | main.rs:392:9:392:21 | ExprStmt | true | +| main.rs:389:17:389:21 | Ok(...) | main.rs:389:13:390:7 | [boolean(false)] let ... = x | no-match | +| main.rs:389:17:389:21 | Ok(...) | main.rs:389:20:389:20 | x | match | +| main.rs:389:20:389:20 | x | main.rs:389:13:390:7 | [boolean(true)] let ... = x | match | +| main.rs:389:20:389:20 | x | main.rs:389:20:389:20 | x | | +| main.rs:390:7:390:7 | x | main.rs:389:17:389:21 | Ok(...) | | +| main.rs:391:5:393:5 | { ... } | main.rs:389:10:395:5 | if ... {...} else {...} | | +| main.rs:392:9:392:17 | print_i64 | main.rs:392:19:392:19 | x | | +| main.rs:392:9:392:20 | print_i64(...) | main.rs:391:5:393:5 | { ... } | | +| main.rs:392:9:392:21 | ExprStmt | main.rs:392:9:392:17 | print_i64 | | +| main.rs:392:19:392:19 | x | main.rs:392:9:392:20 | print_i64(...) | | +| main.rs:393:12:395:5 | { ... } | main.rs:389:10:395:5 | if ... {...} else {...} | | +| main.rs:394:9:394:17 | print_i64 | main.rs:394:19:394:19 | x | | +| main.rs:394:9:394:29 | print_i64(...) | main.rs:393:12:395:5 | { ... } | | +| main.rs:394:9:394:30 | ExprStmt | main.rs:394:9:394:17 | print_i64 | | +| main.rs:394:19:394:19 | x | main.rs:394:19:394:28 | x.unwrap() | | +| main.rs:394:19:394:28 | x.unwrap() | main.rs:394:9:394:29 | print_i64(...) | | +| main.rs:398:1:405:1 | enter fn match_pattern15 | main.rs:399:5:399:20 | let ... = ... | | +| main.rs:398:1:405:1 | exit fn match_pattern15 (normal) | main.rs:398:1:405:1 | exit fn match_pattern15 | | +| main.rs:398:22:405:1 | { ... } | main.rs:398:1:405:1 | exit fn match_pattern15 (normal) | | +| main.rs:399:5:399:20 | let ... = ... | main.rs:399:13:399:16 | Some | | +| main.rs:399:9:399:9 | x | main.rs:399:9:399:9 | x | | +| main.rs:399:9:399:9 | x | main.rs:400:5:404:10 | ExprStmt | match | +| main.rs:399:13:399:16 | Some | main.rs:399:18:399:18 | 0 | | +| main.rs:399:13:399:19 | Some(...) | main.rs:399:9:399:9 | x | | +| main.rs:399:18:399:18 | 0 | main.rs:399:13:399:19 | Some(...) | | +| main.rs:400:5:404:9 | match x { ... } | main.rs:398:22:405:1 | { ... } | | +| main.rs:400:5:404:10 | ExprStmt | main.rs:400:11:400:11 | x | | +| main.rs:400:11:400:11 | x | main.rs:401:13:401:19 | Some(...) | | +| main.rs:401:13:401:19 | Some(...) | main.rs:401:18:401:18 | x | match | +| main.rs:401:13:401:19 | Some(...) | main.rs:403:13:403:13 | _ | no-match | +| main.rs:401:18:401:18 | x | main.rs:401:18:401:18 | x | | +| main.rs:401:18:401:18 | x | main.rs:402:20:402:20 | x | match | +| main.rs:402:20:402:20 | x | main.rs:400:5:404:9 | match x { ... } | | +| main.rs:403:13:403:13 | _ | main.rs:403:18:403:18 | 0 | match | +| main.rs:403:18:403:18 | 0 | main.rs:400:5:404:9 | match x { ... } | | +| main.rs:407:1:417:1 | enter fn match_pattern16 | main.rs:408:5:408:21 | let ... = ... | | +| main.rs:407:1:417:1 | exit fn match_pattern16 (normal) | main.rs:407:1:417:1 | exit fn match_pattern16 | | +| main.rs:407:22:417:1 | { ... } | main.rs:407:1:417:1 | exit fn match_pattern16 (normal) | | +| main.rs:408:5:408:21 | let ... = ... | main.rs:408:13:408:16 | Some | | +| main.rs:408:9:408:9 | x | main.rs:408:9:408:9 | x | | +| main.rs:408:9:408:9 | x | main.rs:409:11:409:11 | x | match | +| main.rs:408:13:408:16 | Some | main.rs:408:18:408:19 | 32 | | +| main.rs:408:13:408:20 | Some(...) | main.rs:408:9:408:9 | x | | +| main.rs:408:18:408:19 | 32 | main.rs:408:13:408:20 | Some(...) | | +| main.rs:409:5:416:5 | match x { ... } | main.rs:407:22:417:1 | { ... } | | +| main.rs:409:11:409:11 | x | main.rs:410:9:410:15 | Some(...) | | +| main.rs:410:9:410:15 | Some(...) | main.rs:410:14:410:14 | y | match | +| main.rs:410:9:410:15 | Some(...) | main.rs:415:9:415:9 | _ | no-match | +| main.rs:410:14:410:14 | y | main.rs:410:14:410:14 | y | | +| main.rs:410:14:410:14 | y | main.rs:411:16:411:16 | y | match | +| main.rs:411:16:411:16 | y | main.rs:411:20:411:20 | 0 | | +| main.rs:411:16:411:20 | ... > ... | main.rs:411:16:413:23 | [boolean(false)] ... && ... | false | +| main.rs:411:16:411:20 | ... > ... | main.rs:413:17:413:20 | Some | true | +| main.rs:411:16:413:23 | [boolean(false)] ... && ... | main.rs:415:9:415:9 | _ | false | +| main.rs:411:16:413:23 | [boolean(true)] ... && ... | main.rs:414:16:414:24 | print_i64 | true | +| main.rs:411:20:411:20 | 0 | main.rs:411:16:411:20 | ... > ... | | +| main.rs:412:13:413:23 | [boolean(false)] let ... = ... | main.rs:411:16:413:23 | [boolean(false)] ... && ... | false | +| main.rs:412:13:413:23 | [boolean(true)] let ... = ... | main.rs:411:16:413:23 | [boolean(true)] ... && ... | true | +| main.rs:412:17:412:23 | Some(...) | main.rs:412:13:413:23 | [boolean(false)] let ... = ... | no-match | +| main.rs:412:17:412:23 | Some(...) | main.rs:412:22:412:22 | y | match | +| main.rs:412:22:412:22 | y | main.rs:412:13:413:23 | [boolean(true)] let ... = ... | match | +| main.rs:412:22:412:22 | y | main.rs:412:22:412:22 | y | | +| main.rs:413:17:413:20 | Some | main.rs:413:22:413:22 | y | | +| main.rs:413:17:413:23 | Some(...) | main.rs:412:17:412:23 | Some(...) | | +| main.rs:413:22:413:22 | y | main.rs:413:17:413:23 | Some(...) | | +| main.rs:414:16:414:24 | print_i64 | main.rs:414:26:414:26 | y | | +| main.rs:414:16:414:27 | print_i64(...) | main.rs:409:5:416:5 | match x { ... } | | +| main.rs:414:26:414:26 | y | main.rs:414:16:414:27 | print_i64(...) | | +| main.rs:415:9:415:9 | _ | main.rs:415:14:415:15 | { ... } | match | +| main.rs:415:14:415:15 | { ... } | main.rs:409:5:416:5 | match x { ... } | | +| main.rs:419:1:429:1 | enter fn param_pattern1 | main.rs:420:5:420:6 | a8 | | +| main.rs:419:1:429:1 | exit fn param_pattern1 (normal) | main.rs:419:1:429:1 | exit fn param_pattern1 | | +| main.rs:420:5:420:6 | a8 | main.rs:420:5:420:6 | a8 | | +| main.rs:420:5:420:6 | a8 | main.rs:420:5:420:12 | ...: ... | match | +| main.rs:420:5:420:12 | ...: ... | main.rs:421:5:424:5 | TuplePat | | +| main.rs:421:5:424:5 | TuplePat | main.rs:422:9:422:10 | b3 | match | +| main.rs:421:5:424:19 | ...: ... | main.rs:426:5:426:18 | ExprStmt | | +| main.rs:422:9:422:10 | b3 | main.rs:422:9:422:10 | b3 | | +| main.rs:422:9:422:10 | b3 | main.rs:423:9:423:10 | c1 | match | +| main.rs:423:9:423:10 | c1 | main.rs:421:5:424:19 | ...: ... | match | +| main.rs:423:9:423:10 | c1 | main.rs:423:9:423:10 | c1 | | +| main.rs:425:9:429:1 | { ... } | main.rs:419:1:429:1 | exit fn param_pattern1 (normal) | | +| main.rs:426:5:426:13 | print_str | main.rs:426:15:426:16 | a8 | | +| main.rs:426:5:426:17 | print_str(...) | main.rs:427:5:427:18 | ExprStmt | | +| main.rs:426:5:426:18 | ExprStmt | main.rs:426:5:426:13 | print_str | | +| main.rs:426:15:426:16 | a8 | main.rs:426:5:426:17 | print_str(...) | | +| main.rs:427:5:427:13 | print_str | main.rs:427:15:427:16 | b3 | | +| main.rs:427:5:427:17 | print_str(...) | main.rs:428:5:428:18 | ExprStmt | | +| main.rs:427:5:427:18 | ExprStmt | main.rs:427:5:427:13 | print_str | | +| main.rs:427:15:427:16 | b3 | main.rs:427:5:427:17 | print_str(...) | | +| main.rs:428:5:428:13 | print_str | main.rs:428:15:428:16 | c1 | | +| main.rs:428:5:428:17 | print_str(...) | main.rs:425:9:429:1 | { ... } | | +| main.rs:428:5:428:18 | ExprStmt | main.rs:428:5:428:13 | print_str | | +| main.rs:428:15:428:16 | c1 | main.rs:428:5:428:17 | print_str(...) | | +| main.rs:431:1:434:1 | enter fn param_pattern2 | main.rs:431:20:431:35 | ...::Left(...) | | +| main.rs:431:1:434:1 | exit fn param_pattern2 (normal) | main.rs:431:1:434:1 | exit fn param_pattern2 | | +| main.rs:431:19:431:64 | ...: Either | main.rs:433:5:433:18 | ExprStmt | | +| main.rs:431:20:431:35 | ...::Left(...) | main.rs:431:33:431:34 | a9 | match | +| main.rs:431:20:431:35 | ...::Left(...) | main.rs:431:39:431:55 | ...::Right(...) | no-match | +| main.rs:431:20:431:55 | ... \| ... | main.rs:431:19:431:64 | ...: Either | match | +| main.rs:431:33:431:34 | a9 | main.rs:431:20:431:55 | ... \| ... | match | +| main.rs:431:33:431:34 | a9 | main.rs:431:33:431:34 | a9 | | +| main.rs:431:39:431:55 | ...::Right(...) | main.rs:431:53:431:54 | a9 | match | +| main.rs:431:53:431:54 | a9 | main.rs:431:20:431:55 | ... \| ... | match | +| main.rs:431:53:431:54 | a9 | main.rs:431:53:431:54 | a9 | | +| main.rs:432:9:434:1 | { ... } | main.rs:431:1:434:1 | exit fn param_pattern2 (normal) | | +| main.rs:433:5:433:13 | print_i64 | main.rs:433:15:433:16 | a9 | | +| main.rs:433:5:433:17 | print_i64(...) | main.rs:432:9:434:1 | { ... } | | +| main.rs:433:5:433:18 | ExprStmt | main.rs:433:5:433:13 | print_i64 | | +| main.rs:433:15:433:16 | a9 | main.rs:433:5:433:17 | print_i64(...) | | +| main.rs:436:1:471:1 | enter fn destruct_assignment | main.rs:437:5:441:18 | let ... = ... | | +| main.rs:436:1:471:1 | exit fn destruct_assignment (normal) | main.rs:436:1:471:1 | exit fn destruct_assignment | | +| main.rs:436:26:471:1 | { ... } | main.rs:436:1:471:1 | exit fn destruct_assignment (normal) | | +| main.rs:437:5:441:18 | let ... = ... | main.rs:441:10:441:10 | 1 | | +| main.rs:437:9:441:5 | TuplePat | main.rs:438:13:438:15 | a10 | match | +| main.rs:438:9:438:15 | mut a10 | main.rs:439:13:439:14 | b4 | match | +| main.rs:438:13:438:15 | a10 | main.rs:438:9:438:15 | mut a10 | | +| main.rs:439:9:439:14 | mut b4 | main.rs:440:13:440:14 | c2 | match | +| main.rs:439:13:439:14 | b4 | main.rs:439:9:439:14 | mut b4 | | +| main.rs:440:9:440:14 | mut c2 | main.rs:442:5:442:19 | ExprStmt | match | +| main.rs:440:13:440:14 | c2 | main.rs:440:9:440:14 | mut c2 | | +| main.rs:441:9:441:17 | TupleExpr | main.rs:437:9:441:5 | TuplePat | | +| main.rs:441:10:441:10 | 1 | main.rs:441:13:441:13 | 2 | | +| main.rs:441:13:441:13 | 2 | main.rs:441:16:441:16 | 3 | | +| main.rs:441:16:441:16 | 3 | main.rs:441:9:441:17 | TupleExpr | | +| main.rs:442:5:442:13 | print_i64 | main.rs:442:15:442:17 | a10 | | +| main.rs:442:5:442:18 | print_i64(...) | main.rs:443:5:443:18 | ExprStmt | | +| main.rs:442:5:442:19 | ExprStmt | main.rs:442:5:442:13 | print_i64 | | +| main.rs:442:15:442:17 | a10 | main.rs:442:5:442:18 | print_i64(...) | | +| main.rs:443:5:443:13 | print_i64 | main.rs:443:15:443:16 | b4 | | +| main.rs:443:5:443:17 | print_i64(...) | main.rs:444:5:444:18 | ExprStmt | | | main.rs:443:5:443:18 | ExprStmt | main.rs:443:5:443:13 | print_i64 | | -| main.rs:443:15:443:16 | n1 | main.rs:443:5:443:17 | print_i64(...) | | -| main.rs:445:5:445:22 | immutable_variable | main.rs:445:5:445:24 | immutable_variable(...) | | -| main.rs:445:5:445:24 | immutable_variable(...) | main.rs:446:5:448:10 | let ... = ... | | -| main.rs:445:5:445:25 | ExprStmt | main.rs:445:5:445:22 | immutable_variable | | -| main.rs:446:5:448:10 | let ... = ... | main.rs:447:5:448:9 | \|...\| x | | -| main.rs:446:9:446:26 | immutable_variable | main.rs:446:9:446:26 | immutable_variable | | -| main.rs:446:9:446:26 | immutable_variable | main.rs:449:5:450:30 | let ... = ... | match | -| main.rs:447:5:448:9 | \|...\| x | main.rs:446:9:446:26 | immutable_variable | | -| main.rs:447:5:448:9 | enter \|...\| x | main.rs:447:6:447:6 | x | | -| main.rs:447:5:448:9 | exit \|...\| x (normal) | main.rs:447:5:448:9 | exit \|...\| x | | -| main.rs:447:6:447:6 | x | main.rs:447:6:447:6 | x | | -| main.rs:447:6:447:6 | x | main.rs:447:6:447:11 | ...: i64 | match | -| main.rs:447:6:447:11 | ...: i64 | main.rs:448:9:448:9 | x | | -| main.rs:448:9:448:9 | x | main.rs:447:5:448:9 | exit \|...\| x (normal) | | -| main.rs:449:5:450:30 | let ... = ... | main.rs:450:9:450:26 | immutable_variable | | -| main.rs:449:9:449:10 | n2 | main.rs:449:9:449:10 | n2 | | -| main.rs:449:9:449:10 | n2 | main.rs:451:5:451:18 | ExprStmt | match | -| main.rs:450:9:450:26 | immutable_variable | main.rs:450:28:450:28 | 6 | | -| main.rs:450:9:450:29 | immutable_variable(...) | main.rs:449:9:449:10 | n2 | | -| main.rs:450:28:450:28 | 6 | main.rs:450:9:450:29 | immutable_variable(...) | | -| main.rs:451:5:451:13 | print_i64 | main.rs:451:15:451:16 | n2 | | -| main.rs:451:5:451:17 | print_i64(...) | main.rs:437:23:452:1 | { ... } | | -| main.rs:451:5:451:18 | ExprStmt | main.rs:451:5:451:13 | print_i64 | | -| main.rs:451:15:451:16 | n2 | main.rs:451:5:451:17 | print_i64(...) | | -| main.rs:454:1:484:1 | enter fn nested_function | main.rs:456:5:458:10 | let ... = ... | | -| main.rs:454:1:484:1 | exit fn nested_function (normal) | main.rs:454:1:484:1 | exit fn nested_function | | -| main.rs:454:22:484:1 | { ... } | main.rs:454:1:484:1 | exit fn nested_function (normal) | | -| main.rs:456:5:458:10 | let ... = ... | main.rs:457:9:458:9 | \|...\| x | | -| main.rs:456:9:456:9 | f | main.rs:456:9:456:9 | f | | -| main.rs:456:9:456:9 | f | main.rs:459:5:459:20 | ExprStmt | match | -| main.rs:457:9:458:9 | \|...\| x | main.rs:456:9:456:9 | f | | -| main.rs:457:9:458:9 | enter \|...\| x | main.rs:457:10:457:10 | x | | -| main.rs:457:9:458:9 | exit \|...\| x (normal) | main.rs:457:9:458:9 | exit \|...\| x | | -| main.rs:457:10:457:10 | x | main.rs:457:10:457:10 | x | | -| main.rs:457:10:457:10 | x | main.rs:457:10:457:15 | ...: i64 | match | -| main.rs:457:10:457:15 | ...: i64 | main.rs:458:9:458:9 | x | | -| main.rs:458:9:458:9 | x | main.rs:457:9:458:9 | exit \|...\| x (normal) | | -| main.rs:459:5:459:13 | print_i64 | main.rs:459:15:459:15 | f | | -| main.rs:459:5:459:19 | print_i64(...) | main.rs:461:5:464:5 | fn f | | -| main.rs:459:5:459:20 | ExprStmt | main.rs:459:5:459:13 | print_i64 | | -| main.rs:459:15:459:15 | f | main.rs:459:17:459:17 | 1 | | -| main.rs:459:15:459:18 | f(...) | main.rs:459:5:459:19 | print_i64(...) | | -| main.rs:459:17:459:17 | 1 | main.rs:459:15:459:18 | f(...) | | -| main.rs:461:5:464:5 | enter fn f | main.rs:461:10:461:10 | x | | -| main.rs:461:5:464:5 | exit fn f (normal) | main.rs:461:5:464:5 | exit fn f | | -| main.rs:461:5:464:5 | fn f | main.rs:466:5:466:20 | ExprStmt | | -| main.rs:461:10:461:10 | x | main.rs:461:10:461:10 | x | | -| main.rs:461:10:461:10 | x | main.rs:461:10:461:15 | ...: i64 | match | -| main.rs:461:10:461:15 | ...: i64 | main.rs:463:9:463:9 | x | | -| main.rs:462:5:464:5 | { ... } | main.rs:461:5:464:5 | exit fn f (normal) | | -| main.rs:463:9:463:9 | x | main.rs:463:13:463:13 | 1 | | -| main.rs:463:9:463:13 | ... + ... | main.rs:462:5:464:5 | { ... } | | -| main.rs:463:13:463:13 | 1 | main.rs:463:9:463:13 | ... + ... | | -| main.rs:466:5:466:13 | print_i64 | main.rs:466:15:466:15 | f | | -| main.rs:466:5:466:19 | print_i64(...) | main.rs:469:9:469:24 | ExprStmt | | -| main.rs:466:5:466:20 | ExprStmt | main.rs:466:5:466:13 | print_i64 | | -| main.rs:466:15:466:15 | f | main.rs:466:17:466:17 | 2 | | -| main.rs:466:15:466:18 | f(...) | main.rs:466:5:466:19 | print_i64(...) | | -| main.rs:466:17:466:17 | 2 | main.rs:466:15:466:18 | f(...) | | -| main.rs:468:5:483:5 | { ... } | main.rs:454:22:484:1 | { ... } | | -| main.rs:469:9:469:17 | print_i64 | main.rs:469:19:469:19 | f | | -| main.rs:469:9:469:23 | print_i64(...) | main.rs:470:9:473:9 | fn f | | -| main.rs:469:9:469:24 | ExprStmt | main.rs:469:9:469:17 | print_i64 | | -| main.rs:469:19:469:19 | f | main.rs:469:21:469:21 | 3 | | -| main.rs:469:19:469:22 | f(...) | main.rs:469:9:469:23 | print_i64(...) | | -| main.rs:469:21:469:21 | 3 | main.rs:469:19:469:22 | f(...) | | -| main.rs:470:9:473:9 | enter fn f | main.rs:470:14:470:14 | x | | -| main.rs:470:9:473:9 | exit fn f (normal) | main.rs:470:9:473:9 | exit fn f | | -| main.rs:470:9:473:9 | fn f | main.rs:475:9:477:9 | ExprStmt | | -| main.rs:470:14:470:14 | x | main.rs:470:14:470:14 | x | | -| main.rs:470:14:470:14 | x | main.rs:470:14:470:19 | ...: i64 | match | -| main.rs:470:14:470:19 | ...: i64 | main.rs:472:13:472:13 | 2 | | -| main.rs:471:9:473:9 | { ... } | main.rs:470:9:473:9 | exit fn f (normal) | | -| main.rs:472:13:472:13 | 2 | main.rs:472:17:472:17 | x | | -| main.rs:472:13:472:17 | ... * ... | main.rs:471:9:473:9 | { ... } | | -| main.rs:472:17:472:17 | x | main.rs:472:13:472:17 | ... * ... | | -| main.rs:475:9:477:9 | ExprStmt | main.rs:476:13:476:28 | ExprStmt | | -| main.rs:475:9:477:9 | { ... } | main.rs:479:9:481:14 | let ... = ... | | -| main.rs:476:13:476:21 | print_i64 | main.rs:476:23:476:23 | f | | -| main.rs:476:13:476:27 | print_i64(...) | main.rs:475:9:477:9 | { ... } | | -| main.rs:476:13:476:28 | ExprStmt | main.rs:476:13:476:21 | print_i64 | | -| main.rs:476:23:476:23 | f | main.rs:476:25:476:25 | 4 | | -| main.rs:476:23:476:26 | f(...) | main.rs:476:13:476:27 | print_i64(...) | | -| main.rs:476:25:476:25 | 4 | main.rs:476:23:476:26 | f(...) | | -| main.rs:479:9:481:14 | let ... = ... | main.rs:480:13:481:13 | \|...\| x | | -| main.rs:479:13:479:13 | f | main.rs:479:13:479:13 | f | | -| main.rs:479:13:479:13 | f | main.rs:482:9:482:24 | ExprStmt | match | -| main.rs:480:13:481:13 | \|...\| x | main.rs:479:13:479:13 | f | | -| main.rs:480:13:481:13 | enter \|...\| x | main.rs:480:14:480:14 | x | | -| main.rs:480:13:481:13 | exit \|...\| x (normal) | main.rs:480:13:481:13 | exit \|...\| x | | -| main.rs:480:14:480:14 | x | main.rs:480:14:480:14 | x | | -| main.rs:480:14:480:14 | x | main.rs:480:14:480:19 | ...: i64 | match | -| main.rs:480:14:480:19 | ...: i64 | main.rs:481:13:481:13 | x | | -| main.rs:481:13:481:13 | x | main.rs:480:13:481:13 | exit \|...\| x (normal) | | -| main.rs:482:9:482:17 | print_i64 | main.rs:482:19:482:19 | f | | -| main.rs:482:9:482:23 | print_i64(...) | main.rs:468:5:483:5 | { ... } | | -| main.rs:482:9:482:24 | ExprStmt | main.rs:482:9:482:17 | print_i64 | | -| main.rs:482:19:482:19 | f | main.rs:482:21:482:21 | 5 | | -| main.rs:482:19:482:22 | f(...) | main.rs:482:9:482:23 | print_i64(...) | | -| main.rs:482:21:482:21 | 5 | main.rs:482:19:482:22 | f(...) | | -| main.rs:486:1:493:1 | enter fn for_variable | main.rs:487:5:487:42 | let ... = ... | | -| main.rs:486:1:493:1 | exit fn for_variable (normal) | main.rs:486:1:493:1 | exit fn for_variable | | -| main.rs:486:19:493:1 | { ... } | main.rs:486:1:493:1 | exit fn for_variable (normal) | | -| main.rs:487:5:487:42 | let ... = ... | main.rs:487:15:487:22 | "apples" | | -| main.rs:487:9:487:9 | v | main.rs:487:9:487:9 | v | | -| main.rs:487:9:487:9 | v | main.rs:490:12:490:12 | v | match | -| main.rs:487:13:487:41 | &... | main.rs:487:9:487:9 | v | | -| main.rs:487:14:487:41 | [...] | main.rs:487:13:487:41 | &... | | -| main.rs:487:15:487:22 | "apples" | main.rs:487:25:487:30 | "cake" | | -| main.rs:487:25:487:30 | "cake" | main.rs:487:33:487:40 | "coffee" | | -| main.rs:487:33:487:40 | "coffee" | main.rs:487:14:487:41 | [...] | | -| main.rs:489:5:492:5 | for ... in ... { ... } | main.rs:486:19:493:1 | { ... } | | -| main.rs:489:9:489:12 | text | main.rs:489:5:492:5 | for ... in ... { ... } | no-match | -| main.rs:489:9:489:12 | text | main.rs:489:9:489:12 | text | | -| main.rs:489:9:489:12 | text | main.rs:491:9:491:24 | ExprStmt | match | -| main.rs:490:12:490:12 | v | main.rs:489:9:489:12 | text | | -| main.rs:490:14:492:5 | { ... } | main.rs:489:9:489:12 | text | | -| main.rs:491:9:491:17 | print_str | main.rs:491:19:491:22 | text | | -| main.rs:491:9:491:23 | print_str(...) | main.rs:490:14:492:5 | { ... } | | -| main.rs:491:9:491:24 | ExprStmt | main.rs:491:9:491:17 | print_str | | -| main.rs:491:19:491:22 | text | main.rs:491:9:491:23 | print_str(...) | | -| main.rs:495:1:501:1 | enter fn add_assign | main.rs:496:5:496:18 | let ... = 0 | | -| main.rs:495:1:501:1 | exit fn add_assign (normal) | main.rs:495:1:501:1 | exit fn add_assign | | -| main.rs:495:17:501:1 | { ... } | main.rs:495:1:501:1 | exit fn add_assign (normal) | | -| main.rs:496:5:496:18 | let ... = 0 | main.rs:496:17:496:17 | 0 | | -| main.rs:496:9:496:13 | mut a | main.rs:497:5:497:11 | ExprStmt | match | -| main.rs:496:13:496:13 | a | main.rs:496:9:496:13 | mut a | | -| main.rs:496:17:496:17 | 0 | main.rs:496:13:496:13 | a | | -| main.rs:497:5:497:5 | a | main.rs:497:10:497:10 | 1 | | -| main.rs:497:5:497:10 | ... += ... | main.rs:498:5:498:17 | ExprStmt | | -| main.rs:497:5:497:11 | ExprStmt | main.rs:497:5:497:5 | a | | -| main.rs:497:10:497:10 | 1 | main.rs:497:5:497:10 | ... += ... | | -| main.rs:498:5:498:13 | print_i64 | main.rs:498:15:498:15 | a | | -| main.rs:498:5:498:16 | print_i64(...) | main.rs:499:5:499:28 | ExprStmt | | -| main.rs:498:5:498:17 | ExprStmt | main.rs:498:5:498:13 | print_i64 | | -| main.rs:498:15:498:15 | a | main.rs:498:5:498:16 | print_i64(...) | | -| main.rs:499:5:499:27 | ... .add_assign(...) | main.rs:500:5:500:17 | ExprStmt | | -| main.rs:499:5:499:28 | ExprStmt | main.rs:499:11:499:11 | a | | -| main.rs:499:6:499:11 | &mut a | main.rs:499:25:499:26 | 10 | | -| main.rs:499:11:499:11 | a | main.rs:499:6:499:11 | &mut a | | -| main.rs:499:25:499:26 | 10 | main.rs:499:5:499:27 | ... .add_assign(...) | | -| main.rs:500:5:500:13 | print_i64 | main.rs:500:15:500:15 | a | | -| main.rs:500:5:500:16 | print_i64(...) | main.rs:495:17:501:1 | { ... } | | -| main.rs:500:5:500:17 | ExprStmt | main.rs:500:5:500:13 | print_i64 | | -| main.rs:500:15:500:15 | a | main.rs:500:5:500:16 | print_i64(...) | | -| main.rs:503:1:509:1 | enter fn mutate | main.rs:504:5:504:18 | let ... = 1 | | -| main.rs:503:1:509:1 | exit fn mutate (normal) | main.rs:503:1:509:1 | exit fn mutate | | -| main.rs:503:13:509:1 | { ... } | main.rs:503:1:509:1 | exit fn mutate (normal) | | -| main.rs:504:5:504:18 | let ... = 1 | main.rs:504:17:504:17 | 1 | | -| main.rs:504:9:504:13 | mut i | main.rs:505:5:506:15 | let ... = ... | match | -| main.rs:504:13:504:13 | i | main.rs:504:9:504:13 | mut i | | -| main.rs:504:17:504:17 | 1 | main.rs:504:13:504:13 | i | | -| main.rs:505:5:506:15 | let ... = ... | main.rs:506:14:506:14 | i | | -| main.rs:505:9:505:13 | ref_i | main.rs:505:9:505:13 | ref_i | | -| main.rs:505:9:505:13 | ref_i | main.rs:507:5:507:15 | ExprStmt | match | -| main.rs:506:9:506:14 | &mut i | main.rs:505:9:505:13 | ref_i | | -| main.rs:506:14:506:14 | i | main.rs:506:9:506:14 | &mut i | | -| main.rs:507:5:507:10 | * ... | main.rs:507:14:507:14 | 2 | | -| main.rs:507:5:507:14 | ... = ... | main.rs:508:5:508:17 | ExprStmt | | -| main.rs:507:5:507:15 | ExprStmt | main.rs:507:6:507:10 | ref_i | | -| main.rs:507:6:507:10 | ref_i | main.rs:507:5:507:10 | * ... | | -| main.rs:507:14:507:14 | 2 | main.rs:507:5:507:14 | ... = ... | | -| main.rs:508:5:508:13 | print_i64 | main.rs:508:15:508:15 | i | | -| main.rs:508:5:508:16 | print_i64(...) | main.rs:503:13:509:1 | { ... } | | -| main.rs:508:5:508:17 | ExprStmt | main.rs:508:5:508:13 | print_i64 | | -| main.rs:508:15:508:15 | i | main.rs:508:5:508:16 | print_i64(...) | | -| main.rs:511:1:516:1 | enter fn mutate_param | main.rs:511:17:511:17 | x | | -| main.rs:511:1:516:1 | exit fn mutate_param (normal) | main.rs:511:1:516:1 | exit fn mutate_param | | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:27 | ...: ... | match | -| main.rs:511:17:511:27 | ...: ... | main.rs:512:5:514:11 | ExprStmt | | -| main.rs:512:5:512:6 | * ... | main.rs:513:10:513:10 | x | | -| main.rs:512:5:514:10 | ... = ... | main.rs:515:5:515:13 | ExprStmt | | -| main.rs:512:5:514:11 | ExprStmt | main.rs:512:6:512:6 | x | | -| main.rs:512:6:512:6 | x | main.rs:512:5:512:6 | * ... | | -| main.rs:513:9:513:10 | * ... | main.rs:514:10:514:10 | x | | -| main.rs:513:9:514:10 | ... + ... | main.rs:512:5:514:10 | ... = ... | | -| main.rs:513:10:513:10 | x | main.rs:513:9:513:10 | * ... | | -| main.rs:514:9:514:10 | * ... | main.rs:513:9:514:10 | ... + ... | | -| main.rs:514:10:514:10 | x | main.rs:514:9:514:10 | * ... | | -| main.rs:515:5:515:12 | return x | main.rs:511:1:516:1 | exit fn mutate_param (normal) | return | -| main.rs:515:5:515:13 | ExprStmt | main.rs:515:12:515:12 | x | | -| main.rs:515:12:515:12 | x | main.rs:515:5:515:12 | return x | | -| main.rs:518:1:524:1 | enter fn mutate_param2 | main.rs:518:22:518:22 | x | | -| main.rs:518:1:524:1 | exit fn mutate_param2 (normal) | main.rs:518:1:524:1 | exit fn mutate_param2 | | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:35 | ...: ... | match | -| main.rs:518:22:518:35 | ...: ... | main.rs:518:38:518:38 | y | | -| main.rs:518:38:518:38 | y | main.rs:518:38:518:38 | y | | -| main.rs:518:38:518:38 | y | main.rs:518:38:518:56 | ...: ... | match | -| main.rs:518:38:518:56 | ...: ... | main.rs:519:5:521:11 | ExprStmt | | -| main.rs:518:59:524:1 | { ... } | main.rs:518:1:524:1 | exit fn mutate_param2 (normal) | | -| main.rs:519:5:519:6 | * ... | main.rs:520:10:520:10 | x | | -| main.rs:519:5:521:10 | ... = ... | main.rs:522:5:523:10 | ExprStmt | | -| main.rs:519:5:521:11 | ExprStmt | main.rs:519:6:519:6 | x | | -| main.rs:519:6:519:6 | x | main.rs:519:5:519:6 | * ... | | -| main.rs:520:9:520:10 | * ... | main.rs:521:10:521:10 | x | | -| main.rs:520:9:521:10 | ... + ... | main.rs:519:5:521:10 | ... = ... | | -| main.rs:520:10:520:10 | x | main.rs:520:9:520:10 | * ... | | -| main.rs:521:9:521:10 | * ... | main.rs:520:9:521:10 | ... + ... | | -| main.rs:521:10:521:10 | x | main.rs:521:9:521:10 | * ... | | -| main.rs:522:5:522:6 | * ... | main.rs:523:9:523:9 | x | | -| main.rs:522:5:523:9 | ... = ... | main.rs:518:59:524:1 | { ... } | | -| main.rs:522:5:523:10 | ExprStmt | main.rs:522:6:522:6 | y | | -| main.rs:522:6:522:6 | y | main.rs:522:5:522:6 | * ... | | -| main.rs:523:9:523:9 | x | main.rs:522:5:523:9 | ... = ... | | -| main.rs:526:1:546:1 | enter fn mutate_arg | main.rs:527:5:527:18 | let ... = 2 | | -| main.rs:526:1:546:1 | exit fn mutate_arg (normal) | main.rs:526:1:546:1 | exit fn mutate_arg | | -| main.rs:526:17:546:1 | { ... } | main.rs:526:1:546:1 | exit fn mutate_arg (normal) | | -| main.rs:527:5:527:18 | let ... = 2 | main.rs:527:17:527:17 | 2 | | -| main.rs:527:9:527:13 | mut x | main.rs:528:5:529:29 | let ... = ... | match | -| main.rs:527:13:527:13 | x | main.rs:527:9:527:13 | mut x | | -| main.rs:527:17:527:17 | 2 | main.rs:527:13:527:13 | x | | -| main.rs:528:5:529:29 | let ... = ... | main.rs:529:9:529:20 | mutate_param | | -| main.rs:528:9:528:9 | y | main.rs:528:9:528:9 | y | | -| main.rs:528:9:528:9 | y | main.rs:530:5:530:12 | ExprStmt | match | -| main.rs:529:9:529:20 | mutate_param | main.rs:529:27:529:27 | x | | -| main.rs:529:9:529:28 | mutate_param(...) | main.rs:528:9:528:9 | y | | -| main.rs:529:22:529:27 | &mut x | main.rs:529:9:529:28 | mutate_param(...) | | -| main.rs:529:27:529:27 | x | main.rs:529:22:529:27 | &mut x | | -| main.rs:530:5:530:6 | * ... | main.rs:530:10:530:11 | 10 | | -| main.rs:530:5:530:11 | ... = ... | main.rs:533:5:533:17 | ExprStmt | | -| main.rs:530:5:530:12 | ExprStmt | main.rs:530:6:530:6 | y | | -| main.rs:530:6:530:6 | y | main.rs:530:5:530:6 | * ... | | -| main.rs:530:10:530:11 | 10 | main.rs:530:5:530:11 | ... = ... | | -| main.rs:533:5:533:13 | print_i64 | main.rs:533:15:533:15 | x | | -| main.rs:533:5:533:16 | print_i64(...) | main.rs:535:5:535:18 | let ... = 4 | | -| main.rs:533:5:533:17 | ExprStmt | main.rs:533:5:533:13 | print_i64 | | -| main.rs:533:15:533:15 | x | main.rs:533:5:533:16 | print_i64(...) | | -| main.rs:535:5:535:18 | let ... = 4 | main.rs:535:17:535:17 | 4 | | -| main.rs:535:9:535:13 | mut z | main.rs:536:5:537:20 | let ... = ... | match | -| main.rs:535:13:535:13 | z | main.rs:535:9:535:13 | mut z | | -| main.rs:535:17:535:17 | 4 | main.rs:535:13:535:13 | z | | -| main.rs:536:5:537:20 | let ... = ... | main.rs:537:19:537:19 | x | | -| main.rs:536:9:536:9 | w | main.rs:536:9:536:9 | w | | -| main.rs:536:9:536:9 | w | main.rs:538:5:541:6 | ExprStmt | match | -| main.rs:537:9:537:19 | &mut ... | main.rs:536:9:536:9 | w | | -| main.rs:537:14:537:19 | &mut x | main.rs:537:9:537:19 | &mut ... | | -| main.rs:537:19:537:19 | x | main.rs:537:14:537:19 | &mut x | | -| main.rs:538:5:538:17 | mutate_param2 | main.rs:539:14:539:14 | z | | -| main.rs:538:5:541:5 | mutate_param2(...) | main.rs:542:5:542:13 | ExprStmt | | -| main.rs:538:5:541:6 | ExprStmt | main.rs:538:5:538:17 | mutate_param2 | | -| main.rs:539:9:539:14 | &mut z | main.rs:540:9:540:9 | w | | -| main.rs:539:14:539:14 | z | main.rs:539:9:539:14 | &mut z | | -| main.rs:540:9:540:9 | w | main.rs:538:5:541:5 | mutate_param2(...) | | -| main.rs:542:5:542:7 | * ... | main.rs:542:11:542:12 | 11 | | -| main.rs:542:5:542:12 | ... = ... | main.rs:545:5:545:17 | ExprStmt | | -| main.rs:542:5:542:13 | ExprStmt | main.rs:542:7:542:7 | w | | -| main.rs:542:6:542:7 | * ... | main.rs:542:5:542:7 | * ... | | -| main.rs:542:7:542:7 | w | main.rs:542:6:542:7 | * ... | | -| main.rs:542:11:542:12 | 11 | main.rs:542:5:542:12 | ... = ... | | -| main.rs:545:5:545:13 | print_i64 | main.rs:545:15:545:15 | z | | -| main.rs:545:5:545:16 | print_i64(...) | main.rs:526:17:546:1 | { ... } | | -| main.rs:545:5:545:17 | ExprStmt | main.rs:545:5:545:13 | print_i64 | | -| main.rs:545:15:545:15 | z | main.rs:545:5:545:16 | print_i64(...) | | -| main.rs:548:1:554:1 | enter fn alias | main.rs:549:5:549:18 | let ... = 1 | | -| main.rs:548:1:554:1 | exit fn alias (normal) | main.rs:548:1:554:1 | exit fn alias | | -| main.rs:548:12:554:1 | { ... } | main.rs:548:1:554:1 | exit fn alias (normal) | | -| main.rs:549:5:549:18 | let ... = 1 | main.rs:549:17:549:17 | 1 | | -| main.rs:549:9:549:13 | mut x | main.rs:550:5:551:15 | let ... = ... | match | -| main.rs:549:13:549:13 | x | main.rs:549:9:549:13 | mut x | | -| main.rs:549:17:549:17 | 1 | main.rs:549:13:549:13 | x | | -| main.rs:550:5:551:15 | let ... = ... | main.rs:551:14:551:14 | x | | -| main.rs:550:9:550:9 | y | main.rs:550:9:550:9 | y | | -| main.rs:550:9:550:9 | y | main.rs:552:5:552:11 | ExprStmt | match | -| main.rs:551:9:551:14 | &mut x | main.rs:550:9:550:9 | y | | -| main.rs:551:14:551:14 | x | main.rs:551:9:551:14 | &mut x | | -| main.rs:552:5:552:6 | * ... | main.rs:552:10:552:10 | 2 | | -| main.rs:552:5:552:10 | ... = ... | main.rs:553:5:553:17 | ExprStmt | | -| main.rs:552:5:552:11 | ExprStmt | main.rs:552:6:552:6 | y | | -| main.rs:552:6:552:6 | y | main.rs:552:5:552:6 | * ... | | -| main.rs:552:10:552:10 | 2 | main.rs:552:5:552:10 | ... = ... | | -| main.rs:553:5:553:13 | print_i64 | main.rs:553:15:553:15 | x | | -| main.rs:553:5:553:16 | print_i64(...) | main.rs:548:12:554:1 | { ... } | | -| main.rs:553:5:553:17 | ExprStmt | main.rs:553:5:553:13 | print_i64 | | -| main.rs:553:15:553:15 | x | main.rs:553:5:553:16 | print_i64(...) | | -| main.rs:556:1:565:1 | enter fn capture_immut | main.rs:557:5:557:16 | let ... = 100 | | -| main.rs:556:1:565:1 | exit fn capture_immut (normal) | main.rs:556:1:565:1 | exit fn capture_immut | | -| main.rs:556:20:565:1 | { ... } | main.rs:556:1:565:1 | exit fn capture_immut (normal) | | -| main.rs:557:5:557:16 | let ... = 100 | main.rs:557:13:557:15 | 100 | | -| main.rs:557:9:557:9 | x | main.rs:557:9:557:9 | x | | -| main.rs:557:9:557:9 | x | main.rs:560:5:562:6 | let ... = ... | match | -| main.rs:557:13:557:15 | 100 | main.rs:557:9:557:9 | x | | -| main.rs:560:5:562:6 | let ... = ... | main.rs:560:15:562:5 | \|...\| ... | | -| main.rs:560:9:560:11 | cap | main.rs:560:9:560:11 | cap | | -| main.rs:560:9:560:11 | cap | main.rs:563:5:563:10 | ExprStmt | match | -| main.rs:560:15:562:5 | \|...\| ... | main.rs:560:9:560:11 | cap | | -| main.rs:560:15:562:5 | enter \|...\| ... | main.rs:561:9:561:21 | ExprStmt | | -| main.rs:560:15:562:5 | exit \|...\| ... (normal) | main.rs:560:15:562:5 | exit \|...\| ... | | -| main.rs:560:18:562:5 | { ... } | main.rs:560:15:562:5 | exit \|...\| ... (normal) | | -| main.rs:561:9:561:17 | print_i64 | main.rs:561:19:561:19 | x | | -| main.rs:561:9:561:20 | print_i64(...) | main.rs:560:18:562:5 | { ... } | | -| main.rs:561:9:561:21 | ExprStmt | main.rs:561:9:561:17 | print_i64 | | -| main.rs:561:19:561:19 | x | main.rs:561:9:561:20 | print_i64(...) | | -| main.rs:563:5:563:7 | cap | main.rs:563:5:563:9 | cap(...) | | -| main.rs:563:5:563:9 | cap(...) | main.rs:564:5:564:17 | ExprStmt | | -| main.rs:563:5:563:10 | ExprStmt | main.rs:563:5:563:7 | cap | | -| main.rs:564:5:564:13 | print_i64 | main.rs:564:15:564:15 | x | | -| main.rs:564:5:564:16 | print_i64(...) | main.rs:556:20:565:1 | { ... } | | -| main.rs:564:5:564:17 | ExprStmt | main.rs:564:5:564:13 | print_i64 | | -| main.rs:564:15:564:15 | x | main.rs:564:5:564:16 | print_i64(...) | | -| main.rs:567:1:594:1 | enter fn capture_mut | main.rs:568:5:568:18 | let ... = 1 | | -| main.rs:567:1:594:1 | exit fn capture_mut (normal) | main.rs:567:1:594:1 | exit fn capture_mut | | -| main.rs:567:18:594:1 | { ... } | main.rs:567:1:594:1 | exit fn capture_mut (normal) | | -| main.rs:568:5:568:18 | let ... = 1 | main.rs:568:17:568:17 | 1 | | -| main.rs:568:9:568:13 | mut x | main.rs:571:5:573:6 | let ... = ... | match | -| main.rs:568:13:568:13 | x | main.rs:568:9:568:13 | mut x | | -| main.rs:568:17:568:17 | 1 | main.rs:568:13:568:13 | x | | -| main.rs:571:5:573:6 | let ... = ... | main.rs:571:20:573:5 | \|...\| ... | | -| main.rs:571:9:571:16 | closure1 | main.rs:571:9:571:16 | closure1 | | -| main.rs:571:9:571:16 | closure1 | main.rs:574:5:574:15 | ExprStmt | match | -| main.rs:571:20:573:5 | \|...\| ... | main.rs:571:9:571:16 | closure1 | | -| main.rs:571:20:573:5 | enter \|...\| ... | main.rs:572:9:572:21 | ExprStmt | | -| main.rs:571:20:573:5 | exit \|...\| ... (normal) | main.rs:571:20:573:5 | exit \|...\| ... | | -| main.rs:571:23:573:5 | { ... } | main.rs:571:20:573:5 | exit \|...\| ... (normal) | | -| main.rs:572:9:572:17 | print_i64 | main.rs:572:19:572:19 | x | | -| main.rs:572:9:572:20 | print_i64(...) | main.rs:571:23:573:5 | { ... } | | -| main.rs:572:9:572:21 | ExprStmt | main.rs:572:9:572:17 | print_i64 | | -| main.rs:572:19:572:19 | x | main.rs:572:9:572:20 | print_i64(...) | | -| main.rs:574:5:574:12 | closure1 | main.rs:574:5:574:14 | closure1(...) | | -| main.rs:574:5:574:14 | closure1(...) | main.rs:575:5:575:17 | ExprStmt | | -| main.rs:574:5:574:15 | ExprStmt | main.rs:574:5:574:12 | closure1 | | -| main.rs:575:5:575:13 | print_i64 | main.rs:575:15:575:15 | x | | -| main.rs:575:5:575:16 | print_i64(...) | main.rs:577:5:577:18 | let ... = 2 | | -| main.rs:575:5:575:17 | ExprStmt | main.rs:575:5:575:13 | print_i64 | | -| main.rs:575:15:575:15 | x | main.rs:575:5:575:16 | print_i64(...) | | -| main.rs:577:5:577:18 | let ... = 2 | main.rs:577:17:577:17 | 2 | | -| main.rs:577:9:577:13 | mut y | main.rs:580:5:582:6 | let ... = ... | match | -| main.rs:577:13:577:13 | y | main.rs:577:9:577:13 | mut y | | -| main.rs:577:17:577:17 | 2 | main.rs:577:13:577:13 | y | | -| main.rs:580:5:582:6 | let ... = ... | main.rs:580:24:582:5 | \|...\| ... | | -| main.rs:580:9:580:20 | mut closure2 | main.rs:583:5:583:15 | ExprStmt | match | -| main.rs:580:13:580:20 | closure2 | main.rs:580:9:580:20 | mut closure2 | | -| main.rs:580:24:582:5 | \|...\| ... | main.rs:580:13:580:20 | closure2 | | -| main.rs:580:24:582:5 | enter \|...\| ... | main.rs:581:9:581:14 | ExprStmt | | -| main.rs:580:24:582:5 | exit \|...\| ... (normal) | main.rs:580:24:582:5 | exit \|...\| ... | | -| main.rs:580:27:582:5 | { ... } | main.rs:580:24:582:5 | exit \|...\| ... (normal) | | -| main.rs:581:9:581:9 | y | main.rs:581:13:581:13 | 3 | | -| main.rs:581:9:581:13 | ... = ... | main.rs:580:27:582:5 | { ... } | | -| main.rs:581:9:581:14 | ExprStmt | main.rs:581:9:581:9 | y | | -| main.rs:581:13:581:13 | 3 | main.rs:581:9:581:13 | ... = ... | | -| main.rs:583:5:583:12 | closure2 | main.rs:583:5:583:14 | closure2(...) | | -| main.rs:583:5:583:14 | closure2(...) | main.rs:584:5:584:17 | ExprStmt | | -| main.rs:583:5:583:15 | ExprStmt | main.rs:583:5:583:12 | closure2 | | -| main.rs:584:5:584:13 | print_i64 | main.rs:584:15:584:15 | y | | -| main.rs:584:5:584:16 | print_i64(...) | main.rs:586:5:586:18 | let ... = 2 | | -| main.rs:584:5:584:17 | ExprStmt | main.rs:584:5:584:13 | print_i64 | | -| main.rs:584:15:584:15 | y | main.rs:584:5:584:16 | print_i64(...) | | -| main.rs:586:5:586:18 | let ... = 2 | main.rs:586:17:586:17 | 2 | | -| main.rs:586:9:586:13 | mut z | main.rs:589:5:591:6 | let ... = ... | match | -| main.rs:586:13:586:13 | z | main.rs:586:9:586:13 | mut z | | -| main.rs:586:17:586:17 | 2 | main.rs:586:13:586:13 | z | | -| main.rs:589:5:591:6 | let ... = ... | main.rs:589:24:591:5 | \|...\| ... | | -| main.rs:589:9:589:20 | mut closure3 | main.rs:592:5:592:15 | ExprStmt | match | -| main.rs:589:13:589:20 | closure3 | main.rs:589:9:589:20 | mut closure3 | | -| main.rs:589:24:591:5 | \|...\| ... | main.rs:589:13:589:20 | closure3 | | -| main.rs:589:24:591:5 | enter \|...\| ... | main.rs:590:9:590:24 | ExprStmt | | -| main.rs:589:24:591:5 | exit \|...\| ... (normal) | main.rs:589:24:591:5 | exit \|...\| ... | | -| main.rs:589:27:591:5 | { ... } | main.rs:589:24:591:5 | exit \|...\| ... (normal) | | -| main.rs:590:9:590:9 | z | main.rs:590:22:590:22 | 1 | | -| main.rs:590:9:590:23 | z.add_assign(...) | main.rs:589:27:591:5 | { ... } | | -| main.rs:590:9:590:24 | ExprStmt | main.rs:590:9:590:9 | z | | -| main.rs:590:22:590:22 | 1 | main.rs:590:9:590:23 | z.add_assign(...) | | -| main.rs:592:5:592:12 | closure3 | main.rs:592:5:592:14 | closure3(...) | | -| main.rs:592:5:592:14 | closure3(...) | main.rs:593:5:593:17 | ExprStmt | | -| main.rs:592:5:592:15 | ExprStmt | main.rs:592:5:592:12 | closure3 | | -| main.rs:593:5:593:13 | print_i64 | main.rs:593:15:593:15 | z | | -| main.rs:593:5:593:16 | print_i64(...) | main.rs:567:18:594:1 | { ... } | | -| main.rs:593:5:593:17 | ExprStmt | main.rs:593:5:593:13 | print_i64 | | -| main.rs:593:15:593:15 | z | main.rs:593:5:593:16 | print_i64(...) | | -| main.rs:596:1:604:1 | enter fn async_block_capture | main.rs:597:5:597:23 | let ... = 0 | | -| main.rs:596:1:604:1 | exit fn async_block_capture (normal) | main.rs:596:1:604:1 | exit fn async_block_capture | | -| main.rs:596:32:604:1 | { ... } | main.rs:596:1:604:1 | exit fn async_block_capture (normal) | | -| main.rs:597:5:597:23 | let ... = 0 | main.rs:597:22:597:22 | 0 | | -| main.rs:597:9:597:13 | mut i | main.rs:598:5:600:6 | let ... = ... | match | -| main.rs:597:13:597:13 | i | main.rs:597:9:597:13 | mut i | | -| main.rs:597:22:597:22 | 0 | main.rs:597:13:597:13 | i | | -| main.rs:598:5:600:6 | let ... = ... | main.rs:598:17:600:5 | { ... } | | -| main.rs:598:9:598:13 | block | main.rs:598:9:598:13 | block | | -| main.rs:598:9:598:13 | block | main.rs:602:5:602:16 | ExprStmt | match | -| main.rs:598:17:600:5 | enter { ... } | main.rs:599:9:599:14 | ExprStmt | | -| main.rs:598:17:600:5 | exit { ... } (normal) | main.rs:598:17:600:5 | exit { ... } | | -| main.rs:598:17:600:5 | { ... } | main.rs:598:9:598:13 | block | | -| main.rs:599:9:599:9 | i | main.rs:599:13:599:13 | 1 | | -| main.rs:599:9:599:13 | ... = ... | main.rs:598:17:600:5 | exit { ... } (normal) | | -| main.rs:599:9:599:14 | ExprStmt | main.rs:599:9:599:9 | i | | -| main.rs:599:13:599:13 | 1 | main.rs:599:9:599:13 | ... = ... | | -| main.rs:602:5:602:9 | block | main.rs:602:5:602:15 | await block | | -| main.rs:602:5:602:15 | await block | main.rs:603:5:603:17 | ExprStmt | | -| main.rs:602:5:602:16 | ExprStmt | main.rs:602:5:602:9 | block | | -| main.rs:603:5:603:13 | print_i64 | main.rs:603:15:603:15 | i | | -| main.rs:603:5:603:16 | print_i64(...) | main.rs:596:32:604:1 | { ... } | | -| main.rs:603:5:603:17 | ExprStmt | main.rs:603:5:603:13 | print_i64 | | -| main.rs:603:15:603:15 | i | main.rs:603:5:603:16 | print_i64(...) | | -| main.rs:606:1:622:1 | enter fn phi | main.rs:606:8:606:8 | b | | -| main.rs:606:1:622:1 | exit fn phi (normal) | main.rs:606:1:622:1 | exit fn phi | | -| main.rs:606:8:606:8 | b | main.rs:606:8:606:8 | b | | -| main.rs:606:8:606:8 | b | main.rs:606:8:606:14 | ...: bool | match | -| main.rs:606:8:606:14 | ...: bool | main.rs:607:5:607:18 | let ... = 1 | | -| main.rs:606:17:622:1 | { ... } | main.rs:606:1:622:1 | exit fn phi (normal) | | -| main.rs:607:5:607:18 | let ... = 1 | main.rs:607:17:607:17 | 1 | | -| main.rs:607:9:607:13 | mut x | main.rs:608:5:608:17 | ExprStmt | match | -| main.rs:607:13:607:13 | x | main.rs:607:9:607:13 | mut x | | -| main.rs:607:17:607:17 | 1 | main.rs:607:13:607:13 | x | | -| main.rs:608:5:608:13 | print_i64 | main.rs:608:15:608:15 | x | | -| main.rs:608:5:608:16 | print_i64(...) | main.rs:609:5:609:21 | ExprStmt | | -| main.rs:608:5:608:17 | ExprStmt | main.rs:608:5:608:13 | print_i64 | | -| main.rs:608:15:608:15 | x | main.rs:608:5:608:16 | print_i64(...) | | -| main.rs:609:5:609:13 | print_i64 | main.rs:609:15:609:15 | x | | -| main.rs:609:5:609:20 | print_i64(...) | main.rs:610:5:620:6 | let _ = ... | | -| main.rs:609:5:609:21 | ExprStmt | main.rs:609:5:609:13 | print_i64 | | -| main.rs:609:15:609:15 | x | main.rs:609:19:609:19 | 1 | | -| main.rs:609:15:609:19 | ... + ... | main.rs:609:5:609:20 | print_i64(...) | | -| main.rs:609:19:609:19 | 1 | main.rs:609:15:609:19 | ... + ... | | -| main.rs:610:5:620:6 | let _ = ... | main.rs:611:16:611:16 | b | | -| main.rs:611:9:611:9 | _ | main.rs:621:5:621:17 | ExprStmt | match | -| main.rs:611:13:620:5 | if b {...} else {...} | main.rs:611:9:611:9 | _ | | -| main.rs:611:16:611:16 | b | main.rs:613:9:613:14 | ExprStmt | true | -| main.rs:611:16:611:16 | b | main.rs:617:9:617:14 | ExprStmt | false | -| main.rs:612:5:616:5 | { ... } | main.rs:611:13:620:5 | if b {...} else {...} | | -| main.rs:613:9:613:9 | x | main.rs:613:13:613:13 | 2 | | -| main.rs:613:9:613:13 | ... = ... | main.rs:614:9:614:21 | ExprStmt | | -| main.rs:613:9:613:14 | ExprStmt | main.rs:613:9:613:9 | x | | -| main.rs:613:13:613:13 | 2 | main.rs:613:9:613:13 | ... = ... | | -| main.rs:614:9:614:17 | print_i64 | main.rs:614:19:614:19 | x | | -| main.rs:614:9:614:20 | print_i64(...) | main.rs:615:9:615:25 | ExprStmt | | -| main.rs:614:9:614:21 | ExprStmt | main.rs:614:9:614:17 | print_i64 | | -| main.rs:614:19:614:19 | x | main.rs:614:9:614:20 | print_i64(...) | | -| main.rs:615:9:615:17 | print_i64 | main.rs:615:19:615:19 | x | | -| main.rs:615:9:615:24 | print_i64(...) | main.rs:612:5:616:5 | { ... } | | -| main.rs:615:9:615:25 | ExprStmt | main.rs:615:9:615:17 | print_i64 | | -| main.rs:615:19:615:19 | x | main.rs:615:23:615:23 | 1 | | -| main.rs:615:19:615:23 | ... + ... | main.rs:615:9:615:24 | print_i64(...) | | -| main.rs:615:23:615:23 | 1 | main.rs:615:19:615:23 | ... + ... | | -| main.rs:616:12:620:5 | { ... } | main.rs:611:13:620:5 | if b {...} else {...} | | -| main.rs:617:9:617:9 | x | main.rs:617:13:617:13 | 3 | | -| main.rs:617:9:617:13 | ... = ... | main.rs:618:9:618:21 | ExprStmt | | -| main.rs:617:9:617:14 | ExprStmt | main.rs:617:9:617:9 | x | | +| main.rs:443:15:443:16 | b4 | main.rs:443:5:443:17 | print_i64(...) | | +| main.rs:444:5:444:13 | print_i64 | main.rs:444:15:444:16 | c2 | | +| main.rs:444:5:444:17 | print_i64(...) | main.rs:446:5:454:6 | ExprStmt | | +| main.rs:444:5:444:18 | ExprStmt | main.rs:444:5:444:13 | print_i64 | | +| main.rs:444:15:444:16 | c2 | main.rs:444:5:444:17 | print_i64(...) | | +| main.rs:446:5:450:5 | TupleExpr | main.rs:451:9:451:11 | a10 | | +| main.rs:446:5:454:5 | ... = ... | main.rs:455:5:455:19 | ExprStmt | | +| main.rs:446:5:454:6 | ExprStmt | main.rs:447:9:447:10 | c2 | | +| main.rs:447:9:447:10 | c2 | main.rs:448:9:448:10 | b4 | | +| main.rs:448:9:448:10 | b4 | main.rs:449:9:449:11 | a10 | | +| main.rs:449:9:449:11 | a10 | main.rs:446:5:450:5 | TupleExpr | | +| main.rs:450:9:454:5 | TupleExpr | main.rs:446:5:454:5 | ... = ... | | +| main.rs:451:9:451:11 | a10 | main.rs:452:9:452:10 | b4 | | +| main.rs:452:9:452:10 | b4 | main.rs:453:9:453:10 | c2 | | +| main.rs:453:9:453:10 | c2 | main.rs:450:9:454:5 | TupleExpr | | +| main.rs:455:5:455:13 | print_i64 | main.rs:455:15:455:17 | a10 | | +| main.rs:455:5:455:18 | print_i64(...) | main.rs:456:5:456:18 | ExprStmt | | +| main.rs:455:5:455:19 | ExprStmt | main.rs:455:5:455:13 | print_i64 | | +| main.rs:455:15:455:17 | a10 | main.rs:455:5:455:18 | print_i64(...) | | +| main.rs:456:5:456:13 | print_i64 | main.rs:456:15:456:16 | b4 | | +| main.rs:456:5:456:17 | print_i64(...) | main.rs:457:5:457:18 | ExprStmt | | +| main.rs:456:5:456:18 | ExprStmt | main.rs:456:5:456:13 | print_i64 | | +| main.rs:456:15:456:16 | b4 | main.rs:456:5:456:17 | print_i64(...) | | +| main.rs:457:5:457:13 | print_i64 | main.rs:457:15:457:16 | c2 | | +| main.rs:457:5:457:17 | print_i64(...) | main.rs:459:5:467:5 | ExprStmt | | +| main.rs:457:5:457:18 | ExprStmt | main.rs:457:5:457:13 | print_i64 | | +| main.rs:457:15:457:16 | c2 | main.rs:457:5:457:17 | print_i64(...) | | +| main.rs:459:5:467:5 | ExprStmt | main.rs:459:12:459:12 | 4 | | +| main.rs:459:5:467:5 | match ... { ... } | main.rs:469:5:469:19 | ExprStmt | | +| main.rs:459:11:459:16 | TupleExpr | main.rs:460:9:463:9 | TuplePat | | +| main.rs:459:12:459:12 | 4 | main.rs:459:15:459:15 | 5 | | +| main.rs:459:15:459:15 | 5 | main.rs:459:11:459:16 | TupleExpr | | +| main.rs:460:9:463:9 | TuplePat | main.rs:461:13:461:15 | a10 | match | +| main.rs:461:13:461:15 | a10 | main.rs:461:13:461:15 | a10 | | +| main.rs:461:13:461:15 | a10 | main.rs:462:13:462:14 | b4 | match | +| main.rs:462:13:462:14 | b4 | main.rs:462:13:462:14 | b4 | | +| main.rs:462:13:462:14 | b4 | main.rs:464:13:464:27 | ExprStmt | match | +| main.rs:463:14:466:9 | { ... } | main.rs:459:5:467:5 | match ... { ... } | | +| main.rs:464:13:464:21 | print_i64 | main.rs:464:23:464:25 | a10 | | +| main.rs:464:13:464:26 | print_i64(...) | main.rs:465:13:465:26 | ExprStmt | | +| main.rs:464:13:464:27 | ExprStmt | main.rs:464:13:464:21 | print_i64 | | +| main.rs:464:23:464:25 | a10 | main.rs:464:13:464:26 | print_i64(...) | | +| main.rs:465:13:465:21 | print_i64 | main.rs:465:23:465:24 | b4 | | +| main.rs:465:13:465:25 | print_i64(...) | main.rs:463:14:466:9 | { ... } | | +| main.rs:465:13:465:26 | ExprStmt | main.rs:465:13:465:21 | print_i64 | | +| main.rs:465:23:465:24 | b4 | main.rs:465:13:465:25 | print_i64(...) | | +| main.rs:469:5:469:13 | print_i64 | main.rs:469:15:469:17 | a10 | | +| main.rs:469:5:469:18 | print_i64(...) | main.rs:470:5:470:18 | ExprStmt | | +| main.rs:469:5:469:19 | ExprStmt | main.rs:469:5:469:13 | print_i64 | | +| main.rs:469:15:469:17 | a10 | main.rs:469:5:469:18 | print_i64(...) | | +| main.rs:470:5:470:13 | print_i64 | main.rs:470:15:470:16 | b4 | | +| main.rs:470:5:470:17 | print_i64(...) | main.rs:436:26:471:1 | { ... } | | +| main.rs:470:5:470:18 | ExprStmt | main.rs:470:5:470:13 | print_i64 | | +| main.rs:470:15:470:16 | b4 | main.rs:470:5:470:17 | print_i64(...) | | +| main.rs:473:1:488:1 | enter fn closure_variable | main.rs:474:5:476:10 | let ... = ... | | +| main.rs:473:1:488:1 | exit fn closure_variable (normal) | main.rs:473:1:488:1 | exit fn closure_variable | | +| main.rs:473:23:488:1 | { ... } | main.rs:473:1:488:1 | exit fn closure_variable (normal) | | +| main.rs:474:5:476:10 | let ... = ... | main.rs:475:9:476:9 | \|...\| x | | +| main.rs:474:9:474:23 | example_closure | main.rs:474:9:474:23 | example_closure | | +| main.rs:474:9:474:23 | example_closure | main.rs:477:5:478:27 | let ... = ... | match | +| main.rs:475:9:476:9 | \|...\| x | main.rs:474:9:474:23 | example_closure | | +| main.rs:475:9:476:9 | enter \|...\| x | main.rs:475:10:475:10 | x | | +| main.rs:475:9:476:9 | exit \|...\| x (normal) | main.rs:475:9:476:9 | exit \|...\| x | | +| main.rs:475:10:475:10 | x | main.rs:475:10:475:10 | x | | +| main.rs:475:10:475:10 | x | main.rs:475:10:475:15 | ...: i64 | match | +| main.rs:475:10:475:15 | ...: i64 | main.rs:476:9:476:9 | x | | +| main.rs:476:9:476:9 | x | main.rs:475:9:476:9 | exit \|...\| x (normal) | | +| main.rs:477:5:478:27 | let ... = ... | main.rs:478:9:478:23 | example_closure | | +| main.rs:477:9:477:10 | n1 | main.rs:477:9:477:10 | n1 | | +| main.rs:477:9:477:10 | n1 | main.rs:479:5:479:18 | ExprStmt | match | +| main.rs:478:9:478:23 | example_closure | main.rs:478:25:478:25 | 5 | | +| main.rs:478:9:478:26 | example_closure(...) | main.rs:477:9:477:10 | n1 | | +| main.rs:478:25:478:25 | 5 | main.rs:478:9:478:26 | example_closure(...) | | +| main.rs:479:5:479:13 | print_i64 | main.rs:479:15:479:16 | n1 | | +| main.rs:479:5:479:17 | print_i64(...) | main.rs:481:5:481:25 | ExprStmt | | +| main.rs:479:5:479:18 | ExprStmt | main.rs:479:5:479:13 | print_i64 | | +| main.rs:479:15:479:16 | n1 | main.rs:479:5:479:17 | print_i64(...) | | +| main.rs:481:5:481:22 | immutable_variable | main.rs:481:5:481:24 | immutable_variable(...) | | +| main.rs:481:5:481:24 | immutable_variable(...) | main.rs:482:5:484:10 | let ... = ... | | +| main.rs:481:5:481:25 | ExprStmt | main.rs:481:5:481:22 | immutable_variable | | +| main.rs:482:5:484:10 | let ... = ... | main.rs:483:5:484:9 | \|...\| x | | +| main.rs:482:9:482:26 | immutable_variable | main.rs:482:9:482:26 | immutable_variable | | +| main.rs:482:9:482:26 | immutable_variable | main.rs:485:5:486:30 | let ... = ... | match | +| main.rs:483:5:484:9 | \|...\| x | main.rs:482:9:482:26 | immutable_variable | | +| main.rs:483:5:484:9 | enter \|...\| x | main.rs:483:6:483:6 | x | | +| main.rs:483:5:484:9 | exit \|...\| x (normal) | main.rs:483:5:484:9 | exit \|...\| x | | +| main.rs:483:6:483:6 | x | main.rs:483:6:483:6 | x | | +| main.rs:483:6:483:6 | x | main.rs:483:6:483:11 | ...: i64 | match | +| main.rs:483:6:483:11 | ...: i64 | main.rs:484:9:484:9 | x | | +| main.rs:484:9:484:9 | x | main.rs:483:5:484:9 | exit \|...\| x (normal) | | +| main.rs:485:5:486:30 | let ... = ... | main.rs:486:9:486:26 | immutable_variable | | +| main.rs:485:9:485:10 | n2 | main.rs:485:9:485:10 | n2 | | +| main.rs:485:9:485:10 | n2 | main.rs:487:5:487:18 | ExprStmt | match | +| main.rs:486:9:486:26 | immutable_variable | main.rs:486:28:486:28 | 6 | | +| main.rs:486:9:486:29 | immutable_variable(...) | main.rs:485:9:485:10 | n2 | | +| main.rs:486:28:486:28 | 6 | main.rs:486:9:486:29 | immutable_variable(...) | | +| main.rs:487:5:487:13 | print_i64 | main.rs:487:15:487:16 | n2 | | +| main.rs:487:5:487:17 | print_i64(...) | main.rs:473:23:488:1 | { ... } | | +| main.rs:487:5:487:18 | ExprStmt | main.rs:487:5:487:13 | print_i64 | | +| main.rs:487:15:487:16 | n2 | main.rs:487:5:487:17 | print_i64(...) | | +| main.rs:490:1:520:1 | enter fn nested_function | main.rs:492:5:494:10 | let ... = ... | | +| main.rs:490:1:520:1 | exit fn nested_function (normal) | main.rs:490:1:520:1 | exit fn nested_function | | +| main.rs:490:22:520:1 | { ... } | main.rs:490:1:520:1 | exit fn nested_function (normal) | | +| main.rs:492:5:494:10 | let ... = ... | main.rs:493:9:494:9 | \|...\| x | | +| main.rs:492:9:492:9 | f | main.rs:492:9:492:9 | f | | +| main.rs:492:9:492:9 | f | main.rs:495:5:495:20 | ExprStmt | match | +| main.rs:493:9:494:9 | \|...\| x | main.rs:492:9:492:9 | f | | +| main.rs:493:9:494:9 | enter \|...\| x | main.rs:493:10:493:10 | x | | +| main.rs:493:9:494:9 | exit \|...\| x (normal) | main.rs:493:9:494:9 | exit \|...\| x | | +| main.rs:493:10:493:10 | x | main.rs:493:10:493:10 | x | | +| main.rs:493:10:493:10 | x | main.rs:493:10:493:15 | ...: i64 | match | +| main.rs:493:10:493:15 | ...: i64 | main.rs:494:9:494:9 | x | | +| main.rs:494:9:494:9 | x | main.rs:493:9:494:9 | exit \|...\| x (normal) | | +| main.rs:495:5:495:13 | print_i64 | main.rs:495:15:495:15 | f | | +| main.rs:495:5:495:19 | print_i64(...) | main.rs:497:5:500:5 | fn f | | +| main.rs:495:5:495:20 | ExprStmt | main.rs:495:5:495:13 | print_i64 | | +| main.rs:495:15:495:15 | f | main.rs:495:17:495:17 | 1 | | +| main.rs:495:15:495:18 | f(...) | main.rs:495:5:495:19 | print_i64(...) | | +| main.rs:495:17:495:17 | 1 | main.rs:495:15:495:18 | f(...) | | +| main.rs:497:5:500:5 | enter fn f | main.rs:497:10:497:10 | x | | +| main.rs:497:5:500:5 | exit fn f (normal) | main.rs:497:5:500:5 | exit fn f | | +| main.rs:497:5:500:5 | fn f | main.rs:502:5:502:20 | ExprStmt | | +| main.rs:497:10:497:10 | x | main.rs:497:10:497:10 | x | | +| main.rs:497:10:497:10 | x | main.rs:497:10:497:15 | ...: i64 | match | +| main.rs:497:10:497:15 | ...: i64 | main.rs:499:9:499:9 | x | | +| main.rs:498:5:500:5 | { ... } | main.rs:497:5:500:5 | exit fn f (normal) | | +| main.rs:499:9:499:9 | x | main.rs:499:13:499:13 | 1 | | +| main.rs:499:9:499:13 | ... + ... | main.rs:498:5:500:5 | { ... } | | +| main.rs:499:13:499:13 | 1 | main.rs:499:9:499:13 | ... + ... | | +| main.rs:502:5:502:13 | print_i64 | main.rs:502:15:502:15 | f | | +| main.rs:502:5:502:19 | print_i64(...) | main.rs:505:9:505:24 | ExprStmt | | +| main.rs:502:5:502:20 | ExprStmt | main.rs:502:5:502:13 | print_i64 | | +| main.rs:502:15:502:15 | f | main.rs:502:17:502:17 | 2 | | +| main.rs:502:15:502:18 | f(...) | main.rs:502:5:502:19 | print_i64(...) | | +| main.rs:502:17:502:17 | 2 | main.rs:502:15:502:18 | f(...) | | +| main.rs:504:5:519:5 | { ... } | main.rs:490:22:520:1 | { ... } | | +| main.rs:505:9:505:17 | print_i64 | main.rs:505:19:505:19 | f | | +| main.rs:505:9:505:23 | print_i64(...) | main.rs:506:9:509:9 | fn f | | +| main.rs:505:9:505:24 | ExprStmt | main.rs:505:9:505:17 | print_i64 | | +| main.rs:505:19:505:19 | f | main.rs:505:21:505:21 | 3 | | +| main.rs:505:19:505:22 | f(...) | main.rs:505:9:505:23 | print_i64(...) | | +| main.rs:505:21:505:21 | 3 | main.rs:505:19:505:22 | f(...) | | +| main.rs:506:9:509:9 | enter fn f | main.rs:506:14:506:14 | x | | +| main.rs:506:9:509:9 | exit fn f (normal) | main.rs:506:9:509:9 | exit fn f | | +| main.rs:506:9:509:9 | fn f | main.rs:511:9:513:9 | ExprStmt | | +| main.rs:506:14:506:14 | x | main.rs:506:14:506:14 | x | | +| main.rs:506:14:506:14 | x | main.rs:506:14:506:19 | ...: i64 | match | +| main.rs:506:14:506:19 | ...: i64 | main.rs:508:13:508:13 | 2 | | +| main.rs:507:9:509:9 | { ... } | main.rs:506:9:509:9 | exit fn f (normal) | | +| main.rs:508:13:508:13 | 2 | main.rs:508:17:508:17 | x | | +| main.rs:508:13:508:17 | ... * ... | main.rs:507:9:509:9 | { ... } | | +| main.rs:508:17:508:17 | x | main.rs:508:13:508:17 | ... * ... | | +| main.rs:511:9:513:9 | ExprStmt | main.rs:512:13:512:28 | ExprStmt | | +| main.rs:511:9:513:9 | { ... } | main.rs:515:9:517:14 | let ... = ... | | +| main.rs:512:13:512:21 | print_i64 | main.rs:512:23:512:23 | f | | +| main.rs:512:13:512:27 | print_i64(...) | main.rs:511:9:513:9 | { ... } | | +| main.rs:512:13:512:28 | ExprStmt | main.rs:512:13:512:21 | print_i64 | | +| main.rs:512:23:512:23 | f | main.rs:512:25:512:25 | 4 | | +| main.rs:512:23:512:26 | f(...) | main.rs:512:13:512:27 | print_i64(...) | | +| main.rs:512:25:512:25 | 4 | main.rs:512:23:512:26 | f(...) | | +| main.rs:515:9:517:14 | let ... = ... | main.rs:516:13:517:13 | \|...\| x | | +| main.rs:515:13:515:13 | f | main.rs:515:13:515:13 | f | | +| main.rs:515:13:515:13 | f | main.rs:518:9:518:24 | ExprStmt | match | +| main.rs:516:13:517:13 | \|...\| x | main.rs:515:13:515:13 | f | | +| main.rs:516:13:517:13 | enter \|...\| x | main.rs:516:14:516:14 | x | | +| main.rs:516:13:517:13 | exit \|...\| x (normal) | main.rs:516:13:517:13 | exit \|...\| x | | +| main.rs:516:14:516:14 | x | main.rs:516:14:516:14 | x | | +| main.rs:516:14:516:14 | x | main.rs:516:14:516:19 | ...: i64 | match | +| main.rs:516:14:516:19 | ...: i64 | main.rs:517:13:517:13 | x | | +| main.rs:517:13:517:13 | x | main.rs:516:13:517:13 | exit \|...\| x (normal) | | +| main.rs:518:9:518:17 | print_i64 | main.rs:518:19:518:19 | f | | +| main.rs:518:9:518:23 | print_i64(...) | main.rs:504:5:519:5 | { ... } | | +| main.rs:518:9:518:24 | ExprStmt | main.rs:518:9:518:17 | print_i64 | | +| main.rs:518:19:518:19 | f | main.rs:518:21:518:21 | 5 | | +| main.rs:518:19:518:22 | f(...) | main.rs:518:9:518:23 | print_i64(...) | | +| main.rs:518:21:518:21 | 5 | main.rs:518:19:518:22 | f(...) | | +| main.rs:522:1:529:1 | enter fn for_variable | main.rs:523:5:523:42 | let ... = ... | | +| main.rs:522:1:529:1 | exit fn for_variable (normal) | main.rs:522:1:529:1 | exit fn for_variable | | +| main.rs:522:19:529:1 | { ... } | main.rs:522:1:529:1 | exit fn for_variable (normal) | | +| main.rs:523:5:523:42 | let ... = ... | main.rs:523:15:523:22 | "apples" | | +| main.rs:523:9:523:9 | v | main.rs:523:9:523:9 | v | | +| main.rs:523:9:523:9 | v | main.rs:526:12:526:12 | v | match | +| main.rs:523:13:523:41 | &... | main.rs:523:9:523:9 | v | | +| main.rs:523:14:523:41 | [...] | main.rs:523:13:523:41 | &... | | +| main.rs:523:15:523:22 | "apples" | main.rs:523:25:523:30 | "cake" | | +| main.rs:523:25:523:30 | "cake" | main.rs:523:33:523:40 | "coffee" | | +| main.rs:523:33:523:40 | "coffee" | main.rs:523:14:523:41 | [...] | | +| main.rs:525:5:528:5 | for ... in ... { ... } | main.rs:522:19:529:1 | { ... } | | +| main.rs:525:9:525:12 | text | main.rs:525:5:528:5 | for ... in ... { ... } | no-match | +| main.rs:525:9:525:12 | text | main.rs:525:9:525:12 | text | | +| main.rs:525:9:525:12 | text | main.rs:527:9:527:24 | ExprStmt | match | +| main.rs:526:12:526:12 | v | main.rs:525:9:525:12 | text | | +| main.rs:526:14:528:5 | { ... } | main.rs:525:9:525:12 | text | | +| main.rs:527:9:527:17 | print_str | main.rs:527:19:527:22 | text | | +| main.rs:527:9:527:23 | print_str(...) | main.rs:526:14:528:5 | { ... } | | +| main.rs:527:9:527:24 | ExprStmt | main.rs:527:9:527:17 | print_str | | +| main.rs:527:19:527:22 | text | main.rs:527:9:527:23 | print_str(...) | | +| main.rs:531:1:537:1 | enter fn add_assign | main.rs:532:5:532:18 | let ... = 0 | | +| main.rs:531:1:537:1 | exit fn add_assign (normal) | main.rs:531:1:537:1 | exit fn add_assign | | +| main.rs:531:17:537:1 | { ... } | main.rs:531:1:537:1 | exit fn add_assign (normal) | | +| main.rs:532:5:532:18 | let ... = 0 | main.rs:532:17:532:17 | 0 | | +| main.rs:532:9:532:13 | mut a | main.rs:533:5:533:11 | ExprStmt | match | +| main.rs:532:13:532:13 | a | main.rs:532:9:532:13 | mut a | | +| main.rs:532:17:532:17 | 0 | main.rs:532:13:532:13 | a | | +| main.rs:533:5:533:5 | a | main.rs:533:10:533:10 | 1 | | +| main.rs:533:5:533:10 | ... += ... | main.rs:534:5:534:17 | ExprStmt | | +| main.rs:533:5:533:11 | ExprStmt | main.rs:533:5:533:5 | a | | +| main.rs:533:10:533:10 | 1 | main.rs:533:5:533:10 | ... += ... | | +| main.rs:534:5:534:13 | print_i64 | main.rs:534:15:534:15 | a | | +| main.rs:534:5:534:16 | print_i64(...) | main.rs:535:5:535:28 | ExprStmt | | +| main.rs:534:5:534:17 | ExprStmt | main.rs:534:5:534:13 | print_i64 | | +| main.rs:534:15:534:15 | a | main.rs:534:5:534:16 | print_i64(...) | | +| main.rs:535:5:535:27 | ... .add_assign(...) | main.rs:536:5:536:17 | ExprStmt | | +| main.rs:535:5:535:28 | ExprStmt | main.rs:535:11:535:11 | a | | +| main.rs:535:6:535:11 | &mut a | main.rs:535:25:535:26 | 10 | | +| main.rs:535:11:535:11 | a | main.rs:535:6:535:11 | &mut a | | +| main.rs:535:25:535:26 | 10 | main.rs:535:5:535:27 | ... .add_assign(...) | | +| main.rs:536:5:536:13 | print_i64 | main.rs:536:15:536:15 | a | | +| main.rs:536:5:536:16 | print_i64(...) | main.rs:531:17:537:1 | { ... } | | +| main.rs:536:5:536:17 | ExprStmt | main.rs:536:5:536:13 | print_i64 | | +| main.rs:536:15:536:15 | a | main.rs:536:5:536:16 | print_i64(...) | | +| main.rs:539:1:545:1 | enter fn mutate | main.rs:540:5:540:18 | let ... = 1 | | +| main.rs:539:1:545:1 | exit fn mutate (normal) | main.rs:539:1:545:1 | exit fn mutate | | +| main.rs:539:13:545:1 | { ... } | main.rs:539:1:545:1 | exit fn mutate (normal) | | +| main.rs:540:5:540:18 | let ... = 1 | main.rs:540:17:540:17 | 1 | | +| main.rs:540:9:540:13 | mut i | main.rs:541:5:542:15 | let ... = ... | match | +| main.rs:540:13:540:13 | i | main.rs:540:9:540:13 | mut i | | +| main.rs:540:17:540:17 | 1 | main.rs:540:13:540:13 | i | | +| main.rs:541:5:542:15 | let ... = ... | main.rs:542:14:542:14 | i | | +| main.rs:541:9:541:13 | ref_i | main.rs:541:9:541:13 | ref_i | | +| main.rs:541:9:541:13 | ref_i | main.rs:543:5:543:15 | ExprStmt | match | +| main.rs:542:9:542:14 | &mut i | main.rs:541:9:541:13 | ref_i | | +| main.rs:542:14:542:14 | i | main.rs:542:9:542:14 | &mut i | | +| main.rs:543:5:543:10 | * ... | main.rs:543:14:543:14 | 2 | | +| main.rs:543:5:543:14 | ... = ... | main.rs:544:5:544:17 | ExprStmt | | +| main.rs:543:5:543:15 | ExprStmt | main.rs:543:6:543:10 | ref_i | | +| main.rs:543:6:543:10 | ref_i | main.rs:543:5:543:10 | * ... | | +| main.rs:543:14:543:14 | 2 | main.rs:543:5:543:14 | ... = ... | | +| main.rs:544:5:544:13 | print_i64 | main.rs:544:15:544:15 | i | | +| main.rs:544:5:544:16 | print_i64(...) | main.rs:539:13:545:1 | { ... } | | +| main.rs:544:5:544:17 | ExprStmt | main.rs:544:5:544:13 | print_i64 | | +| main.rs:544:15:544:15 | i | main.rs:544:5:544:16 | print_i64(...) | | +| main.rs:547:1:552:1 | enter fn mutate_param | main.rs:547:17:547:17 | x | | +| main.rs:547:1:552:1 | exit fn mutate_param (normal) | main.rs:547:1:552:1 | exit fn mutate_param | | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:27 | ...: ... | match | +| main.rs:547:17:547:27 | ...: ... | main.rs:548:5:550:11 | ExprStmt | | +| main.rs:548:5:548:6 | * ... | main.rs:549:10:549:10 | x | | +| main.rs:548:5:550:10 | ... = ... | main.rs:551:5:551:13 | ExprStmt | | +| main.rs:548:5:550:11 | ExprStmt | main.rs:548:6:548:6 | x | | +| main.rs:548:6:548:6 | x | main.rs:548:5:548:6 | * ... | | +| main.rs:549:9:549:10 | * ... | main.rs:550:10:550:10 | x | | +| main.rs:549:9:550:10 | ... + ... | main.rs:548:5:550:10 | ... = ... | | +| main.rs:549:10:549:10 | x | main.rs:549:9:549:10 | * ... | | +| main.rs:550:9:550:10 | * ... | main.rs:549:9:550:10 | ... + ... | | +| main.rs:550:10:550:10 | x | main.rs:550:9:550:10 | * ... | | +| main.rs:551:5:551:12 | return x | main.rs:547:1:552:1 | exit fn mutate_param (normal) | return | +| main.rs:551:5:551:13 | ExprStmt | main.rs:551:12:551:12 | x | | +| main.rs:551:12:551:12 | x | main.rs:551:5:551:12 | return x | | +| main.rs:554:1:560:1 | enter fn mutate_param2 | main.rs:554:22:554:22 | x | | +| main.rs:554:1:560:1 | exit fn mutate_param2 (normal) | main.rs:554:1:560:1 | exit fn mutate_param2 | | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:35 | ...: ... | match | +| main.rs:554:22:554:35 | ...: ... | main.rs:554:38:554:38 | y | | +| main.rs:554:38:554:38 | y | main.rs:554:38:554:38 | y | | +| main.rs:554:38:554:38 | y | main.rs:554:38:554:56 | ...: ... | match | +| main.rs:554:38:554:56 | ...: ... | main.rs:555:5:557:11 | ExprStmt | | +| main.rs:554:59:560:1 | { ... } | main.rs:554:1:560:1 | exit fn mutate_param2 (normal) | | +| main.rs:555:5:555:6 | * ... | main.rs:556:10:556:10 | x | | +| main.rs:555:5:557:10 | ... = ... | main.rs:558:5:559:10 | ExprStmt | | +| main.rs:555:5:557:11 | ExprStmt | main.rs:555:6:555:6 | x | | +| main.rs:555:6:555:6 | x | main.rs:555:5:555:6 | * ... | | +| main.rs:556:9:556:10 | * ... | main.rs:557:10:557:10 | x | | +| main.rs:556:9:557:10 | ... + ... | main.rs:555:5:557:10 | ... = ... | | +| main.rs:556:10:556:10 | x | main.rs:556:9:556:10 | * ... | | +| main.rs:557:9:557:10 | * ... | main.rs:556:9:557:10 | ... + ... | | +| main.rs:557:10:557:10 | x | main.rs:557:9:557:10 | * ... | | +| main.rs:558:5:558:6 | * ... | main.rs:559:9:559:9 | x | | +| main.rs:558:5:559:9 | ... = ... | main.rs:554:59:560:1 | { ... } | | +| main.rs:558:5:559:10 | ExprStmt | main.rs:558:6:558:6 | y | | +| main.rs:558:6:558:6 | y | main.rs:558:5:558:6 | * ... | | +| main.rs:559:9:559:9 | x | main.rs:558:5:559:9 | ... = ... | | +| main.rs:562:1:582:1 | enter fn mutate_arg | main.rs:563:5:563:18 | let ... = 2 | | +| main.rs:562:1:582:1 | exit fn mutate_arg (normal) | main.rs:562:1:582:1 | exit fn mutate_arg | | +| main.rs:562:17:582:1 | { ... } | main.rs:562:1:582:1 | exit fn mutate_arg (normal) | | +| main.rs:563:5:563:18 | let ... = 2 | main.rs:563:17:563:17 | 2 | | +| main.rs:563:9:563:13 | mut x | main.rs:564:5:565:29 | let ... = ... | match | +| main.rs:563:13:563:13 | x | main.rs:563:9:563:13 | mut x | | +| main.rs:563:17:563:17 | 2 | main.rs:563:13:563:13 | x | | +| main.rs:564:5:565:29 | let ... = ... | main.rs:565:9:565:20 | mutate_param | | +| main.rs:564:9:564:9 | y | main.rs:564:9:564:9 | y | | +| main.rs:564:9:564:9 | y | main.rs:566:5:566:12 | ExprStmt | match | +| main.rs:565:9:565:20 | mutate_param | main.rs:565:27:565:27 | x | | +| main.rs:565:9:565:28 | mutate_param(...) | main.rs:564:9:564:9 | y | | +| main.rs:565:22:565:27 | &mut x | main.rs:565:9:565:28 | mutate_param(...) | | +| main.rs:565:27:565:27 | x | main.rs:565:22:565:27 | &mut x | | +| main.rs:566:5:566:6 | * ... | main.rs:566:10:566:11 | 10 | | +| main.rs:566:5:566:11 | ... = ... | main.rs:569:5:569:17 | ExprStmt | | +| main.rs:566:5:566:12 | ExprStmt | main.rs:566:6:566:6 | y | | +| main.rs:566:6:566:6 | y | main.rs:566:5:566:6 | * ... | | +| main.rs:566:10:566:11 | 10 | main.rs:566:5:566:11 | ... = ... | | +| main.rs:569:5:569:13 | print_i64 | main.rs:569:15:569:15 | x | | +| main.rs:569:5:569:16 | print_i64(...) | main.rs:571:5:571:18 | let ... = 4 | | +| main.rs:569:5:569:17 | ExprStmt | main.rs:569:5:569:13 | print_i64 | | +| main.rs:569:15:569:15 | x | main.rs:569:5:569:16 | print_i64(...) | | +| main.rs:571:5:571:18 | let ... = 4 | main.rs:571:17:571:17 | 4 | | +| main.rs:571:9:571:13 | mut z | main.rs:572:5:573:20 | let ... = ... | match | +| main.rs:571:13:571:13 | z | main.rs:571:9:571:13 | mut z | | +| main.rs:571:17:571:17 | 4 | main.rs:571:13:571:13 | z | | +| main.rs:572:5:573:20 | let ... = ... | main.rs:573:19:573:19 | x | | +| main.rs:572:9:572:9 | w | main.rs:572:9:572:9 | w | | +| main.rs:572:9:572:9 | w | main.rs:574:5:577:6 | ExprStmt | match | +| main.rs:573:9:573:19 | &mut ... | main.rs:572:9:572:9 | w | | +| main.rs:573:14:573:19 | &mut x | main.rs:573:9:573:19 | &mut ... | | +| main.rs:573:19:573:19 | x | main.rs:573:14:573:19 | &mut x | | +| main.rs:574:5:574:17 | mutate_param2 | main.rs:575:14:575:14 | z | | +| main.rs:574:5:577:5 | mutate_param2(...) | main.rs:578:5:578:13 | ExprStmt | | +| main.rs:574:5:577:6 | ExprStmt | main.rs:574:5:574:17 | mutate_param2 | | +| main.rs:575:9:575:14 | &mut z | main.rs:576:9:576:9 | w | | +| main.rs:575:14:575:14 | z | main.rs:575:9:575:14 | &mut z | | +| main.rs:576:9:576:9 | w | main.rs:574:5:577:5 | mutate_param2(...) | | +| main.rs:578:5:578:7 | * ... | main.rs:578:11:578:12 | 11 | | +| main.rs:578:5:578:12 | ... = ... | main.rs:581:5:581:17 | ExprStmt | | +| main.rs:578:5:578:13 | ExprStmt | main.rs:578:7:578:7 | w | | +| main.rs:578:6:578:7 | * ... | main.rs:578:5:578:7 | * ... | | +| main.rs:578:7:578:7 | w | main.rs:578:6:578:7 | * ... | | +| main.rs:578:11:578:12 | 11 | main.rs:578:5:578:12 | ... = ... | | +| main.rs:581:5:581:13 | print_i64 | main.rs:581:15:581:15 | z | | +| main.rs:581:5:581:16 | print_i64(...) | main.rs:562:17:582:1 | { ... } | | +| main.rs:581:5:581:17 | ExprStmt | main.rs:581:5:581:13 | print_i64 | | +| main.rs:581:15:581:15 | z | main.rs:581:5:581:16 | print_i64(...) | | +| main.rs:584:1:590:1 | enter fn alias | main.rs:585:5:585:18 | let ... = 1 | | +| main.rs:584:1:590:1 | exit fn alias (normal) | main.rs:584:1:590:1 | exit fn alias | | +| main.rs:584:12:590:1 | { ... } | main.rs:584:1:590:1 | exit fn alias (normal) | | +| main.rs:585:5:585:18 | let ... = 1 | main.rs:585:17:585:17 | 1 | | +| main.rs:585:9:585:13 | mut x | main.rs:586:5:587:15 | let ... = ... | match | +| main.rs:585:13:585:13 | x | main.rs:585:9:585:13 | mut x | | +| main.rs:585:17:585:17 | 1 | main.rs:585:13:585:13 | x | | +| main.rs:586:5:587:15 | let ... = ... | main.rs:587:14:587:14 | x | | +| main.rs:586:9:586:9 | y | main.rs:586:9:586:9 | y | | +| main.rs:586:9:586:9 | y | main.rs:588:5:588:11 | ExprStmt | match | +| main.rs:587:9:587:14 | &mut x | main.rs:586:9:586:9 | y | | +| main.rs:587:14:587:14 | x | main.rs:587:9:587:14 | &mut x | | +| main.rs:588:5:588:6 | * ... | main.rs:588:10:588:10 | 2 | | +| main.rs:588:5:588:10 | ... = ... | main.rs:589:5:589:17 | ExprStmt | | +| main.rs:588:5:588:11 | ExprStmt | main.rs:588:6:588:6 | y | | +| main.rs:588:6:588:6 | y | main.rs:588:5:588:6 | * ... | | +| main.rs:588:10:588:10 | 2 | main.rs:588:5:588:10 | ... = ... | | +| main.rs:589:5:589:13 | print_i64 | main.rs:589:15:589:15 | x | | +| main.rs:589:5:589:16 | print_i64(...) | main.rs:584:12:590:1 | { ... } | | +| main.rs:589:5:589:17 | ExprStmt | main.rs:589:5:589:13 | print_i64 | | +| main.rs:589:15:589:15 | x | main.rs:589:5:589:16 | print_i64(...) | | +| main.rs:592:1:601:1 | enter fn capture_immut | main.rs:593:5:593:16 | let ... = 100 | | +| main.rs:592:1:601:1 | exit fn capture_immut (normal) | main.rs:592:1:601:1 | exit fn capture_immut | | +| main.rs:592:20:601:1 | { ... } | main.rs:592:1:601:1 | exit fn capture_immut (normal) | | +| main.rs:593:5:593:16 | let ... = 100 | main.rs:593:13:593:15 | 100 | | +| main.rs:593:9:593:9 | x | main.rs:593:9:593:9 | x | | +| main.rs:593:9:593:9 | x | main.rs:596:5:598:6 | let ... = ... | match | +| main.rs:593:13:593:15 | 100 | main.rs:593:9:593:9 | x | | +| main.rs:596:5:598:6 | let ... = ... | main.rs:596:15:598:5 | \|...\| ... | | +| main.rs:596:9:596:11 | cap | main.rs:596:9:596:11 | cap | | +| main.rs:596:9:596:11 | cap | main.rs:599:5:599:10 | ExprStmt | match | +| main.rs:596:15:598:5 | \|...\| ... | main.rs:596:9:596:11 | cap | | +| main.rs:596:15:598:5 | enter \|...\| ... | main.rs:597:9:597:21 | ExprStmt | | +| main.rs:596:15:598:5 | exit \|...\| ... (normal) | main.rs:596:15:598:5 | exit \|...\| ... | | +| main.rs:596:18:598:5 | { ... } | main.rs:596:15:598:5 | exit \|...\| ... (normal) | | +| main.rs:597:9:597:17 | print_i64 | main.rs:597:19:597:19 | x | | +| main.rs:597:9:597:20 | print_i64(...) | main.rs:596:18:598:5 | { ... } | | +| main.rs:597:9:597:21 | ExprStmt | main.rs:597:9:597:17 | print_i64 | | +| main.rs:597:19:597:19 | x | main.rs:597:9:597:20 | print_i64(...) | | +| main.rs:599:5:599:7 | cap | main.rs:599:5:599:9 | cap(...) | | +| main.rs:599:5:599:9 | cap(...) | main.rs:600:5:600:17 | ExprStmt | | +| main.rs:599:5:599:10 | ExprStmt | main.rs:599:5:599:7 | cap | | +| main.rs:600:5:600:13 | print_i64 | main.rs:600:15:600:15 | x | | +| main.rs:600:5:600:16 | print_i64(...) | main.rs:592:20:601:1 | { ... } | | +| main.rs:600:5:600:17 | ExprStmt | main.rs:600:5:600:13 | print_i64 | | +| main.rs:600:15:600:15 | x | main.rs:600:5:600:16 | print_i64(...) | | +| main.rs:603:1:630:1 | enter fn capture_mut | main.rs:604:5:604:18 | let ... = 1 | | +| main.rs:603:1:630:1 | exit fn capture_mut (normal) | main.rs:603:1:630:1 | exit fn capture_mut | | +| main.rs:603:18:630:1 | { ... } | main.rs:603:1:630:1 | exit fn capture_mut (normal) | | +| main.rs:604:5:604:18 | let ... = 1 | main.rs:604:17:604:17 | 1 | | +| main.rs:604:9:604:13 | mut x | main.rs:607:5:609:6 | let ... = ... | match | +| main.rs:604:13:604:13 | x | main.rs:604:9:604:13 | mut x | | +| main.rs:604:17:604:17 | 1 | main.rs:604:13:604:13 | x | | +| main.rs:607:5:609:6 | let ... = ... | main.rs:607:20:609:5 | \|...\| ... | | +| main.rs:607:9:607:16 | closure1 | main.rs:607:9:607:16 | closure1 | | +| main.rs:607:9:607:16 | closure1 | main.rs:610:5:610:15 | ExprStmt | match | +| main.rs:607:20:609:5 | \|...\| ... | main.rs:607:9:607:16 | closure1 | | +| main.rs:607:20:609:5 | enter \|...\| ... | main.rs:608:9:608:21 | ExprStmt | | +| main.rs:607:20:609:5 | exit \|...\| ... (normal) | main.rs:607:20:609:5 | exit \|...\| ... | | +| main.rs:607:23:609:5 | { ... } | main.rs:607:20:609:5 | exit \|...\| ... (normal) | | +| main.rs:608:9:608:17 | print_i64 | main.rs:608:19:608:19 | x | | +| main.rs:608:9:608:20 | print_i64(...) | main.rs:607:23:609:5 | { ... } | | +| main.rs:608:9:608:21 | ExprStmt | main.rs:608:9:608:17 | print_i64 | | +| main.rs:608:19:608:19 | x | main.rs:608:9:608:20 | print_i64(...) | | +| main.rs:610:5:610:12 | closure1 | main.rs:610:5:610:14 | closure1(...) | | +| main.rs:610:5:610:14 | closure1(...) | main.rs:611:5:611:17 | ExprStmt | | +| main.rs:610:5:610:15 | ExprStmt | main.rs:610:5:610:12 | closure1 | | +| main.rs:611:5:611:13 | print_i64 | main.rs:611:15:611:15 | x | | +| main.rs:611:5:611:16 | print_i64(...) | main.rs:613:5:613:18 | let ... = 2 | | +| main.rs:611:5:611:17 | ExprStmt | main.rs:611:5:611:13 | print_i64 | | +| main.rs:611:15:611:15 | x | main.rs:611:5:611:16 | print_i64(...) | | +| main.rs:613:5:613:18 | let ... = 2 | main.rs:613:17:613:17 | 2 | | +| main.rs:613:9:613:13 | mut y | main.rs:616:5:618:6 | let ... = ... | match | +| main.rs:613:13:613:13 | y | main.rs:613:9:613:13 | mut y | | +| main.rs:613:17:613:17 | 2 | main.rs:613:13:613:13 | y | | +| main.rs:616:5:618:6 | let ... = ... | main.rs:616:24:618:5 | \|...\| ... | | +| main.rs:616:9:616:20 | mut closure2 | main.rs:619:5:619:15 | ExprStmt | match | +| main.rs:616:13:616:20 | closure2 | main.rs:616:9:616:20 | mut closure2 | | +| main.rs:616:24:618:5 | \|...\| ... | main.rs:616:13:616:20 | closure2 | | +| main.rs:616:24:618:5 | enter \|...\| ... | main.rs:617:9:617:14 | ExprStmt | | +| main.rs:616:24:618:5 | exit \|...\| ... (normal) | main.rs:616:24:618:5 | exit \|...\| ... | | +| main.rs:616:27:618:5 | { ... } | main.rs:616:24:618:5 | exit \|...\| ... (normal) | | +| main.rs:617:9:617:9 | y | main.rs:617:13:617:13 | 3 | | +| main.rs:617:9:617:13 | ... = ... | main.rs:616:27:618:5 | { ... } | | +| main.rs:617:9:617:14 | ExprStmt | main.rs:617:9:617:9 | y | | | main.rs:617:13:617:13 | 3 | main.rs:617:9:617:13 | ... = ... | | -| main.rs:618:9:618:17 | print_i64 | main.rs:618:19:618:19 | x | | -| main.rs:618:9:618:20 | print_i64(...) | main.rs:619:9:619:25 | ExprStmt | | -| main.rs:618:9:618:21 | ExprStmt | main.rs:618:9:618:17 | print_i64 | | -| main.rs:618:19:618:19 | x | main.rs:618:9:618:20 | print_i64(...) | | -| main.rs:619:9:619:17 | print_i64 | main.rs:619:19:619:19 | x | | -| main.rs:619:9:619:24 | print_i64(...) | main.rs:616:12:620:5 | { ... } | | -| main.rs:619:9:619:25 | ExprStmt | main.rs:619:9:619:17 | print_i64 | | -| main.rs:619:19:619:19 | x | main.rs:619:23:619:23 | 1 | | -| main.rs:619:19:619:23 | ... + ... | main.rs:619:9:619:24 | print_i64(...) | | -| main.rs:619:23:619:23 | 1 | main.rs:619:19:619:23 | ... + ... | | -| main.rs:621:5:621:13 | print_i64 | main.rs:621:15:621:15 | x | | -| main.rs:621:5:621:16 | print_i64(...) | main.rs:606:17:622:1 | { ... } | | -| main.rs:621:5:621:17 | ExprStmt | main.rs:621:5:621:13 | print_i64 | | -| main.rs:621:15:621:15 | x | main.rs:621:5:621:16 | print_i64(...) | | -| main.rs:624:1:641:1 | enter fn phi_read | main.rs:624:13:624:14 | b1 | | -| main.rs:624:1:641:1 | exit fn phi_read (normal) | main.rs:624:1:641:1 | exit fn phi_read | | -| main.rs:624:13:624:14 | b1 | main.rs:624:13:624:14 | b1 | | -| main.rs:624:13:624:14 | b1 | main.rs:624:13:624:20 | ...: bool | match | -| main.rs:624:13:624:20 | ...: bool | main.rs:624:23:624:24 | b2 | | -| main.rs:624:23:624:24 | b2 | main.rs:624:23:624:24 | b2 | | -| main.rs:624:23:624:24 | b2 | main.rs:624:23:624:30 | ...: bool | match | -| main.rs:624:23:624:30 | ...: bool | main.rs:625:5:625:14 | let ... = 1 | | -| main.rs:624:33:641:1 | { ... } | main.rs:624:1:641:1 | exit fn phi_read (normal) | | -| main.rs:625:5:625:14 | let ... = 1 | main.rs:625:13:625:13 | 1 | | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | | -| main.rs:625:9:625:9 | x | main.rs:626:5:632:6 | let _ = ... | match | -| main.rs:625:13:625:13 | 1 | main.rs:625:9:625:9 | x | | -| main.rs:626:5:632:6 | let _ = ... | main.rs:627:16:627:17 | b1 | | -| main.rs:627:9:627:9 | _ | main.rs:634:5:640:6 | let _ = ... | match | -| main.rs:627:13:632:5 | if b1 {...} else {...} | main.rs:627:9:627:9 | _ | | -| main.rs:627:16:627:17 | b1 | main.rs:629:9:629:21 | ExprStmt | true | -| main.rs:627:16:627:17 | b1 | main.rs:631:9:631:21 | ExprStmt | false | -| main.rs:628:5:630:5 | { ... } | main.rs:627:13:632:5 | if b1 {...} else {...} | | -| main.rs:629:9:629:17 | print_i64 | main.rs:629:19:629:19 | x | | -| main.rs:629:9:629:20 | print_i64(...) | main.rs:628:5:630:5 | { ... } | | -| main.rs:629:9:629:21 | ExprStmt | main.rs:629:9:629:17 | print_i64 | | -| main.rs:629:19:629:19 | x | main.rs:629:9:629:20 | print_i64(...) | | -| main.rs:630:12:632:5 | { ... } | main.rs:627:13:632:5 | if b1 {...} else {...} | | -| main.rs:631:9:631:17 | print_i64 | main.rs:631:19:631:19 | x | | -| main.rs:631:9:631:20 | print_i64(...) | main.rs:630:12:632:5 | { ... } | | -| main.rs:631:9:631:21 | ExprStmt | main.rs:631:9:631:17 | print_i64 | | -| main.rs:631:19:631:19 | x | main.rs:631:9:631:20 | print_i64(...) | | -| main.rs:634:5:640:6 | let _ = ... | main.rs:635:16:635:17 | b2 | | -| main.rs:635:9:635:9 | _ | main.rs:624:33:641:1 | { ... } | match | -| main.rs:635:13:640:5 | if b2 {...} else {...} | main.rs:635:9:635:9 | _ | | -| main.rs:635:16:635:17 | b2 | main.rs:637:9:637:21 | ExprStmt | true | -| main.rs:635:16:635:17 | b2 | main.rs:639:9:639:21 | ExprStmt | false | -| main.rs:636:5:638:5 | { ... } | main.rs:635:13:640:5 | if b2 {...} else {...} | | -| main.rs:637:9:637:17 | print_i64 | main.rs:637:19:637:19 | x | | -| main.rs:637:9:637:20 | print_i64(...) | main.rs:636:5:638:5 | { ... } | | -| main.rs:637:9:637:21 | ExprStmt | main.rs:637:9:637:17 | print_i64 | | -| main.rs:637:19:637:19 | x | main.rs:637:9:637:20 | print_i64(...) | | -| main.rs:638:12:640:5 | { ... } | main.rs:635:13:640:5 | if b2 {...} else {...} | | -| main.rs:639:9:639:17 | print_i64 | main.rs:639:19:639:19 | x | | -| main.rs:639:9:639:20 | print_i64(...) | main.rs:638:12:640:5 | { ... } | | -| main.rs:639:9:639:21 | ExprStmt | main.rs:639:9:639:17 | print_i64 | | -| main.rs:639:19:639:19 | x | main.rs:639:9:639:20 | print_i64(...) | | -| main.rs:648:5:650:5 | enter fn my_get | main.rs:648:20:648:23 | self | | -| main.rs:648:5:650:5 | exit fn my_get (normal) | main.rs:648:5:650:5 | exit fn my_get | | -| main.rs:648:15:648:23 | SelfParam | main.rs:649:9:649:24 | ExprStmt | | -| main.rs:648:20:648:23 | self | main.rs:648:15:648:23 | SelfParam | | -| main.rs:649:9:649:23 | return ... | main.rs:648:5:650:5 | exit fn my_get (normal) | return | -| main.rs:649:9:649:24 | ExprStmt | main.rs:649:16:649:19 | self | | -| main.rs:649:16:649:19 | self | main.rs:649:16:649:23 | self.val | | -| main.rs:649:16:649:23 | self.val | main.rs:649:9:649:23 | return ... | | -| main.rs:652:5:654:5 | enter fn id | main.rs:652:11:652:14 | self | | -| main.rs:652:5:654:5 | exit fn id (normal) | main.rs:652:5:654:5 | exit fn id | | -| main.rs:652:11:652:14 | SelfParam | main.rs:653:9:653:12 | self | | -| main.rs:652:11:652:14 | self | main.rs:652:11:652:14 | SelfParam | | -| main.rs:652:25:654:5 | { ... } | main.rs:652:5:654:5 | exit fn id (normal) | | -| main.rs:653:9:653:12 | self | main.rs:652:25:654:5 | { ... } | | -| main.rs:656:5:663:5 | enter fn my_method | main.rs:656:23:656:26 | self | | -| main.rs:656:5:663:5 | exit fn my_method (normal) | main.rs:656:5:663:5 | exit fn my_method | | -| main.rs:656:18:656:26 | SelfParam | main.rs:657:9:660:10 | let ... = ... | | -| main.rs:656:23:656:26 | self | main.rs:656:18:656:26 | SelfParam | | -| main.rs:656:29:663:5 | { ... } | main.rs:656:5:663:5 | exit fn my_method (normal) | | -| main.rs:657:9:660:10 | let ... = ... | main.rs:657:21:660:9 | \|...\| ... | | -| main.rs:657:13:657:17 | mut f | main.rs:661:9:661:13 | ExprStmt | match | -| main.rs:657:17:657:17 | f | main.rs:657:13:657:17 | mut f | | -| main.rs:657:21:660:9 | \|...\| ... | main.rs:657:17:657:17 | f | | -| main.rs:657:21:660:9 | enter \|...\| ... | main.rs:657:22:657:22 | n | | -| main.rs:657:21:660:9 | exit \|...\| ... (normal) | main.rs:657:21:660:9 | exit \|...\| ... | | -| main.rs:657:22:657:22 | ... | main.rs:659:13:659:26 | ExprStmt | | -| main.rs:657:22:657:22 | n | main.rs:657:22:657:22 | ... | match | -| main.rs:657:22:657:22 | n | main.rs:657:22:657:22 | n | | -| main.rs:657:25:660:9 | { ... } | main.rs:657:21:660:9 | exit \|...\| ... (normal) | | -| main.rs:659:13:659:16 | self | main.rs:659:13:659:20 | self.val | | -| main.rs:659:13:659:20 | self.val | main.rs:659:25:659:25 | n | | -| main.rs:659:13:659:25 | ... += ... | main.rs:657:25:660:9 | { ... } | | -| main.rs:659:13:659:26 | ExprStmt | main.rs:659:13:659:16 | self | | -| main.rs:659:25:659:25 | n | main.rs:659:13:659:25 | ... += ... | | -| main.rs:661:9:661:9 | f | main.rs:661:11:661:11 | 3 | | -| main.rs:661:9:661:12 | f(...) | main.rs:662:9:662:13 | ExprStmt | | -| main.rs:661:9:661:13 | ExprStmt | main.rs:661:9:661:9 | f | | -| main.rs:661:11:661:11 | 3 | main.rs:661:9:661:12 | f(...) | | -| main.rs:662:9:662:9 | f | main.rs:662:11:662:11 | 4 | | -| main.rs:662:9:662:12 | f(...) | main.rs:656:29:663:5 | { ... } | | -| main.rs:662:9:662:13 | ExprStmt | main.rs:662:9:662:9 | f | | -| main.rs:662:11:662:11 | 4 | main.rs:662:9:662:12 | f(...) | | -| main.rs:666:1:673:1 | enter fn structs | main.rs:667:5:667:36 | let ... = ... | | -| main.rs:666:1:673:1 | exit fn structs (normal) | main.rs:666:1:673:1 | exit fn structs | | -| main.rs:666:14:673:1 | { ... } | main.rs:666:1:673:1 | exit fn structs (normal) | | -| main.rs:667:5:667:36 | let ... = ... | main.rs:667:33:667:33 | 1 | | -| main.rs:667:9:667:13 | mut a | main.rs:668:5:668:26 | ExprStmt | match | -| main.rs:667:13:667:13 | a | main.rs:667:9:667:13 | mut a | | -| main.rs:667:17:667:35 | MyStruct {...} | main.rs:667:13:667:13 | a | | -| main.rs:667:33:667:33 | 1 | main.rs:667:17:667:35 | MyStruct {...} | | -| main.rs:668:5:668:13 | print_i64 | main.rs:668:15:668:15 | a | | -| main.rs:668:5:668:25 | print_i64(...) | main.rs:669:5:669:14 | ExprStmt | | -| main.rs:668:5:668:26 | ExprStmt | main.rs:668:5:668:13 | print_i64 | | -| main.rs:668:15:668:15 | a | main.rs:668:15:668:24 | a.my_get() | | -| main.rs:668:15:668:24 | a.my_get() | main.rs:668:5:668:25 | print_i64(...) | | -| main.rs:669:5:669:5 | a | main.rs:669:5:669:9 | a.val | | -| main.rs:669:5:669:9 | a.val | main.rs:669:13:669:13 | 5 | | -| main.rs:669:5:669:13 | ... = ... | main.rs:670:5:670:26 | ExprStmt | | -| main.rs:669:5:669:14 | ExprStmt | main.rs:669:5:669:5 | a | | -| main.rs:669:13:669:13 | 5 | main.rs:669:5:669:13 | ... = ... | | -| main.rs:670:5:670:13 | print_i64 | main.rs:670:15:670:15 | a | | -| main.rs:670:5:670:25 | print_i64(...) | main.rs:671:5:671:28 | ExprStmt | | -| main.rs:670:5:670:26 | ExprStmt | main.rs:670:5:670:13 | print_i64 | | -| main.rs:670:15:670:15 | a | main.rs:670:15:670:24 | a.my_get() | | -| main.rs:670:15:670:24 | a.my_get() | main.rs:670:5:670:25 | print_i64(...) | | -| main.rs:671:5:671:5 | a | main.rs:671:25:671:25 | 2 | | -| main.rs:671:5:671:27 | ... = ... | main.rs:672:5:672:26 | ExprStmt | | -| main.rs:671:5:671:28 | ExprStmt | main.rs:671:5:671:5 | a | | -| main.rs:671:9:671:27 | MyStruct {...} | main.rs:671:5:671:27 | ... = ... | | -| main.rs:671:25:671:25 | 2 | main.rs:671:9:671:27 | MyStruct {...} | | -| main.rs:672:5:672:13 | print_i64 | main.rs:672:15:672:15 | a | | -| main.rs:672:5:672:25 | print_i64(...) | main.rs:666:14:673:1 | { ... } | | -| main.rs:672:5:672:26 | ExprStmt | main.rs:672:5:672:13 | print_i64 | | -| main.rs:672:15:672:15 | a | main.rs:672:15:672:24 | a.my_get() | | -| main.rs:672:15:672:24 | a.my_get() | main.rs:672:5:672:25 | print_i64(...) | | -| main.rs:675:1:682:1 | enter fn arrays | main.rs:676:5:676:26 | let ... = ... | | -| main.rs:675:1:682:1 | exit fn arrays (normal) | main.rs:675:1:682:1 | exit fn arrays | | -| main.rs:675:13:682:1 | { ... } | main.rs:675:1:682:1 | exit fn arrays (normal) | | -| main.rs:676:5:676:26 | let ... = ... | main.rs:676:18:676:18 | 1 | | -| main.rs:676:9:676:13 | mut a | main.rs:677:5:677:20 | ExprStmt | match | -| main.rs:676:13:676:13 | a | main.rs:676:9:676:13 | mut a | | -| main.rs:676:17:676:25 | [...] | main.rs:676:13:676:13 | a | | -| main.rs:676:18:676:18 | 1 | main.rs:676:21:676:21 | 2 | | -| main.rs:676:21:676:21 | 2 | main.rs:676:24:676:24 | 3 | | -| main.rs:676:24:676:24 | 3 | main.rs:676:17:676:25 | [...] | | -| main.rs:677:5:677:13 | print_i64 | main.rs:677:15:677:15 | a | | -| main.rs:677:5:677:19 | print_i64(...) | main.rs:678:5:678:13 | ExprStmt | | -| main.rs:677:5:677:20 | ExprStmt | main.rs:677:5:677:13 | print_i64 | | -| main.rs:677:15:677:15 | a | main.rs:677:17:677:17 | 0 | | -| main.rs:677:15:677:18 | a[0] | main.rs:677:5:677:19 | print_i64(...) | | -| main.rs:677:17:677:17 | 0 | main.rs:677:15:677:18 | a[0] | | -| main.rs:678:5:678:5 | a | main.rs:678:7:678:7 | 1 | | -| main.rs:678:5:678:8 | a[1] | main.rs:678:12:678:12 | 5 | | -| main.rs:678:5:678:12 | ... = ... | main.rs:679:5:679:20 | ExprStmt | | -| main.rs:678:5:678:13 | ExprStmt | main.rs:678:5:678:5 | a | | -| main.rs:678:7:678:7 | 1 | main.rs:678:5:678:8 | a[1] | | -| main.rs:678:12:678:12 | 5 | main.rs:678:5:678:12 | ... = ... | | -| main.rs:679:5:679:13 | print_i64 | main.rs:679:15:679:15 | a | | -| main.rs:679:5:679:19 | print_i64(...) | main.rs:680:5:680:18 | ExprStmt | | -| main.rs:679:5:679:20 | ExprStmt | main.rs:679:5:679:13 | print_i64 | | -| main.rs:679:15:679:15 | a | main.rs:679:17:679:17 | 1 | | -| main.rs:679:15:679:18 | a[1] | main.rs:679:5:679:19 | print_i64(...) | | -| main.rs:679:17:679:17 | 1 | main.rs:679:15:679:18 | a[1] | | -| main.rs:680:5:680:5 | a | main.rs:680:10:680:10 | 4 | | -| main.rs:680:5:680:17 | ... = ... | main.rs:681:5:681:20 | ExprStmt | | -| main.rs:680:5:680:18 | ExprStmt | main.rs:680:5:680:5 | a | | -| main.rs:680:9:680:17 | [...] | main.rs:680:5:680:17 | ... = ... | | -| main.rs:680:10:680:10 | 4 | main.rs:680:13:680:13 | 5 | | -| main.rs:680:13:680:13 | 5 | main.rs:680:16:680:16 | 6 | | -| main.rs:680:16:680:16 | 6 | main.rs:680:9:680:17 | [...] | | -| main.rs:681:5:681:13 | print_i64 | main.rs:681:15:681:15 | a | | -| main.rs:681:5:681:19 | print_i64(...) | main.rs:675:13:682:1 | { ... } | | -| main.rs:681:5:681:20 | ExprStmt | main.rs:681:5:681:13 | print_i64 | | -| main.rs:681:15:681:15 | a | main.rs:681:17:681:17 | 2 | | -| main.rs:681:15:681:18 | a[2] | main.rs:681:5:681:19 | print_i64(...) | | -| main.rs:681:17:681:17 | 2 | main.rs:681:15:681:18 | a[2] | | -| main.rs:684:1:691:1 | enter fn ref_arg | main.rs:685:5:685:15 | let ... = 16 | | -| main.rs:684:1:691:1 | exit fn ref_arg (normal) | main.rs:684:1:691:1 | exit fn ref_arg | | -| main.rs:684:14:691:1 | { ... } | main.rs:684:1:691:1 | exit fn ref_arg (normal) | | -| main.rs:685:5:685:15 | let ... = 16 | main.rs:685:13:685:14 | 16 | | -| main.rs:685:9:685:9 | x | main.rs:685:9:685:9 | x | | -| main.rs:685:9:685:9 | x | main.rs:686:5:686:22 | ExprStmt | match | -| main.rs:685:13:685:14 | 16 | main.rs:685:9:685:9 | x | | -| main.rs:686:5:686:17 | print_i64_ref | main.rs:686:20:686:20 | x | | -| main.rs:686:5:686:21 | print_i64_ref(...) | main.rs:687:5:687:17 | ExprStmt | | -| main.rs:686:5:686:22 | ExprStmt | main.rs:686:5:686:17 | print_i64_ref | | -| main.rs:686:19:686:20 | &x | main.rs:686:5:686:21 | print_i64_ref(...) | | -| main.rs:686:20:686:20 | x | main.rs:686:19:686:20 | &x | | -| main.rs:687:5:687:13 | print_i64 | main.rs:687:15:687:15 | x | | -| main.rs:687:5:687:16 | print_i64(...) | main.rs:689:5:689:15 | let ... = 17 | | -| main.rs:687:5:687:17 | ExprStmt | main.rs:687:5:687:13 | print_i64 | | -| main.rs:687:15:687:15 | x | main.rs:687:5:687:16 | print_i64(...) | | -| main.rs:689:5:689:15 | let ... = 17 | main.rs:689:13:689:14 | 17 | | -| main.rs:689:9:689:9 | z | main.rs:689:9:689:9 | z | | -| main.rs:689:9:689:9 | z | main.rs:690:5:690:22 | ExprStmt | match | -| main.rs:689:13:689:14 | 17 | main.rs:689:9:689:9 | z | | -| main.rs:690:5:690:17 | print_i64_ref | main.rs:690:20:690:20 | z | | -| main.rs:690:5:690:21 | print_i64_ref(...) | main.rs:684:14:691:1 | { ... } | | -| main.rs:690:5:690:22 | ExprStmt | main.rs:690:5:690:17 | print_i64_ref | | -| main.rs:690:19:690:20 | &z | main.rs:690:5:690:21 | print_i64_ref(...) | | -| main.rs:690:20:690:20 | z | main.rs:690:19:690:20 | &z | | -| main.rs:698:5:700:5 | enter fn bar | main.rs:698:17:698:20 | self | | -| main.rs:698:5:700:5 | exit fn bar (normal) | main.rs:698:5:700:5 | exit fn bar | | -| main.rs:698:12:698:20 | SelfParam | main.rs:699:9:699:36 | ExprStmt | | -| main.rs:698:17:698:20 | self | main.rs:698:12:698:20 | SelfParam | | -| main.rs:698:23:700:5 | { ... } | main.rs:698:5:700:5 | exit fn bar (normal) | | -| main.rs:699:9:699:13 | * ... | main.rs:699:33:699:33 | 3 | | -| main.rs:699:9:699:35 | ... = ... | main.rs:698:23:700:5 | { ... } | | -| main.rs:699:9:699:36 | ExprStmt | main.rs:699:10:699:13 | self | | -| main.rs:699:10:699:13 | self | main.rs:699:9:699:13 | * ... | | -| main.rs:699:17:699:35 | MyStruct {...} | main.rs:699:9:699:35 | ... = ... | | -| main.rs:699:33:699:33 | 3 | main.rs:699:17:699:35 | MyStruct {...} | | -| main.rs:703:1:709:1 | enter fn ref_methodcall_receiver | main.rs:704:5:704:36 | let ... = ... | | -| main.rs:703:1:709:1 | exit fn ref_methodcall_receiver (normal) | main.rs:703:1:709:1 | exit fn ref_methodcall_receiver | | -| main.rs:703:30:709:1 | { ... } | main.rs:703:1:709:1 | exit fn ref_methodcall_receiver (normal) | | -| main.rs:704:5:704:36 | let ... = ... | main.rs:704:33:704:33 | 1 | | -| main.rs:704:9:704:13 | mut a | main.rs:705:5:705:12 | ExprStmt | match | -| main.rs:704:13:704:13 | a | main.rs:704:9:704:13 | mut a | | -| main.rs:704:17:704:35 | MyStruct {...} | main.rs:704:13:704:13 | a | | -| main.rs:704:33:704:33 | 1 | main.rs:704:17:704:35 | MyStruct {...} | | -| main.rs:705:5:705:5 | a | main.rs:705:5:705:11 | a.bar() | | -| main.rs:705:5:705:11 | a.bar() | main.rs:708:5:708:21 | ExprStmt | | -| main.rs:705:5:705:12 | ExprStmt | main.rs:705:5:705:5 | a | | +| main.rs:619:5:619:12 | closure2 | main.rs:619:5:619:14 | closure2(...) | | +| main.rs:619:5:619:14 | closure2(...) | main.rs:620:5:620:17 | ExprStmt | | +| main.rs:619:5:619:15 | ExprStmt | main.rs:619:5:619:12 | closure2 | | +| main.rs:620:5:620:13 | print_i64 | main.rs:620:15:620:15 | y | | +| main.rs:620:5:620:16 | print_i64(...) | main.rs:622:5:622:18 | let ... = 2 | | +| main.rs:620:5:620:17 | ExprStmt | main.rs:620:5:620:13 | print_i64 | | +| main.rs:620:15:620:15 | y | main.rs:620:5:620:16 | print_i64(...) | | +| main.rs:622:5:622:18 | let ... = 2 | main.rs:622:17:622:17 | 2 | | +| main.rs:622:9:622:13 | mut z | main.rs:625:5:627:6 | let ... = ... | match | +| main.rs:622:13:622:13 | z | main.rs:622:9:622:13 | mut z | | +| main.rs:622:17:622:17 | 2 | main.rs:622:13:622:13 | z | | +| main.rs:625:5:627:6 | let ... = ... | main.rs:625:24:627:5 | \|...\| ... | | +| main.rs:625:9:625:20 | mut closure3 | main.rs:628:5:628:15 | ExprStmt | match | +| main.rs:625:13:625:20 | closure3 | main.rs:625:9:625:20 | mut closure3 | | +| main.rs:625:24:627:5 | \|...\| ... | main.rs:625:13:625:20 | closure3 | | +| main.rs:625:24:627:5 | enter \|...\| ... | main.rs:626:9:626:24 | ExprStmt | | +| main.rs:625:24:627:5 | exit \|...\| ... (normal) | main.rs:625:24:627:5 | exit \|...\| ... | | +| main.rs:625:27:627:5 | { ... } | main.rs:625:24:627:5 | exit \|...\| ... (normal) | | +| main.rs:626:9:626:9 | z | main.rs:626:22:626:22 | 1 | | +| main.rs:626:9:626:23 | z.add_assign(...) | main.rs:625:27:627:5 | { ... } | | +| main.rs:626:9:626:24 | ExprStmt | main.rs:626:9:626:9 | z | | +| main.rs:626:22:626:22 | 1 | main.rs:626:9:626:23 | z.add_assign(...) | | +| main.rs:628:5:628:12 | closure3 | main.rs:628:5:628:14 | closure3(...) | | +| main.rs:628:5:628:14 | closure3(...) | main.rs:629:5:629:17 | ExprStmt | | +| main.rs:628:5:628:15 | ExprStmt | main.rs:628:5:628:12 | closure3 | | +| main.rs:629:5:629:13 | print_i64 | main.rs:629:15:629:15 | z | | +| main.rs:629:5:629:16 | print_i64(...) | main.rs:603:18:630:1 | { ... } | | +| main.rs:629:5:629:17 | ExprStmt | main.rs:629:5:629:13 | print_i64 | | +| main.rs:629:15:629:15 | z | main.rs:629:5:629:16 | print_i64(...) | | +| main.rs:632:1:640:1 | enter fn async_block_capture | main.rs:633:5:633:23 | let ... = 0 | | +| main.rs:632:1:640:1 | exit fn async_block_capture (normal) | main.rs:632:1:640:1 | exit fn async_block_capture | | +| main.rs:632:32:640:1 | { ... } | main.rs:632:1:640:1 | exit fn async_block_capture (normal) | | +| main.rs:633:5:633:23 | let ... = 0 | main.rs:633:22:633:22 | 0 | | +| main.rs:633:9:633:13 | mut i | main.rs:634:5:636:6 | let ... = ... | match | +| main.rs:633:13:633:13 | i | main.rs:633:9:633:13 | mut i | | +| main.rs:633:22:633:22 | 0 | main.rs:633:13:633:13 | i | | +| main.rs:634:5:636:6 | let ... = ... | main.rs:634:17:636:5 | { ... } | | +| main.rs:634:9:634:13 | block | main.rs:634:9:634:13 | block | | +| main.rs:634:9:634:13 | block | main.rs:638:5:638:16 | ExprStmt | match | +| main.rs:634:17:636:5 | enter { ... } | main.rs:635:9:635:14 | ExprStmt | | +| main.rs:634:17:636:5 | exit { ... } (normal) | main.rs:634:17:636:5 | exit { ... } | | +| main.rs:634:17:636:5 | { ... } | main.rs:634:9:634:13 | block | | +| main.rs:635:9:635:9 | i | main.rs:635:13:635:13 | 1 | | +| main.rs:635:9:635:13 | ... = ... | main.rs:634:17:636:5 | exit { ... } (normal) | | +| main.rs:635:9:635:14 | ExprStmt | main.rs:635:9:635:9 | i | | +| main.rs:635:13:635:13 | 1 | main.rs:635:9:635:13 | ... = ... | | +| main.rs:638:5:638:9 | block | main.rs:638:5:638:15 | await block | | +| main.rs:638:5:638:15 | await block | main.rs:639:5:639:17 | ExprStmt | | +| main.rs:638:5:638:16 | ExprStmt | main.rs:638:5:638:9 | block | | +| main.rs:639:5:639:13 | print_i64 | main.rs:639:15:639:15 | i | | +| main.rs:639:5:639:16 | print_i64(...) | main.rs:632:32:640:1 | { ... } | | +| main.rs:639:5:639:17 | ExprStmt | main.rs:639:5:639:13 | print_i64 | | +| main.rs:639:15:639:15 | i | main.rs:639:5:639:16 | print_i64(...) | | +| main.rs:642:1:658:1 | enter fn phi | main.rs:642:8:642:8 | b | | +| main.rs:642:1:658:1 | exit fn phi (normal) | main.rs:642:1:658:1 | exit fn phi | | +| main.rs:642:8:642:8 | b | main.rs:642:8:642:8 | b | | +| main.rs:642:8:642:8 | b | main.rs:642:8:642:14 | ...: bool | match | +| main.rs:642:8:642:14 | ...: bool | main.rs:643:5:643:18 | let ... = 1 | | +| main.rs:642:17:658:1 | { ... } | main.rs:642:1:658:1 | exit fn phi (normal) | | +| main.rs:643:5:643:18 | let ... = 1 | main.rs:643:17:643:17 | 1 | | +| main.rs:643:9:643:13 | mut x | main.rs:644:5:644:17 | ExprStmt | match | +| main.rs:643:13:643:13 | x | main.rs:643:9:643:13 | mut x | | +| main.rs:643:17:643:17 | 1 | main.rs:643:13:643:13 | x | | +| main.rs:644:5:644:13 | print_i64 | main.rs:644:15:644:15 | x | | +| main.rs:644:5:644:16 | print_i64(...) | main.rs:645:5:645:21 | ExprStmt | | +| main.rs:644:5:644:17 | ExprStmt | main.rs:644:5:644:13 | print_i64 | | +| main.rs:644:15:644:15 | x | main.rs:644:5:644:16 | print_i64(...) | | +| main.rs:645:5:645:13 | print_i64 | main.rs:645:15:645:15 | x | | +| main.rs:645:5:645:20 | print_i64(...) | main.rs:646:5:656:6 | let _ = ... | | +| main.rs:645:5:645:21 | ExprStmt | main.rs:645:5:645:13 | print_i64 | | +| main.rs:645:15:645:15 | x | main.rs:645:19:645:19 | 1 | | +| main.rs:645:15:645:19 | ... + ... | main.rs:645:5:645:20 | print_i64(...) | | +| main.rs:645:19:645:19 | 1 | main.rs:645:15:645:19 | ... + ... | | +| main.rs:646:5:656:6 | let _ = ... | main.rs:647:16:647:16 | b | | +| main.rs:647:9:647:9 | _ | main.rs:657:5:657:17 | ExprStmt | match | +| main.rs:647:13:656:5 | if b {...} else {...} | main.rs:647:9:647:9 | _ | | +| main.rs:647:16:647:16 | b | main.rs:649:9:649:14 | ExprStmt | true | +| main.rs:647:16:647:16 | b | main.rs:653:9:653:14 | ExprStmt | false | +| main.rs:648:5:652:5 | { ... } | main.rs:647:13:656:5 | if b {...} else {...} | | +| main.rs:649:9:649:9 | x | main.rs:649:13:649:13 | 2 | | +| main.rs:649:9:649:13 | ... = ... | main.rs:650:9:650:21 | ExprStmt | | +| main.rs:649:9:649:14 | ExprStmt | main.rs:649:9:649:9 | x | | +| main.rs:649:13:649:13 | 2 | main.rs:649:9:649:13 | ... = ... | | +| main.rs:650:9:650:17 | print_i64 | main.rs:650:19:650:19 | x | | +| main.rs:650:9:650:20 | print_i64(...) | main.rs:651:9:651:25 | ExprStmt | | +| main.rs:650:9:650:21 | ExprStmt | main.rs:650:9:650:17 | print_i64 | | +| main.rs:650:19:650:19 | x | main.rs:650:9:650:20 | print_i64(...) | | +| main.rs:651:9:651:17 | print_i64 | main.rs:651:19:651:19 | x | | +| main.rs:651:9:651:24 | print_i64(...) | main.rs:648:5:652:5 | { ... } | | +| main.rs:651:9:651:25 | ExprStmt | main.rs:651:9:651:17 | print_i64 | | +| main.rs:651:19:651:19 | x | main.rs:651:23:651:23 | 1 | | +| main.rs:651:19:651:23 | ... + ... | main.rs:651:9:651:24 | print_i64(...) | | +| main.rs:651:23:651:23 | 1 | main.rs:651:19:651:23 | ... + ... | | +| main.rs:652:12:656:5 | { ... } | main.rs:647:13:656:5 | if b {...} else {...} | | +| main.rs:653:9:653:9 | x | main.rs:653:13:653:13 | 3 | | +| main.rs:653:9:653:13 | ... = ... | main.rs:654:9:654:21 | ExprStmt | | +| main.rs:653:9:653:14 | ExprStmt | main.rs:653:9:653:9 | x | | +| main.rs:653:13:653:13 | 3 | main.rs:653:9:653:13 | ... = ... | | +| main.rs:654:9:654:17 | print_i64 | main.rs:654:19:654:19 | x | | +| main.rs:654:9:654:20 | print_i64(...) | main.rs:655:9:655:25 | ExprStmt | | +| main.rs:654:9:654:21 | ExprStmt | main.rs:654:9:654:17 | print_i64 | | +| main.rs:654:19:654:19 | x | main.rs:654:9:654:20 | print_i64(...) | | +| main.rs:655:9:655:17 | print_i64 | main.rs:655:19:655:19 | x | | +| main.rs:655:9:655:24 | print_i64(...) | main.rs:652:12:656:5 | { ... } | | +| main.rs:655:9:655:25 | ExprStmt | main.rs:655:9:655:17 | print_i64 | | +| main.rs:655:19:655:19 | x | main.rs:655:23:655:23 | 1 | | +| main.rs:655:19:655:23 | ... + ... | main.rs:655:9:655:24 | print_i64(...) | | +| main.rs:655:23:655:23 | 1 | main.rs:655:19:655:23 | ... + ... | | +| main.rs:657:5:657:13 | print_i64 | main.rs:657:15:657:15 | x | | +| main.rs:657:5:657:16 | print_i64(...) | main.rs:642:17:658:1 | { ... } | | +| main.rs:657:5:657:17 | ExprStmt | main.rs:657:5:657:13 | print_i64 | | +| main.rs:657:15:657:15 | x | main.rs:657:5:657:16 | print_i64(...) | | +| main.rs:660:1:677:1 | enter fn phi_read | main.rs:660:13:660:14 | b1 | | +| main.rs:660:1:677:1 | exit fn phi_read (normal) | main.rs:660:1:677:1 | exit fn phi_read | | +| main.rs:660:13:660:14 | b1 | main.rs:660:13:660:14 | b1 | | +| main.rs:660:13:660:14 | b1 | main.rs:660:13:660:20 | ...: bool | match | +| main.rs:660:13:660:20 | ...: bool | main.rs:660:23:660:24 | b2 | | +| main.rs:660:23:660:24 | b2 | main.rs:660:23:660:24 | b2 | | +| main.rs:660:23:660:24 | b2 | main.rs:660:23:660:30 | ...: bool | match | +| main.rs:660:23:660:30 | ...: bool | main.rs:661:5:661:14 | let ... = 1 | | +| main.rs:660:33:677:1 | { ... } | main.rs:660:1:677:1 | exit fn phi_read (normal) | | +| main.rs:661:5:661:14 | let ... = 1 | main.rs:661:13:661:13 | 1 | | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | | +| main.rs:661:9:661:9 | x | main.rs:662:5:668:6 | let _ = ... | match | +| main.rs:661:13:661:13 | 1 | main.rs:661:9:661:9 | x | | +| main.rs:662:5:668:6 | let _ = ... | main.rs:663:16:663:17 | b1 | | +| main.rs:663:9:663:9 | _ | main.rs:670:5:676:6 | let _ = ... | match | +| main.rs:663:13:668:5 | if b1 {...} else {...} | main.rs:663:9:663:9 | _ | | +| main.rs:663:16:663:17 | b1 | main.rs:665:9:665:21 | ExprStmt | true | +| main.rs:663:16:663:17 | b1 | main.rs:667:9:667:21 | ExprStmt | false | +| main.rs:664:5:666:5 | { ... } | main.rs:663:13:668:5 | if b1 {...} else {...} | | +| main.rs:665:9:665:17 | print_i64 | main.rs:665:19:665:19 | x | | +| main.rs:665:9:665:20 | print_i64(...) | main.rs:664:5:666:5 | { ... } | | +| main.rs:665:9:665:21 | ExprStmt | main.rs:665:9:665:17 | print_i64 | | +| main.rs:665:19:665:19 | x | main.rs:665:9:665:20 | print_i64(...) | | +| main.rs:666:12:668:5 | { ... } | main.rs:663:13:668:5 | if b1 {...} else {...} | | +| main.rs:667:9:667:17 | print_i64 | main.rs:667:19:667:19 | x | | +| main.rs:667:9:667:20 | print_i64(...) | main.rs:666:12:668:5 | { ... } | | +| main.rs:667:9:667:21 | ExprStmt | main.rs:667:9:667:17 | print_i64 | | +| main.rs:667:19:667:19 | x | main.rs:667:9:667:20 | print_i64(...) | | +| main.rs:670:5:676:6 | let _ = ... | main.rs:671:16:671:17 | b2 | | +| main.rs:671:9:671:9 | _ | main.rs:660:33:677:1 | { ... } | match | +| main.rs:671:13:676:5 | if b2 {...} else {...} | main.rs:671:9:671:9 | _ | | +| main.rs:671:16:671:17 | b2 | main.rs:673:9:673:21 | ExprStmt | true | +| main.rs:671:16:671:17 | b2 | main.rs:675:9:675:21 | ExprStmt | false | +| main.rs:672:5:674:5 | { ... } | main.rs:671:13:676:5 | if b2 {...} else {...} | | +| main.rs:673:9:673:17 | print_i64 | main.rs:673:19:673:19 | x | | +| main.rs:673:9:673:20 | print_i64(...) | main.rs:672:5:674:5 | { ... } | | +| main.rs:673:9:673:21 | ExprStmt | main.rs:673:9:673:17 | print_i64 | | +| main.rs:673:19:673:19 | x | main.rs:673:9:673:20 | print_i64(...) | | +| main.rs:674:12:676:5 | { ... } | main.rs:671:13:676:5 | if b2 {...} else {...} | | +| main.rs:675:9:675:17 | print_i64 | main.rs:675:19:675:19 | x | | +| main.rs:675:9:675:20 | print_i64(...) | main.rs:674:12:676:5 | { ... } | | +| main.rs:675:9:675:21 | ExprStmt | main.rs:675:9:675:17 | print_i64 | | +| main.rs:675:19:675:19 | x | main.rs:675:9:675:20 | print_i64(...) | | +| main.rs:684:5:686:5 | enter fn my_get | main.rs:684:20:684:23 | self | | +| main.rs:684:5:686:5 | exit fn my_get (normal) | main.rs:684:5:686:5 | exit fn my_get | | +| main.rs:684:15:684:23 | SelfParam | main.rs:685:9:685:24 | ExprStmt | | +| main.rs:684:20:684:23 | self | main.rs:684:15:684:23 | SelfParam | | +| main.rs:685:9:685:23 | return ... | main.rs:684:5:686:5 | exit fn my_get (normal) | return | +| main.rs:685:9:685:24 | ExprStmt | main.rs:685:16:685:19 | self | | +| main.rs:685:16:685:19 | self | main.rs:685:16:685:23 | self.val | | +| main.rs:685:16:685:23 | self.val | main.rs:685:9:685:23 | return ... | | +| main.rs:688:5:690:5 | enter fn id | main.rs:688:11:688:14 | self | | +| main.rs:688:5:690:5 | exit fn id (normal) | main.rs:688:5:690:5 | exit fn id | | +| main.rs:688:11:688:14 | SelfParam | main.rs:689:9:689:12 | self | | +| main.rs:688:11:688:14 | self | main.rs:688:11:688:14 | SelfParam | | +| main.rs:688:25:690:5 | { ... } | main.rs:688:5:690:5 | exit fn id (normal) | | +| main.rs:689:9:689:12 | self | main.rs:688:25:690:5 | { ... } | | +| main.rs:692:5:699:5 | enter fn my_method | main.rs:692:23:692:26 | self | | +| main.rs:692:5:699:5 | exit fn my_method (normal) | main.rs:692:5:699:5 | exit fn my_method | | +| main.rs:692:18:692:26 | SelfParam | main.rs:693:9:696:10 | let ... = ... | | +| main.rs:692:23:692:26 | self | main.rs:692:18:692:26 | SelfParam | | +| main.rs:692:29:699:5 | { ... } | main.rs:692:5:699:5 | exit fn my_method (normal) | | +| main.rs:693:9:696:10 | let ... = ... | main.rs:693:21:696:9 | \|...\| ... | | +| main.rs:693:13:693:17 | mut f | main.rs:697:9:697:13 | ExprStmt | match | +| main.rs:693:17:693:17 | f | main.rs:693:13:693:17 | mut f | | +| main.rs:693:21:696:9 | \|...\| ... | main.rs:693:17:693:17 | f | | +| main.rs:693:21:696:9 | enter \|...\| ... | main.rs:693:22:693:22 | n | | +| main.rs:693:21:696:9 | exit \|...\| ... (normal) | main.rs:693:21:696:9 | exit \|...\| ... | | +| main.rs:693:22:693:22 | ... | main.rs:695:13:695:26 | ExprStmt | | +| main.rs:693:22:693:22 | n | main.rs:693:22:693:22 | ... | match | +| main.rs:693:22:693:22 | n | main.rs:693:22:693:22 | n | | +| main.rs:693:25:696:9 | { ... } | main.rs:693:21:696:9 | exit \|...\| ... (normal) | | +| main.rs:695:13:695:16 | self | main.rs:695:13:695:20 | self.val | | +| main.rs:695:13:695:20 | self.val | main.rs:695:25:695:25 | n | | +| main.rs:695:13:695:25 | ... += ... | main.rs:693:25:696:9 | { ... } | | +| main.rs:695:13:695:26 | ExprStmt | main.rs:695:13:695:16 | self | | +| main.rs:695:25:695:25 | n | main.rs:695:13:695:25 | ... += ... | | +| main.rs:697:9:697:9 | f | main.rs:697:11:697:11 | 3 | | +| main.rs:697:9:697:12 | f(...) | main.rs:698:9:698:13 | ExprStmt | | +| main.rs:697:9:697:13 | ExprStmt | main.rs:697:9:697:9 | f | | +| main.rs:697:11:697:11 | 3 | main.rs:697:9:697:12 | f(...) | | +| main.rs:698:9:698:9 | f | main.rs:698:11:698:11 | 4 | | +| main.rs:698:9:698:12 | f(...) | main.rs:692:29:699:5 | { ... } | | +| main.rs:698:9:698:13 | ExprStmt | main.rs:698:9:698:9 | f | | +| main.rs:698:11:698:11 | 4 | main.rs:698:9:698:12 | f(...) | | +| main.rs:702:1:709:1 | enter fn structs | main.rs:703:5:703:36 | let ... = ... | | +| main.rs:702:1:709:1 | exit fn structs (normal) | main.rs:702:1:709:1 | exit fn structs | | +| main.rs:702:14:709:1 | { ... } | main.rs:702:1:709:1 | exit fn structs (normal) | | +| main.rs:703:5:703:36 | let ... = ... | main.rs:703:33:703:33 | 1 | | +| main.rs:703:9:703:13 | mut a | main.rs:704:5:704:26 | ExprStmt | match | +| main.rs:703:13:703:13 | a | main.rs:703:9:703:13 | mut a | | +| main.rs:703:17:703:35 | MyStruct {...} | main.rs:703:13:703:13 | a | | +| main.rs:703:33:703:33 | 1 | main.rs:703:17:703:35 | MyStruct {...} | | +| main.rs:704:5:704:13 | print_i64 | main.rs:704:15:704:15 | a | | +| main.rs:704:5:704:25 | print_i64(...) | main.rs:705:5:705:14 | ExprStmt | | +| main.rs:704:5:704:26 | ExprStmt | main.rs:704:5:704:13 | print_i64 | | +| main.rs:704:15:704:15 | a | main.rs:704:15:704:24 | a.my_get() | | +| main.rs:704:15:704:24 | a.my_get() | main.rs:704:5:704:25 | print_i64(...) | | +| main.rs:705:5:705:5 | a | main.rs:705:5:705:9 | a.val | | +| main.rs:705:5:705:9 | a.val | main.rs:705:13:705:13 | 5 | | +| main.rs:705:5:705:13 | ... = ... | main.rs:706:5:706:26 | ExprStmt | | +| main.rs:705:5:705:14 | ExprStmt | main.rs:705:5:705:5 | a | | +| main.rs:705:13:705:13 | 5 | main.rs:705:5:705:13 | ... = ... | | +| main.rs:706:5:706:13 | print_i64 | main.rs:706:15:706:15 | a | | +| main.rs:706:5:706:25 | print_i64(...) | main.rs:707:5:707:28 | ExprStmt | | +| main.rs:706:5:706:26 | ExprStmt | main.rs:706:5:706:13 | print_i64 | | +| main.rs:706:15:706:15 | a | main.rs:706:15:706:24 | a.my_get() | | +| main.rs:706:15:706:24 | a.my_get() | main.rs:706:5:706:25 | print_i64(...) | | +| main.rs:707:5:707:5 | a | main.rs:707:25:707:25 | 2 | | +| main.rs:707:5:707:27 | ... = ... | main.rs:708:5:708:26 | ExprStmt | | +| main.rs:707:5:707:28 | ExprStmt | main.rs:707:5:707:5 | a | | +| main.rs:707:9:707:27 | MyStruct {...} | main.rs:707:5:707:27 | ... = ... | | +| main.rs:707:25:707:25 | 2 | main.rs:707:9:707:27 | MyStruct {...} | | | main.rs:708:5:708:13 | print_i64 | main.rs:708:15:708:15 | a | | -| main.rs:708:5:708:20 | print_i64(...) | main.rs:703:30:709:1 | { ... } | | -| main.rs:708:5:708:21 | ExprStmt | main.rs:708:5:708:13 | print_i64 | | -| main.rs:708:15:708:15 | a | main.rs:708:15:708:19 | a.val | | -| main.rs:708:15:708:19 | a.val | main.rs:708:5:708:20 | print_i64(...) | | -| main.rs:725:1:736:1 | enter fn macro_invocation | main.rs:726:5:727:26 | let ... = ... | | -| main.rs:725:1:736:1 | exit fn macro_invocation (normal) | main.rs:725:1:736:1 | exit fn macro_invocation | | -| main.rs:725:23:736:1 | { ... } | main.rs:725:1:736:1 | exit fn macro_invocation (normal) | | -| main.rs:726:5:727:26 | let ... = ... | main.rs:727:23:727:24 | let ... = 37 | | -| main.rs:726:9:726:22 | var_from_macro | main.rs:726:9:726:22 | var_from_macro | | -| main.rs:726:9:726:22 | var_from_macro | main.rs:728:5:728:30 | ExprStmt | match | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:9:727:21 | var_in_macro | | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:9:727:21 | var_in_macro | match | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:23:727:24 | { ... } | | -| main.rs:727:9:727:25 | MacroExpr | main.rs:726:9:726:22 | var_from_macro | | -| main.rs:727:9:727:25 | let_in_macro!... | main.rs:727:9:727:25 | MacroExpr | | -| main.rs:727:23:727:24 | 37 | main.rs:727:9:727:21 | var_in_macro | | -| main.rs:727:23:727:24 | let ... = 37 | main.rs:727:23:727:24 | 37 | | -| main.rs:727:23:727:24 | { ... } | main.rs:727:9:727:25 | let_in_macro!... | | -| main.rs:728:5:728:13 | print_i64 | main.rs:728:15:728:28 | var_from_macro | | -| main.rs:728:5:728:29 | print_i64(...) | main.rs:729:5:729:26 | let ... = 33 | | -| main.rs:728:5:728:30 | ExprStmt | main.rs:728:5:728:13 | print_i64 | | -| main.rs:728:15:728:28 | var_from_macro | main.rs:728:5:728:29 | print_i64(...) | | -| main.rs:729:5:729:26 | let ... = 33 | main.rs:729:24:729:25 | 33 | | -| main.rs:729:9:729:20 | var_in_macro | main.rs:729:9:729:20 | var_in_macro | | -| main.rs:729:9:729:20 | var_in_macro | main.rs:734:5:734:44 | ExprStmt | match | -| main.rs:729:24:729:25 | 33 | main.rs:729:9:729:20 | var_in_macro | | -| main.rs:734:5:734:13 | print_i64 | main.rs:734:15:734:28 | let ... = 0 | | -| main.rs:734:5:734:43 | print_i64(...) | main.rs:735:5:735:28 | ExprStmt | | -| main.rs:734:5:734:44 | ExprStmt | main.rs:734:5:734:13 | print_i64 | | -| main.rs:734:15:734:28 | 0 | main.rs:734:15:734:28 | var_in_macro | | -| main.rs:734:15:734:28 | let ... = 0 | main.rs:734:15:734:28 | 0 | | -| main.rs:734:15:734:28 | var_in_macro | main.rs:734:15:734:28 | var_in_macro | | -| main.rs:734:15:734:28 | var_in_macro | main.rs:734:30:734:41 | var_in_macro | match | -| main.rs:734:15:734:42 | MacroExpr | main.rs:734:5:734:43 | print_i64(...) | | -| main.rs:734:15:734:42 | let_in_macro2!... | main.rs:734:15:734:42 | MacroExpr | | -| main.rs:734:30:734:41 | var_in_macro | main.rs:734:30:734:41 | { ... } | | -| main.rs:734:30:734:41 | { ... } | main.rs:734:15:734:42 | let_in_macro2!... | | -| main.rs:735:5:735:13 | print_i64 | main.rs:735:15:735:26 | var_in_macro | | -| main.rs:735:5:735:27 | print_i64(...) | main.rs:725:23:736:1 | { ... } | | -| main.rs:735:5:735:28 | ExprStmt | main.rs:735:5:735:13 | print_i64 | | -| main.rs:735:15:735:26 | var_in_macro | main.rs:735:5:735:27 | print_i64(...) | | -| main.rs:738:1:742:1 | enter fn let_without_initializer | main.rs:739:5:739:10 | let ... | | -| main.rs:738:1:742:1 | exit fn let_without_initializer (normal) | main.rs:738:1:742:1 | exit fn let_without_initializer | | -| main.rs:738:30:742:1 | { ... } | main.rs:738:1:742:1 | exit fn let_without_initializer (normal) | | -| main.rs:739:5:739:10 | let ... | main.rs:739:9:739:9 | x | | -| main.rs:739:9:739:9 | x | main.rs:739:9:739:9 | x | | -| main.rs:739:9:739:9 | x | main.rs:740:5:740:10 | ExprStmt | match | -| main.rs:740:5:740:5 | x | main.rs:740:9:740:9 | 1 | | -| main.rs:740:5:740:9 | ... = ... | main.rs:741:5:741:17 | ExprStmt | | -| main.rs:740:5:740:10 | ExprStmt | main.rs:740:5:740:5 | x | | -| main.rs:740:9:740:9 | 1 | main.rs:740:5:740:9 | ... = ... | | -| main.rs:741:5:741:13 | print_i64 | main.rs:741:15:741:15 | x | | -| main.rs:741:5:741:16 | print_i64(...) | main.rs:738:30:742:1 | { ... } | | -| main.rs:741:5:741:17 | ExprStmt | main.rs:741:5:741:13 | print_i64 | | -| main.rs:741:15:741:15 | x | main.rs:741:5:741:16 | print_i64(...) | | -| main.rs:744:1:754:1 | enter fn capture_phi | main.rs:745:5:745:20 | let ... = 100 | | -| main.rs:744:1:754:1 | exit fn capture_phi (normal) | main.rs:744:1:754:1 | exit fn capture_phi | | -| main.rs:744:18:754:1 | { ... } | main.rs:744:1:754:1 | exit fn capture_phi (normal) | | -| main.rs:745:5:745:20 | let ... = 100 | main.rs:745:17:745:19 | 100 | | -| main.rs:745:9:745:13 | mut x | main.rs:746:5:751:6 | let ... = ... | match | -| main.rs:745:13:745:13 | x | main.rs:745:9:745:13 | mut x | | -| main.rs:745:17:745:19 | 100 | main.rs:745:13:745:13 | x | | -| main.rs:746:5:751:6 | let ... = ... | main.rs:746:19:751:5 | \|...\| ... | | -| main.rs:746:9:746:15 | mut cap | main.rs:752:5:752:14 | ExprStmt | match | -| main.rs:746:13:746:15 | cap | main.rs:746:9:746:15 | mut cap | | -| main.rs:746:19:751:5 | \|...\| ... | main.rs:746:13:746:15 | cap | | -| main.rs:746:19:751:5 | enter \|...\| ... | main.rs:746:20:746:20 | b | | -| main.rs:746:19:751:5 | exit \|...\| ... (normal) | main.rs:746:19:751:5 | exit \|...\| ... | | -| main.rs:746:20:746:20 | b | main.rs:746:20:746:20 | b | | -| main.rs:746:20:746:20 | b | main.rs:746:20:746:26 | ...: bool | match | -| main.rs:746:20:746:26 | ...: bool | main.rs:747:9:750:10 | let _ = ... | | -| main.rs:746:29:751:5 | { ... } | main.rs:746:19:751:5 | exit \|...\| ... (normal) | | -| main.rs:747:9:750:10 | let _ = ... | main.rs:748:20:748:20 | b | | -| main.rs:748:13:748:13 | _ | main.rs:746:29:751:5 | { ... } | match | -| main.rs:748:17:750:9 | if b {...} | main.rs:748:13:748:13 | _ | | -| main.rs:748:20:748:20 | b | main.rs:748:17:750:9 | if b {...} | false | -| main.rs:748:20:748:20 | b | main.rs:749:13:749:20 | ExprStmt | true | -| main.rs:748:22:750:9 | { ... } | main.rs:748:17:750:9 | if b {...} | | -| main.rs:749:13:749:13 | x | main.rs:749:17:749:19 | 200 | | -| main.rs:749:13:749:19 | ... = ... | main.rs:748:22:750:9 | { ... } | | -| main.rs:749:13:749:20 | ExprStmt | main.rs:749:13:749:13 | x | | -| main.rs:749:17:749:19 | 200 | main.rs:749:13:749:19 | ... = ... | | -| main.rs:752:5:752:7 | cap | main.rs:752:9:752:12 | true | | -| main.rs:752:5:752:13 | cap(...) | main.rs:753:5:753:17 | ExprStmt | | -| main.rs:752:5:752:14 | ExprStmt | main.rs:752:5:752:7 | cap | | -| main.rs:752:9:752:12 | true | main.rs:752:5:752:13 | cap(...) | | -| main.rs:753:5:753:13 | print_i64 | main.rs:753:15:753:15 | x | | -| main.rs:753:5:753:16 | print_i64(...) | main.rs:744:18:754:1 | { ... } | | -| main.rs:753:5:753:17 | ExprStmt | main.rs:753:5:753:13 | print_i64 | | -| main.rs:753:15:753:15 | x | main.rs:753:5:753:16 | print_i64(...) | | -| main.rs:757:5:772:5 | enter fn test | main.rs:759:9:759:25 | let ... = ... | | -| main.rs:757:5:772:5 | exit fn test (normal) | main.rs:757:5:772:5 | exit fn test | | -| main.rs:758:34:772:5 | { ... } | main.rs:757:5:772:5 | exit fn test (normal) | | -| main.rs:759:9:759:25 | let ... = ... | main.rs:759:17:759:20 | Some | | -| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | | -| main.rs:759:13:759:13 | x | main.rs:760:9:767:10 | let ... = ... | match | -| main.rs:759:17:759:20 | Some | main.rs:759:22:759:23 | 42 | | -| main.rs:759:17:759:24 | Some(...) | main.rs:759:13:759:13 | x | | -| main.rs:759:22:759:23 | 42 | main.rs:759:17:759:24 | Some(...) | | -| main.rs:760:9:767:10 | let ... = ... | main.rs:761:19:761:19 | x | | -| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | | -| main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y | match | -| main.rs:761:13:767:9 | match x { ... } | main.rs:760:13:760:13 | y | | -| main.rs:761:19:761:19 | x | main.rs:762:13:762:19 | Some(...) | | -| main.rs:762:13:762:19 | Some(...) | main.rs:762:18:762:18 | y | match | -| main.rs:762:13:762:19 | Some(...) | main.rs:765:13:765:16 | None | no-match | -| main.rs:762:18:762:18 | y | main.rs:762:18:762:18 | y | | -| main.rs:762:18:762:18 | y | main.rs:763:17:763:20 | None | match | -| main.rs:762:24:764:13 | { ... } | main.rs:761:13:767:9 | match x { ... } | | -| main.rs:763:17:763:20 | None | main.rs:762:24:764:13 | { ... } | | -| main.rs:765:13:765:16 | None | main.rs:765:13:765:16 | None | | -| main.rs:765:13:765:16 | None | main.rs:766:17:766:20 | None | match | -| main.rs:766:17:766:20 | None | main.rs:761:13:767:9 | match x { ... } | | -| main.rs:768:9:771:9 | match y { ... } | main.rs:758:34:772:5 | { ... } | | -| main.rs:768:15:768:15 | y | main.rs:769:13:769:16 | N0ne | | -| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | | -| main.rs:769:13:769:16 | N0ne | main.rs:770:17:770:20 | N0ne | match | -| main.rs:770:17:770:20 | N0ne | main.rs:768:9:771:9 | match y { ... } | | -| main.rs:774:5:781:5 | enter fn test2 | main.rs:776:9:777:17 | let ... = test | | -| main.rs:774:5:781:5 | exit fn test2 (normal) | main.rs:774:5:781:5 | exit fn test2 | | -| main.rs:775:31:781:5 | { ... } | main.rs:774:5:781:5 | exit fn test2 (normal) | | -| main.rs:776:9:777:17 | let ... = test | main.rs:777:13:777:16 | test | | -| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | | -| main.rs:776:13:776:22 | test_alias | main.rs:778:9:779:25 | let ... = ... | match | -| main.rs:777:13:777:16 | test | main.rs:776:13:776:22 | test_alias | | -| main.rs:778:9:779:25 | let ... = ... | main.rs:779:13:779:22 | test_alias | | -| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | | -| main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test | match | -| main.rs:779:13:779:22 | test_alias | main.rs:779:13:779:24 | test_alias(...) | | -| main.rs:779:13:779:24 | test_alias(...) | main.rs:778:13:778:16 | test | | -| main.rs:780:9:780:12 | test | main.rs:775:31:781:5 | { ... } | | -| main.rs:785:5:798:5 | enter fn test3 | main.rs:787:9:787:24 | let ... = ... | | -| main.rs:785:5:798:5 | exit fn test3 (normal) | main.rs:785:5:798:5 | exit fn test3 | | -| main.rs:786:16:798:5 | { ... } | main.rs:785:5:798:5 | exit fn test3 (normal) | | -| main.rs:787:9:787:24 | let ... = ... | main.rs:787:17:787:20 | Some | | -| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | | -| main.rs:787:13:787:13 | x | main.rs:788:9:792:10 | ExprStmt | match | -| main.rs:787:17:787:20 | Some | main.rs:787:22:787:22 | 0 | | -| main.rs:787:17:787:23 | Some(...) | main.rs:787:13:787:13 | x | | -| main.rs:787:22:787:22 | 0 | main.rs:787:17:787:23 | Some(...) | | -| main.rs:788:9:792:9 | match x { ... } | main.rs:793:9:797:10 | ExprStmt | | -| main.rs:788:9:792:10 | ExprStmt | main.rs:788:15:788:15 | x | | -| main.rs:788:15:788:15 | x | main.rs:789:13:789:19 | Some(...) | | -| main.rs:789:13:789:19 | Some(...) | main.rs:789:18:789:18 | x | match | -| main.rs:789:13:789:19 | Some(...) | main.rs:791:13:791:13 | _ | no-match | -| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | | -| main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x | match | -| main.rs:790:20:790:20 | x | main.rs:788:9:792:9 | match x { ... } | | -| main.rs:791:13:791:13 | _ | main.rs:791:18:791:18 | 0 | match | -| main.rs:791:18:791:18 | 0 | main.rs:788:9:792:9 | match x { ... } | | -| main.rs:793:9:797:9 | match x { ... } | main.rs:786:16:798:5 | { ... } | | -| main.rs:793:9:797:10 | ExprStmt | main.rs:793:15:793:15 | x | | -| main.rs:793:15:793:15 | x | main.rs:794:13:794:19 | Some(...) | | -| main.rs:794:13:794:19 | Some(...) | main.rs:794:18:794:18 | z | match | -| main.rs:794:13:794:19 | Some(...) | main.rs:796:13:796:13 | _ | no-match | -| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z | | -| main.rs:794:18:794:18 | z | main.rs:795:17:795:17 | z | match | -| main.rs:794:18:794:18 | z | main.rs:796:13:796:13 | _ | no-match | -| main.rs:795:17:795:17 | z | main.rs:793:9:797:9 | match x { ... } | | -| main.rs:796:13:796:13 | _ | main.rs:796:18:796:18 | 0 | match | -| main.rs:796:18:796:18 | 0 | main.rs:793:9:797:9 | match x { ... } | | -| main.rs:801:1:845:1 | enter fn main | main.rs:802:5:802:25 | ExprStmt | | -| main.rs:801:1:845:1 | exit fn main (normal) | main.rs:801:1:845:1 | exit fn main | | -| main.rs:801:11:845:1 | { ... } | main.rs:801:1:845:1 | exit fn main (normal) | | -| main.rs:802:5:802:22 | immutable_variable | main.rs:802:5:802:24 | immutable_variable(...) | | -| main.rs:802:5:802:24 | immutable_variable(...) | main.rs:803:5:803:23 | ExprStmt | | -| main.rs:802:5:802:25 | ExprStmt | main.rs:802:5:802:22 | immutable_variable | | -| main.rs:803:5:803:20 | mutable_variable | main.rs:803:5:803:22 | mutable_variable(...) | | -| main.rs:803:5:803:22 | mutable_variable(...) | main.rs:804:5:804:40 | ExprStmt | | -| main.rs:803:5:803:23 | ExprStmt | main.rs:803:5:803:20 | mutable_variable | | -| main.rs:804:5:804:37 | mutable_variable_immutable_borrow | main.rs:804:5:804:39 | mutable_variable_immutable_borrow(...) | | -| main.rs:804:5:804:39 | mutable_variable_immutable_borrow(...) | main.rs:805:5:805:23 | ExprStmt | | -| main.rs:804:5:804:40 | ExprStmt | main.rs:804:5:804:37 | mutable_variable_immutable_borrow | | -| main.rs:805:5:805:20 | variable_shadow1 | main.rs:805:5:805:22 | variable_shadow1(...) | | -| main.rs:805:5:805:22 | variable_shadow1(...) | main.rs:806:5:806:23 | ExprStmt | | -| main.rs:805:5:805:23 | ExprStmt | main.rs:805:5:805:20 | variable_shadow1 | | -| main.rs:806:5:806:20 | variable_shadow2 | main.rs:806:5:806:22 | variable_shadow2(...) | | -| main.rs:806:5:806:22 | variable_shadow2(...) | main.rs:807:5:807:19 | ExprStmt | | -| main.rs:806:5:806:23 | ExprStmt | main.rs:806:5:806:20 | variable_shadow2 | | -| main.rs:807:5:807:16 | let_pattern1 | main.rs:807:5:807:18 | let_pattern1(...) | | -| main.rs:807:5:807:18 | let_pattern1(...) | main.rs:808:5:808:19 | ExprStmt | | -| main.rs:807:5:807:19 | ExprStmt | main.rs:807:5:807:16 | let_pattern1 | | -| main.rs:808:5:808:16 | let_pattern2 | main.rs:808:5:808:18 | let_pattern2(...) | | -| main.rs:808:5:808:18 | let_pattern2(...) | main.rs:809:5:809:19 | ExprStmt | | -| main.rs:808:5:808:19 | ExprStmt | main.rs:808:5:808:16 | let_pattern2 | | -| main.rs:809:5:809:16 | let_pattern3 | main.rs:809:5:809:18 | let_pattern3(...) | | -| main.rs:809:5:809:18 | let_pattern3(...) | main.rs:810:5:810:19 | ExprStmt | | -| main.rs:809:5:809:19 | ExprStmt | main.rs:809:5:809:16 | let_pattern3 | | -| main.rs:810:5:810:16 | let_pattern4 | main.rs:810:5:810:18 | let_pattern4(...) | | -| main.rs:810:5:810:18 | let_pattern4(...) | main.rs:811:5:811:21 | ExprStmt | | -| main.rs:810:5:810:19 | ExprStmt | main.rs:810:5:810:16 | let_pattern4 | | -| main.rs:811:5:811:18 | match_pattern1 | main.rs:811:5:811:20 | match_pattern1(...) | | -| main.rs:811:5:811:20 | match_pattern1(...) | main.rs:812:5:812:21 | ExprStmt | | -| main.rs:811:5:811:21 | ExprStmt | main.rs:811:5:811:18 | match_pattern1 | | -| main.rs:812:5:812:18 | match_pattern2 | main.rs:812:5:812:20 | match_pattern2(...) | | -| main.rs:812:5:812:20 | match_pattern2(...) | main.rs:813:5:813:21 | ExprStmt | | -| main.rs:812:5:812:21 | ExprStmt | main.rs:812:5:812:18 | match_pattern2 | | -| main.rs:813:5:813:18 | match_pattern3 | main.rs:813:5:813:20 | match_pattern3(...) | | -| main.rs:813:5:813:20 | match_pattern3(...) | main.rs:814:5:814:21 | ExprStmt | | -| main.rs:813:5:813:21 | ExprStmt | main.rs:813:5:813:18 | match_pattern3 | | -| main.rs:814:5:814:18 | match_pattern4 | main.rs:814:5:814:20 | match_pattern4(...) | | -| main.rs:814:5:814:20 | match_pattern4(...) | main.rs:815:5:815:21 | ExprStmt | | -| main.rs:814:5:814:21 | ExprStmt | main.rs:814:5:814:18 | match_pattern4 | | -| main.rs:815:5:815:18 | match_pattern5 | main.rs:815:5:815:20 | match_pattern5(...) | | -| main.rs:815:5:815:20 | match_pattern5(...) | main.rs:816:5:816:21 | ExprStmt | | -| main.rs:815:5:815:21 | ExprStmt | main.rs:815:5:815:18 | match_pattern5 | | -| main.rs:816:5:816:18 | match_pattern6 | main.rs:816:5:816:20 | match_pattern6(...) | | -| main.rs:816:5:816:20 | match_pattern6(...) | main.rs:817:5:817:21 | ExprStmt | | -| main.rs:816:5:816:21 | ExprStmt | main.rs:816:5:816:18 | match_pattern6 | | -| main.rs:817:5:817:18 | match_pattern7 | main.rs:817:5:817:20 | match_pattern7(...) | | -| main.rs:817:5:817:20 | match_pattern7(...) | main.rs:818:5:818:21 | ExprStmt | | -| main.rs:817:5:817:21 | ExprStmt | main.rs:817:5:817:18 | match_pattern7 | | -| main.rs:818:5:818:18 | match_pattern8 | main.rs:818:5:818:20 | match_pattern8(...) | | -| main.rs:818:5:818:20 | match_pattern8(...) | main.rs:819:5:819:21 | ExprStmt | | -| main.rs:818:5:818:21 | ExprStmt | main.rs:818:5:818:18 | match_pattern8 | | -| main.rs:819:5:819:18 | match_pattern9 | main.rs:819:5:819:20 | match_pattern9(...) | | -| main.rs:819:5:819:20 | match_pattern9(...) | main.rs:820:5:820:22 | ExprStmt | | -| main.rs:819:5:819:21 | ExprStmt | main.rs:819:5:819:18 | match_pattern9 | | -| main.rs:820:5:820:19 | match_pattern10 | main.rs:820:5:820:21 | match_pattern10(...) | | -| main.rs:820:5:820:21 | match_pattern10(...) | main.rs:821:5:821:22 | ExprStmt | | -| main.rs:820:5:820:22 | ExprStmt | main.rs:820:5:820:19 | match_pattern10 | | -| main.rs:821:5:821:19 | match_pattern11 | main.rs:821:5:821:21 | match_pattern11(...) | | -| main.rs:821:5:821:21 | match_pattern11(...) | main.rs:822:5:822:22 | ExprStmt | | -| main.rs:821:5:821:22 | ExprStmt | main.rs:821:5:821:19 | match_pattern11 | | -| main.rs:822:5:822:19 | match_pattern12 | main.rs:822:5:822:21 | match_pattern12(...) | | -| main.rs:822:5:822:21 | match_pattern12(...) | main.rs:823:5:823:22 | ExprStmt | | -| main.rs:822:5:822:22 | ExprStmt | main.rs:822:5:822:19 | match_pattern12 | | -| main.rs:823:5:823:19 | match_pattern13 | main.rs:823:5:823:21 | match_pattern13(...) | | -| main.rs:823:5:823:21 | match_pattern13(...) | main.rs:824:5:824:22 | ExprStmt | | -| main.rs:823:5:823:22 | ExprStmt | main.rs:823:5:823:19 | match_pattern13 | | -| main.rs:824:5:824:19 | match_pattern14 | main.rs:824:5:824:21 | match_pattern14(...) | | -| main.rs:824:5:824:21 | match_pattern14(...) | main.rs:825:5:825:22 | ExprStmt | | -| main.rs:824:5:824:22 | ExprStmt | main.rs:824:5:824:19 | match_pattern14 | | -| main.rs:825:5:825:19 | match_pattern15 | main.rs:825:5:825:21 | match_pattern15(...) | | -| main.rs:825:5:825:21 | match_pattern15(...) | main.rs:826:5:826:22 | ExprStmt | | -| main.rs:825:5:825:22 | ExprStmt | main.rs:825:5:825:19 | match_pattern15 | | -| main.rs:826:5:826:19 | match_pattern16 | main.rs:826:5:826:21 | match_pattern16(...) | | -| main.rs:826:5:826:21 | match_pattern16(...) | main.rs:827:5:827:36 | ExprStmt | | -| main.rs:826:5:826:22 | ExprStmt | main.rs:826:5:826:19 | match_pattern16 | | -| main.rs:827:5:827:18 | param_pattern1 | main.rs:827:20:827:22 | "a" | | -| main.rs:827:5:827:35 | param_pattern1(...) | main.rs:828:5:828:37 | ExprStmt | | -| main.rs:827:5:827:36 | ExprStmt | main.rs:827:5:827:18 | param_pattern1 | | -| main.rs:827:20:827:22 | "a" | main.rs:827:26:827:28 | "b" | | -| main.rs:827:25:827:34 | TupleExpr | main.rs:827:5:827:35 | param_pattern1(...) | | -| main.rs:827:26:827:28 | "b" | main.rs:827:31:827:33 | "c" | | -| main.rs:827:31:827:33 | "c" | main.rs:827:25:827:34 | TupleExpr | | -| main.rs:828:5:828:18 | param_pattern2 | main.rs:828:20:828:31 | ...::Left | | -| main.rs:828:5:828:36 | param_pattern2(...) | main.rs:829:5:829:26 | ExprStmt | | -| main.rs:828:5:828:37 | ExprStmt | main.rs:828:5:828:18 | param_pattern2 | | -| main.rs:828:20:828:31 | ...::Left | main.rs:828:33:828:34 | 45 | | -| main.rs:828:20:828:35 | ...::Left(...) | main.rs:828:5:828:36 | param_pattern2(...) | | -| main.rs:828:33:828:34 | 45 | main.rs:828:20:828:35 | ...::Left(...) | | -| main.rs:829:5:829:23 | destruct_assignment | main.rs:829:5:829:25 | destruct_assignment(...) | | -| main.rs:829:5:829:25 | destruct_assignment(...) | main.rs:830:5:830:23 | ExprStmt | | -| main.rs:829:5:829:26 | ExprStmt | main.rs:829:5:829:23 | destruct_assignment | | -| main.rs:830:5:830:20 | closure_variable | main.rs:830:5:830:22 | closure_variable(...) | | -| main.rs:830:5:830:22 | closure_variable(...) | main.rs:831:5:831:22 | ExprStmt | | -| main.rs:830:5:830:23 | ExprStmt | main.rs:830:5:830:20 | closure_variable | | -| main.rs:831:5:831:19 | nested_function | main.rs:831:5:831:21 | nested_function(...) | | -| main.rs:831:5:831:21 | nested_function(...) | main.rs:832:5:832:19 | ExprStmt | | -| main.rs:831:5:831:22 | ExprStmt | main.rs:831:5:831:19 | nested_function | | -| main.rs:832:5:832:16 | for_variable | main.rs:832:5:832:18 | for_variable(...) | | -| main.rs:832:5:832:18 | for_variable(...) | main.rs:833:5:833:17 | ExprStmt | | -| main.rs:832:5:832:19 | ExprStmt | main.rs:832:5:832:16 | for_variable | | -| main.rs:833:5:833:14 | add_assign | main.rs:833:5:833:16 | add_assign(...) | | -| main.rs:833:5:833:16 | add_assign(...) | main.rs:834:5:834:13 | ExprStmt | | -| main.rs:833:5:833:17 | ExprStmt | main.rs:833:5:833:14 | add_assign | | -| main.rs:834:5:834:10 | mutate | main.rs:834:5:834:12 | mutate(...) | | -| main.rs:834:5:834:12 | mutate(...) | main.rs:835:5:835:17 | ExprStmt | | -| main.rs:834:5:834:13 | ExprStmt | main.rs:834:5:834:10 | mutate | | -| main.rs:835:5:835:14 | mutate_arg | main.rs:835:5:835:16 | mutate_arg(...) | | -| main.rs:835:5:835:16 | mutate_arg(...) | main.rs:836:5:836:12 | ExprStmt | | -| main.rs:835:5:835:17 | ExprStmt | main.rs:835:5:835:14 | mutate_arg | | -| main.rs:836:5:836:9 | alias | main.rs:836:5:836:11 | alias(...) | | -| main.rs:836:5:836:11 | alias(...) | main.rs:837:5:837:18 | ExprStmt | | -| main.rs:836:5:836:12 | ExprStmt | main.rs:836:5:836:9 | alias | | -| main.rs:837:5:837:15 | capture_mut | main.rs:837:5:837:17 | capture_mut(...) | | -| main.rs:837:5:837:17 | capture_mut(...) | main.rs:838:5:838:20 | ExprStmt | | -| main.rs:837:5:837:18 | ExprStmt | main.rs:837:5:837:15 | capture_mut | | -| main.rs:838:5:838:17 | capture_immut | main.rs:838:5:838:19 | capture_immut(...) | | -| main.rs:838:5:838:19 | capture_immut(...) | main.rs:839:5:839:26 | ExprStmt | | -| main.rs:838:5:838:20 | ExprStmt | main.rs:838:5:838:17 | capture_immut | | -| main.rs:839:5:839:23 | async_block_capture | main.rs:839:5:839:25 | async_block_capture(...) | | -| main.rs:839:5:839:25 | async_block_capture(...) | main.rs:840:5:840:14 | ExprStmt | | -| main.rs:839:5:839:26 | ExprStmt | main.rs:839:5:839:23 | async_block_capture | | -| main.rs:840:5:840:11 | structs | main.rs:840:5:840:13 | structs(...) | | -| main.rs:840:5:840:13 | structs(...) | main.rs:841:5:841:14 | ExprStmt | | -| main.rs:840:5:840:14 | ExprStmt | main.rs:840:5:840:11 | structs | | -| main.rs:841:5:841:11 | ref_arg | main.rs:841:5:841:13 | ref_arg(...) | | -| main.rs:841:5:841:13 | ref_arg(...) | main.rs:842:5:842:30 | ExprStmt | | -| main.rs:841:5:841:14 | ExprStmt | main.rs:841:5:841:11 | ref_arg | | -| main.rs:842:5:842:27 | ref_methodcall_receiver | main.rs:842:5:842:29 | ref_methodcall_receiver(...) | | -| main.rs:842:5:842:29 | ref_methodcall_receiver(...) | main.rs:843:5:843:23 | ExprStmt | | -| main.rs:842:5:842:30 | ExprStmt | main.rs:842:5:842:27 | ref_methodcall_receiver | | -| main.rs:843:5:843:20 | macro_invocation | main.rs:843:5:843:22 | macro_invocation(...) | | -| main.rs:843:5:843:22 | macro_invocation(...) | main.rs:844:5:844:18 | ExprStmt | | -| main.rs:843:5:843:23 | ExprStmt | main.rs:843:5:843:20 | macro_invocation | | -| main.rs:844:5:844:15 | capture_phi | main.rs:844:5:844:17 | capture_phi(...) | | -| main.rs:844:5:844:17 | capture_phi(...) | main.rs:801:11:845:1 | { ... } | | -| main.rs:844:5:844:18 | ExprStmt | main.rs:844:5:844:15 | capture_phi | | +| main.rs:708:5:708:25 | print_i64(...) | main.rs:702:14:709:1 | { ... } | | +| main.rs:708:5:708:26 | ExprStmt | main.rs:708:5:708:13 | print_i64 | | +| main.rs:708:15:708:15 | a | main.rs:708:15:708:24 | a.my_get() | | +| main.rs:708:15:708:24 | a.my_get() | main.rs:708:5:708:25 | print_i64(...) | | +| main.rs:711:1:718:1 | enter fn arrays | main.rs:712:5:712:26 | let ... = ... | | +| main.rs:711:1:718:1 | exit fn arrays (normal) | main.rs:711:1:718:1 | exit fn arrays | | +| main.rs:711:13:718:1 | { ... } | main.rs:711:1:718:1 | exit fn arrays (normal) | | +| main.rs:712:5:712:26 | let ... = ... | main.rs:712:18:712:18 | 1 | | +| main.rs:712:9:712:13 | mut a | main.rs:713:5:713:20 | ExprStmt | match | +| main.rs:712:13:712:13 | a | main.rs:712:9:712:13 | mut a | | +| main.rs:712:17:712:25 | [...] | main.rs:712:13:712:13 | a | | +| main.rs:712:18:712:18 | 1 | main.rs:712:21:712:21 | 2 | | +| main.rs:712:21:712:21 | 2 | main.rs:712:24:712:24 | 3 | | +| main.rs:712:24:712:24 | 3 | main.rs:712:17:712:25 | [...] | | +| main.rs:713:5:713:13 | print_i64 | main.rs:713:15:713:15 | a | | +| main.rs:713:5:713:19 | print_i64(...) | main.rs:714:5:714:13 | ExprStmt | | +| main.rs:713:5:713:20 | ExprStmt | main.rs:713:5:713:13 | print_i64 | | +| main.rs:713:15:713:15 | a | main.rs:713:17:713:17 | 0 | | +| main.rs:713:15:713:18 | a[0] | main.rs:713:5:713:19 | print_i64(...) | | +| main.rs:713:17:713:17 | 0 | main.rs:713:15:713:18 | a[0] | | +| main.rs:714:5:714:5 | a | main.rs:714:7:714:7 | 1 | | +| main.rs:714:5:714:8 | a[1] | main.rs:714:12:714:12 | 5 | | +| main.rs:714:5:714:12 | ... = ... | main.rs:715:5:715:20 | ExprStmt | | +| main.rs:714:5:714:13 | ExprStmt | main.rs:714:5:714:5 | a | | +| main.rs:714:7:714:7 | 1 | main.rs:714:5:714:8 | a[1] | | +| main.rs:714:12:714:12 | 5 | main.rs:714:5:714:12 | ... = ... | | +| main.rs:715:5:715:13 | print_i64 | main.rs:715:15:715:15 | a | | +| main.rs:715:5:715:19 | print_i64(...) | main.rs:716:5:716:18 | ExprStmt | | +| main.rs:715:5:715:20 | ExprStmt | main.rs:715:5:715:13 | print_i64 | | +| main.rs:715:15:715:15 | a | main.rs:715:17:715:17 | 1 | | +| main.rs:715:15:715:18 | a[1] | main.rs:715:5:715:19 | print_i64(...) | | +| main.rs:715:17:715:17 | 1 | main.rs:715:15:715:18 | a[1] | | +| main.rs:716:5:716:5 | a | main.rs:716:10:716:10 | 4 | | +| main.rs:716:5:716:17 | ... = ... | main.rs:717:5:717:20 | ExprStmt | | +| main.rs:716:5:716:18 | ExprStmt | main.rs:716:5:716:5 | a | | +| main.rs:716:9:716:17 | [...] | main.rs:716:5:716:17 | ... = ... | | +| main.rs:716:10:716:10 | 4 | main.rs:716:13:716:13 | 5 | | +| main.rs:716:13:716:13 | 5 | main.rs:716:16:716:16 | 6 | | +| main.rs:716:16:716:16 | 6 | main.rs:716:9:716:17 | [...] | | +| main.rs:717:5:717:13 | print_i64 | main.rs:717:15:717:15 | a | | +| main.rs:717:5:717:19 | print_i64(...) | main.rs:711:13:718:1 | { ... } | | +| main.rs:717:5:717:20 | ExprStmt | main.rs:717:5:717:13 | print_i64 | | +| main.rs:717:15:717:15 | a | main.rs:717:17:717:17 | 2 | | +| main.rs:717:15:717:18 | a[2] | main.rs:717:5:717:19 | print_i64(...) | | +| main.rs:717:17:717:17 | 2 | main.rs:717:15:717:18 | a[2] | | +| main.rs:720:1:727:1 | enter fn ref_arg | main.rs:721:5:721:15 | let ... = 16 | | +| main.rs:720:1:727:1 | exit fn ref_arg (normal) | main.rs:720:1:727:1 | exit fn ref_arg | | +| main.rs:720:14:727:1 | { ... } | main.rs:720:1:727:1 | exit fn ref_arg (normal) | | +| main.rs:721:5:721:15 | let ... = 16 | main.rs:721:13:721:14 | 16 | | +| main.rs:721:9:721:9 | x | main.rs:721:9:721:9 | x | | +| main.rs:721:9:721:9 | x | main.rs:722:5:722:22 | ExprStmt | match | +| main.rs:721:13:721:14 | 16 | main.rs:721:9:721:9 | x | | +| main.rs:722:5:722:17 | print_i64_ref | main.rs:722:20:722:20 | x | | +| main.rs:722:5:722:21 | print_i64_ref(...) | main.rs:723:5:723:17 | ExprStmt | | +| main.rs:722:5:722:22 | ExprStmt | main.rs:722:5:722:17 | print_i64_ref | | +| main.rs:722:19:722:20 | &x | main.rs:722:5:722:21 | print_i64_ref(...) | | +| main.rs:722:20:722:20 | x | main.rs:722:19:722:20 | &x | | +| main.rs:723:5:723:13 | print_i64 | main.rs:723:15:723:15 | x | | +| main.rs:723:5:723:16 | print_i64(...) | main.rs:725:5:725:15 | let ... = 17 | | +| main.rs:723:5:723:17 | ExprStmt | main.rs:723:5:723:13 | print_i64 | | +| main.rs:723:15:723:15 | x | main.rs:723:5:723:16 | print_i64(...) | | +| main.rs:725:5:725:15 | let ... = 17 | main.rs:725:13:725:14 | 17 | | +| main.rs:725:9:725:9 | z | main.rs:725:9:725:9 | z | | +| main.rs:725:9:725:9 | z | main.rs:726:5:726:22 | ExprStmt | match | +| main.rs:725:13:725:14 | 17 | main.rs:725:9:725:9 | z | | +| main.rs:726:5:726:17 | print_i64_ref | main.rs:726:20:726:20 | z | | +| main.rs:726:5:726:21 | print_i64_ref(...) | main.rs:720:14:727:1 | { ... } | | +| main.rs:726:5:726:22 | ExprStmt | main.rs:726:5:726:17 | print_i64_ref | | +| main.rs:726:19:726:20 | &z | main.rs:726:5:726:21 | print_i64_ref(...) | | +| main.rs:726:20:726:20 | z | main.rs:726:19:726:20 | &z | | +| main.rs:734:5:736:5 | enter fn bar | main.rs:734:17:734:20 | self | | +| main.rs:734:5:736:5 | exit fn bar (normal) | main.rs:734:5:736:5 | exit fn bar | | +| main.rs:734:12:734:20 | SelfParam | main.rs:735:9:735:36 | ExprStmt | | +| main.rs:734:17:734:20 | self | main.rs:734:12:734:20 | SelfParam | | +| main.rs:734:23:736:5 | { ... } | main.rs:734:5:736:5 | exit fn bar (normal) | | +| main.rs:735:9:735:13 | * ... | main.rs:735:33:735:33 | 3 | | +| main.rs:735:9:735:35 | ... = ... | main.rs:734:23:736:5 | { ... } | | +| main.rs:735:9:735:36 | ExprStmt | main.rs:735:10:735:13 | self | | +| main.rs:735:10:735:13 | self | main.rs:735:9:735:13 | * ... | | +| main.rs:735:17:735:35 | MyStruct {...} | main.rs:735:9:735:35 | ... = ... | | +| main.rs:735:33:735:33 | 3 | main.rs:735:17:735:35 | MyStruct {...} | | +| main.rs:739:1:745:1 | enter fn ref_methodcall_receiver | main.rs:740:5:740:36 | let ... = ... | | +| main.rs:739:1:745:1 | exit fn ref_methodcall_receiver (normal) | main.rs:739:1:745:1 | exit fn ref_methodcall_receiver | | +| main.rs:739:30:745:1 | { ... } | main.rs:739:1:745:1 | exit fn ref_methodcall_receiver (normal) | | +| main.rs:740:5:740:36 | let ... = ... | main.rs:740:33:740:33 | 1 | | +| main.rs:740:9:740:13 | mut a | main.rs:741:5:741:12 | ExprStmt | match | +| main.rs:740:13:740:13 | a | main.rs:740:9:740:13 | mut a | | +| main.rs:740:17:740:35 | MyStruct {...} | main.rs:740:13:740:13 | a | | +| main.rs:740:33:740:33 | 1 | main.rs:740:17:740:35 | MyStruct {...} | | +| main.rs:741:5:741:5 | a | main.rs:741:5:741:11 | a.bar() | | +| main.rs:741:5:741:11 | a.bar() | main.rs:744:5:744:21 | ExprStmt | | +| main.rs:741:5:741:12 | ExprStmt | main.rs:741:5:741:5 | a | | +| main.rs:744:5:744:13 | print_i64 | main.rs:744:15:744:15 | a | | +| main.rs:744:5:744:20 | print_i64(...) | main.rs:739:30:745:1 | { ... } | | +| main.rs:744:5:744:21 | ExprStmt | main.rs:744:5:744:13 | print_i64 | | +| main.rs:744:15:744:15 | a | main.rs:744:15:744:19 | a.val | | +| main.rs:744:15:744:19 | a.val | main.rs:744:5:744:20 | print_i64(...) | | +| main.rs:761:1:772:1 | enter fn macro_invocation | main.rs:762:5:763:26 | let ... = ... | | +| main.rs:761:1:772:1 | exit fn macro_invocation (normal) | main.rs:761:1:772:1 | exit fn macro_invocation | | +| main.rs:761:23:772:1 | { ... } | main.rs:761:1:772:1 | exit fn macro_invocation (normal) | | +| main.rs:762:5:763:26 | let ... = ... | main.rs:763:23:763:24 | let ... = 37 | | +| main.rs:762:9:762:22 | var_from_macro | main.rs:762:9:762:22 | var_from_macro | | +| main.rs:762:9:762:22 | var_from_macro | main.rs:764:5:764:30 | ExprStmt | match | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:9:763:21 | var_in_macro | | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:9:763:21 | var_in_macro | match | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:23:763:24 | { ... } | | +| main.rs:763:9:763:25 | MacroExpr | main.rs:762:9:762:22 | var_from_macro | | +| main.rs:763:9:763:25 | let_in_macro!... | main.rs:763:9:763:25 | MacroExpr | | +| main.rs:763:23:763:24 | 37 | main.rs:763:9:763:21 | var_in_macro | | +| main.rs:763:23:763:24 | let ... = 37 | main.rs:763:23:763:24 | 37 | | +| main.rs:763:23:763:24 | { ... } | main.rs:763:9:763:25 | let_in_macro!... | | +| main.rs:764:5:764:13 | print_i64 | main.rs:764:15:764:28 | var_from_macro | | +| main.rs:764:5:764:29 | print_i64(...) | main.rs:765:5:765:26 | let ... = 33 | | +| main.rs:764:5:764:30 | ExprStmt | main.rs:764:5:764:13 | print_i64 | | +| main.rs:764:15:764:28 | var_from_macro | main.rs:764:5:764:29 | print_i64(...) | | +| main.rs:765:5:765:26 | let ... = 33 | main.rs:765:24:765:25 | 33 | | +| main.rs:765:9:765:20 | var_in_macro | main.rs:765:9:765:20 | var_in_macro | | +| main.rs:765:9:765:20 | var_in_macro | main.rs:770:5:770:44 | ExprStmt | match | +| main.rs:765:24:765:25 | 33 | main.rs:765:9:765:20 | var_in_macro | | +| main.rs:770:5:770:13 | print_i64 | main.rs:770:15:770:28 | let ... = 0 | | +| main.rs:770:5:770:43 | print_i64(...) | main.rs:771:5:771:28 | ExprStmt | | +| main.rs:770:5:770:44 | ExprStmt | main.rs:770:5:770:13 | print_i64 | | +| main.rs:770:15:770:28 | 0 | main.rs:770:15:770:28 | var_in_macro | | +| main.rs:770:15:770:28 | let ... = 0 | main.rs:770:15:770:28 | 0 | | +| main.rs:770:15:770:28 | var_in_macro | main.rs:770:15:770:28 | var_in_macro | | +| main.rs:770:15:770:28 | var_in_macro | main.rs:770:30:770:41 | var_in_macro | match | +| main.rs:770:15:770:42 | MacroExpr | main.rs:770:5:770:43 | print_i64(...) | | +| main.rs:770:15:770:42 | let_in_macro2!... | main.rs:770:15:770:42 | MacroExpr | | +| main.rs:770:30:770:41 | var_in_macro | main.rs:770:30:770:41 | { ... } | | +| main.rs:770:30:770:41 | { ... } | main.rs:770:15:770:42 | let_in_macro2!... | | +| main.rs:771:5:771:13 | print_i64 | main.rs:771:15:771:26 | var_in_macro | | +| main.rs:771:5:771:27 | print_i64(...) | main.rs:761:23:772:1 | { ... } | | +| main.rs:771:5:771:28 | ExprStmt | main.rs:771:5:771:13 | print_i64 | | +| main.rs:771:15:771:26 | var_in_macro | main.rs:771:5:771:27 | print_i64(...) | | +| main.rs:774:1:778:1 | enter fn let_without_initializer | main.rs:775:5:775:10 | let ... | | +| main.rs:774:1:778:1 | exit fn let_without_initializer (normal) | main.rs:774:1:778:1 | exit fn let_without_initializer | | +| main.rs:774:30:778:1 | { ... } | main.rs:774:1:778:1 | exit fn let_without_initializer (normal) | | +| main.rs:775:5:775:10 | let ... | main.rs:775:9:775:9 | x | | +| main.rs:775:9:775:9 | x | main.rs:775:9:775:9 | x | | +| main.rs:775:9:775:9 | x | main.rs:776:5:776:10 | ExprStmt | match | +| main.rs:776:5:776:5 | x | main.rs:776:9:776:9 | 1 | | +| main.rs:776:5:776:9 | ... = ... | main.rs:777:5:777:17 | ExprStmt | | +| main.rs:776:5:776:10 | ExprStmt | main.rs:776:5:776:5 | x | | +| main.rs:776:9:776:9 | 1 | main.rs:776:5:776:9 | ... = ... | | +| main.rs:777:5:777:13 | print_i64 | main.rs:777:15:777:15 | x | | +| main.rs:777:5:777:16 | print_i64(...) | main.rs:774:30:778:1 | { ... } | | +| main.rs:777:5:777:17 | ExprStmt | main.rs:777:5:777:13 | print_i64 | | +| main.rs:777:15:777:15 | x | main.rs:777:5:777:16 | print_i64(...) | | +| main.rs:780:1:790:1 | enter fn capture_phi | main.rs:781:5:781:20 | let ... = 100 | | +| main.rs:780:1:790:1 | exit fn capture_phi (normal) | main.rs:780:1:790:1 | exit fn capture_phi | | +| main.rs:780:18:790:1 | { ... } | main.rs:780:1:790:1 | exit fn capture_phi (normal) | | +| main.rs:781:5:781:20 | let ... = 100 | main.rs:781:17:781:19 | 100 | | +| main.rs:781:9:781:13 | mut x | main.rs:782:5:787:6 | let ... = ... | match | +| main.rs:781:13:781:13 | x | main.rs:781:9:781:13 | mut x | | +| main.rs:781:17:781:19 | 100 | main.rs:781:13:781:13 | x | | +| main.rs:782:5:787:6 | let ... = ... | main.rs:782:19:787:5 | \|...\| ... | | +| main.rs:782:9:782:15 | mut cap | main.rs:788:5:788:14 | ExprStmt | match | +| main.rs:782:13:782:15 | cap | main.rs:782:9:782:15 | mut cap | | +| main.rs:782:19:787:5 | \|...\| ... | main.rs:782:13:782:15 | cap | | +| main.rs:782:19:787:5 | enter \|...\| ... | main.rs:782:20:782:20 | b | | +| main.rs:782:19:787:5 | exit \|...\| ... (normal) | main.rs:782:19:787:5 | exit \|...\| ... | | +| main.rs:782:20:782:20 | b | main.rs:782:20:782:20 | b | | +| main.rs:782:20:782:20 | b | main.rs:782:20:782:26 | ...: bool | match | +| main.rs:782:20:782:26 | ...: bool | main.rs:783:9:786:10 | let _ = ... | | +| main.rs:782:29:787:5 | { ... } | main.rs:782:19:787:5 | exit \|...\| ... (normal) | | +| main.rs:783:9:786:10 | let _ = ... | main.rs:784:20:784:20 | b | | +| main.rs:784:13:784:13 | _ | main.rs:782:29:787:5 | { ... } | match | +| main.rs:784:17:786:9 | if b {...} | main.rs:784:13:784:13 | _ | | +| main.rs:784:20:784:20 | b | main.rs:784:17:786:9 | if b {...} | false | +| main.rs:784:20:784:20 | b | main.rs:785:13:785:20 | ExprStmt | true | +| main.rs:784:22:786:9 | { ... } | main.rs:784:17:786:9 | if b {...} | | +| main.rs:785:13:785:13 | x | main.rs:785:17:785:19 | 200 | | +| main.rs:785:13:785:19 | ... = ... | main.rs:784:22:786:9 | { ... } | | +| main.rs:785:13:785:20 | ExprStmt | main.rs:785:13:785:13 | x | | +| main.rs:785:17:785:19 | 200 | main.rs:785:13:785:19 | ... = ... | | +| main.rs:788:5:788:7 | cap | main.rs:788:9:788:12 | true | | +| main.rs:788:5:788:13 | cap(...) | main.rs:789:5:789:17 | ExprStmt | | +| main.rs:788:5:788:14 | ExprStmt | main.rs:788:5:788:7 | cap | | +| main.rs:788:9:788:12 | true | main.rs:788:5:788:13 | cap(...) | | +| main.rs:789:5:789:13 | print_i64 | main.rs:789:15:789:15 | x | | +| main.rs:789:5:789:16 | print_i64(...) | main.rs:780:18:790:1 | { ... } | | +| main.rs:789:5:789:17 | ExprStmt | main.rs:789:5:789:13 | print_i64 | | +| main.rs:789:15:789:15 | x | main.rs:789:5:789:16 | print_i64(...) | | +| main.rs:793:5:808:5 | enter fn test | main.rs:795:9:795:25 | let ... = ... | | +| main.rs:793:5:808:5 | exit fn test (normal) | main.rs:793:5:808:5 | exit fn test | | +| main.rs:794:34:808:5 | { ... } | main.rs:793:5:808:5 | exit fn test (normal) | | +| main.rs:795:9:795:25 | let ... = ... | main.rs:795:17:795:20 | Some | | +| main.rs:795:13:795:13 | x | main.rs:795:13:795:13 | x | | +| main.rs:795:13:795:13 | x | main.rs:796:9:803:10 | let ... = ... | match | +| main.rs:795:17:795:20 | Some | main.rs:795:22:795:23 | 42 | | +| main.rs:795:17:795:24 | Some(...) | main.rs:795:13:795:13 | x | | +| main.rs:795:22:795:23 | 42 | main.rs:795:17:795:24 | Some(...) | | +| main.rs:796:9:803:10 | let ... = ... | main.rs:797:19:797:19 | x | | +| main.rs:796:13:796:13 | y | main.rs:796:13:796:13 | y | | +| main.rs:796:13:796:13 | y | main.rs:804:15:804:15 | y | match | +| main.rs:797:13:803:9 | match x { ... } | main.rs:796:13:796:13 | y | | +| main.rs:797:19:797:19 | x | main.rs:798:13:798:19 | Some(...) | | +| main.rs:798:13:798:19 | Some(...) | main.rs:798:18:798:18 | y | match | +| main.rs:798:13:798:19 | Some(...) | main.rs:801:13:801:16 | None | no-match | +| main.rs:798:18:798:18 | y | main.rs:798:18:798:18 | y | | +| main.rs:798:18:798:18 | y | main.rs:799:17:799:20 | None | match | +| main.rs:798:24:800:13 | { ... } | main.rs:797:13:803:9 | match x { ... } | | +| main.rs:799:17:799:20 | None | main.rs:798:24:800:13 | { ... } | | +| main.rs:801:13:801:16 | None | main.rs:801:13:801:16 | None | | +| main.rs:801:13:801:16 | None | main.rs:802:17:802:20 | None | match | +| main.rs:802:17:802:20 | None | main.rs:797:13:803:9 | match x { ... } | | +| main.rs:804:9:807:9 | match y { ... } | main.rs:794:34:808:5 | { ... } | | +| main.rs:804:15:804:15 | y | main.rs:805:13:805:16 | N0ne | | +| main.rs:805:13:805:16 | N0ne | main.rs:805:13:805:16 | N0ne | | +| main.rs:805:13:805:16 | N0ne | main.rs:806:17:806:20 | N0ne | match | +| main.rs:806:17:806:20 | N0ne | main.rs:804:9:807:9 | match y { ... } | | +| main.rs:810:5:817:5 | enter fn test2 | main.rs:812:9:813:17 | let ... = test | | +| main.rs:810:5:817:5 | exit fn test2 (normal) | main.rs:810:5:817:5 | exit fn test2 | | +| main.rs:811:31:817:5 | { ... } | main.rs:810:5:817:5 | exit fn test2 (normal) | | +| main.rs:812:9:813:17 | let ... = test | main.rs:813:13:813:16 | test | | +| main.rs:812:13:812:22 | test_alias | main.rs:812:13:812:22 | test_alias | | +| main.rs:812:13:812:22 | test_alias | main.rs:814:9:815:25 | let ... = ... | match | +| main.rs:813:13:813:16 | test | main.rs:812:13:812:22 | test_alias | | +| main.rs:814:9:815:25 | let ... = ... | main.rs:815:13:815:22 | test_alias | | +| main.rs:814:13:814:16 | test | main.rs:814:13:814:16 | test | | +| main.rs:814:13:814:16 | test | main.rs:816:9:816:12 | test | match | +| main.rs:815:13:815:22 | test_alias | main.rs:815:13:815:24 | test_alias(...) | | +| main.rs:815:13:815:24 | test_alias(...) | main.rs:814:13:814:16 | test | | +| main.rs:816:9:816:12 | test | main.rs:811:31:817:5 | { ... } | | +| main.rs:821:5:834:5 | enter fn test3 | main.rs:823:9:823:24 | let ... = ... | | +| main.rs:821:5:834:5 | exit fn test3 (normal) | main.rs:821:5:834:5 | exit fn test3 | | +| main.rs:822:16:834:5 | { ... } | main.rs:821:5:834:5 | exit fn test3 (normal) | | +| main.rs:823:9:823:24 | let ... = ... | main.rs:823:17:823:20 | Some | | +| main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | | +| main.rs:823:13:823:13 | x | main.rs:824:9:828:10 | ExprStmt | match | +| main.rs:823:17:823:20 | Some | main.rs:823:22:823:22 | 0 | | +| main.rs:823:17:823:23 | Some(...) | main.rs:823:13:823:13 | x | | +| main.rs:823:22:823:22 | 0 | main.rs:823:17:823:23 | Some(...) | | +| main.rs:824:9:828:9 | match x { ... } | main.rs:829:9:833:10 | ExprStmt | | +| main.rs:824:9:828:10 | ExprStmt | main.rs:824:15:824:15 | x | | +| main.rs:824:15:824:15 | x | main.rs:825:13:825:19 | Some(...) | | +| main.rs:825:13:825:19 | Some(...) | main.rs:825:18:825:18 | x | match | +| main.rs:825:13:825:19 | Some(...) | main.rs:827:13:827:13 | _ | no-match | +| main.rs:825:18:825:18 | x | main.rs:825:18:825:18 | x | | +| main.rs:825:18:825:18 | x | main.rs:826:20:826:20 | x | match | +| main.rs:826:20:826:20 | x | main.rs:824:9:828:9 | match x { ... } | | +| main.rs:827:13:827:13 | _ | main.rs:827:18:827:18 | 0 | match | +| main.rs:827:18:827:18 | 0 | main.rs:824:9:828:9 | match x { ... } | | +| main.rs:829:9:833:9 | match x { ... } | main.rs:822:16:834:5 | { ... } | | +| main.rs:829:9:833:10 | ExprStmt | main.rs:829:15:829:15 | x | | +| main.rs:829:15:829:15 | x | main.rs:830:13:830:19 | Some(...) | | +| main.rs:830:13:830:19 | Some(...) | main.rs:830:18:830:18 | z | match | +| main.rs:830:13:830:19 | Some(...) | main.rs:832:13:832:13 | _ | no-match | +| main.rs:830:18:830:18 | z | main.rs:830:18:830:18 | z | | +| main.rs:830:18:830:18 | z | main.rs:831:17:831:17 | z | match | +| main.rs:830:18:830:18 | z | main.rs:832:13:832:13 | _ | no-match | +| main.rs:831:17:831:17 | z | main.rs:829:9:833:9 | match x { ... } | | +| main.rs:832:13:832:13 | _ | main.rs:832:18:832:18 | 0 | match | +| main.rs:832:18:832:18 | 0 | main.rs:829:9:833:9 | match x { ... } | | +| main.rs:837:1:847:1 | enter fn let_in_block_in_cond | main.rs:838:5:838:14 | let ... = 1 | | +| main.rs:837:1:847:1 | exit fn let_in_block_in_cond (normal) | main.rs:837:1:847:1 | exit fn let_in_block_in_cond | | +| main.rs:837:27:847:1 | { ... } | main.rs:837:1:847:1 | exit fn let_in_block_in_cond (normal) | | +| main.rs:838:5:838:14 | let ... = 1 | main.rs:838:13:838:13 | 1 | | +| main.rs:838:9:838:9 | x | main.rs:838:9:838:9 | x | | +| main.rs:838:9:838:9 | x | main.rs:840:9:840:18 | let ... = 1 | match | +| main.rs:838:13:838:13 | 1 | main.rs:838:9:838:9 | x | | +| main.rs:839:5:846:5 | if ... {...} else {...} | main.rs:837:27:847:1 | { ... } | | +| main.rs:839:8:842:5 | [boolean(false)] { ... } | main.rs:845:9:845:21 | ExprStmt | false | +| main.rs:839:8:842:5 | [boolean(true)] { ... } | main.rs:843:9:843:21 | ExprStmt | true | +| main.rs:840:9:840:18 | let ... = 1 | main.rs:840:17:840:17 | 1 | | +| main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | | +| main.rs:840:13:840:13 | x | main.rs:841:9:841:9 | x | match | +| main.rs:840:17:840:17 | 1 | main.rs:840:13:840:13 | x | | +| main.rs:841:9:841:9 | x | main.rs:841:13:841:13 | 0 | | +| main.rs:841:9:841:13 | ... > ... | main.rs:839:8:842:5 | [boolean(false)] { ... } | false | +| main.rs:841:9:841:13 | ... > ... | main.rs:839:8:842:5 | [boolean(true)] { ... } | true | +| main.rs:841:13:841:13 | 0 | main.rs:841:9:841:13 | ... > ... | | +| main.rs:842:7:844:5 | { ... } | main.rs:839:5:846:5 | if ... {...} else {...} | | +| main.rs:843:9:843:17 | print_i64 | main.rs:843:19:843:19 | x | | +| main.rs:843:9:843:20 | print_i64(...) | main.rs:842:7:844:5 | { ... } | | +| main.rs:843:9:843:21 | ExprStmt | main.rs:843:9:843:17 | print_i64 | | +| main.rs:843:19:843:19 | x | main.rs:843:9:843:20 | print_i64(...) | | +| main.rs:844:12:846:5 | { ... } | main.rs:839:5:846:5 | if ... {...} else {...} | | +| main.rs:845:9:845:17 | print_i64 | main.rs:845:19:845:19 | x | | +| main.rs:845:9:845:20 | print_i64(...) | main.rs:844:12:846:5 | { ... } | | +| main.rs:845:9:845:21 | ExprStmt | main.rs:845:9:845:17 | print_i64 | | +| main.rs:845:19:845:19 | x | main.rs:845:9:845:20 | print_i64(...) | | +| main.rs:849:1:896:1 | enter fn main | main.rs:850:5:850:25 | ExprStmt | | +| main.rs:849:1:896:1 | exit fn main (normal) | main.rs:849:1:896:1 | exit fn main | | +| main.rs:849:11:896:1 | { ... } | main.rs:849:1:896:1 | exit fn main (normal) | | +| main.rs:850:5:850:22 | immutable_variable | main.rs:850:5:850:24 | immutable_variable(...) | | +| main.rs:850:5:850:24 | immutable_variable(...) | main.rs:851:5:851:23 | ExprStmt | | +| main.rs:850:5:850:25 | ExprStmt | main.rs:850:5:850:22 | immutable_variable | | +| main.rs:851:5:851:20 | mutable_variable | main.rs:851:5:851:22 | mutable_variable(...) | | +| main.rs:851:5:851:22 | mutable_variable(...) | main.rs:852:5:852:40 | ExprStmt | | +| main.rs:851:5:851:23 | ExprStmt | main.rs:851:5:851:20 | mutable_variable | | +| main.rs:852:5:852:37 | mutable_variable_immutable_borrow | main.rs:852:5:852:39 | mutable_variable_immutable_borrow(...) | | +| main.rs:852:5:852:39 | mutable_variable_immutable_borrow(...) | main.rs:853:5:853:23 | ExprStmt | | +| main.rs:852:5:852:40 | ExprStmt | main.rs:852:5:852:37 | mutable_variable_immutable_borrow | | +| main.rs:853:5:853:20 | variable_shadow1 | main.rs:853:5:853:22 | variable_shadow1(...) | | +| main.rs:853:5:853:22 | variable_shadow1(...) | main.rs:854:5:854:23 | ExprStmt | | +| main.rs:853:5:853:23 | ExprStmt | main.rs:853:5:853:20 | variable_shadow1 | | +| main.rs:854:5:854:20 | variable_shadow2 | main.rs:854:5:854:22 | variable_shadow2(...) | | +| main.rs:854:5:854:22 | variable_shadow2(...) | main.rs:855:5:855:19 | ExprStmt | | +| main.rs:854:5:854:23 | ExprStmt | main.rs:854:5:854:20 | variable_shadow2 | | +| main.rs:855:5:855:16 | let_pattern1 | main.rs:855:5:855:18 | let_pattern1(...) | | +| main.rs:855:5:855:18 | let_pattern1(...) | main.rs:856:5:856:19 | ExprStmt | | +| main.rs:855:5:855:19 | ExprStmt | main.rs:855:5:855:16 | let_pattern1 | | +| main.rs:856:5:856:16 | let_pattern2 | main.rs:856:5:856:18 | let_pattern2(...) | | +| main.rs:856:5:856:18 | let_pattern2(...) | main.rs:857:5:857:19 | ExprStmt | | +| main.rs:856:5:856:19 | ExprStmt | main.rs:856:5:856:16 | let_pattern2 | | +| main.rs:857:5:857:16 | let_pattern3 | main.rs:857:5:857:18 | let_pattern3(...) | | +| main.rs:857:5:857:18 | let_pattern3(...) | main.rs:858:5:858:19 | ExprStmt | | +| main.rs:857:5:857:19 | ExprStmt | main.rs:857:5:857:16 | let_pattern3 | | +| main.rs:858:5:858:16 | let_pattern4 | main.rs:858:5:858:18 | let_pattern4(...) | | +| main.rs:858:5:858:18 | let_pattern4(...) | main.rs:859:5:859:19 | ExprStmt | | +| main.rs:858:5:858:19 | ExprStmt | main.rs:858:5:858:16 | let_pattern4 | | +| main.rs:859:5:859:16 | let_pattern5 | main.rs:859:5:859:18 | let_pattern5(...) | | +| main.rs:859:5:859:18 | let_pattern5(...) | main.rs:860:5:860:19 | ExprStmt | | +| main.rs:859:5:859:19 | ExprStmt | main.rs:859:5:859:16 | let_pattern5 | | +| main.rs:860:5:860:16 | let_pattern6 | main.rs:860:5:860:18 | let_pattern6(...) | | +| main.rs:860:5:860:18 | let_pattern6(...) | main.rs:861:5:861:21 | ExprStmt | | +| main.rs:860:5:860:19 | ExprStmt | main.rs:860:5:860:16 | let_pattern6 | | +| main.rs:861:5:861:18 | match_pattern1 | main.rs:861:5:861:20 | match_pattern1(...) | | +| main.rs:861:5:861:20 | match_pattern1(...) | main.rs:862:5:862:21 | ExprStmt | | +| main.rs:861:5:861:21 | ExprStmt | main.rs:861:5:861:18 | match_pattern1 | | +| main.rs:862:5:862:18 | match_pattern2 | main.rs:862:5:862:20 | match_pattern2(...) | | +| main.rs:862:5:862:20 | match_pattern2(...) | main.rs:863:5:863:21 | ExprStmt | | +| main.rs:862:5:862:21 | ExprStmt | main.rs:862:5:862:18 | match_pattern2 | | +| main.rs:863:5:863:18 | match_pattern3 | main.rs:863:5:863:20 | match_pattern3(...) | | +| main.rs:863:5:863:20 | match_pattern3(...) | main.rs:864:5:864:21 | ExprStmt | | +| main.rs:863:5:863:21 | ExprStmt | main.rs:863:5:863:18 | match_pattern3 | | +| main.rs:864:5:864:18 | match_pattern4 | main.rs:864:5:864:20 | match_pattern4(...) | | +| main.rs:864:5:864:20 | match_pattern4(...) | main.rs:865:5:865:21 | ExprStmt | | +| main.rs:864:5:864:21 | ExprStmt | main.rs:864:5:864:18 | match_pattern4 | | +| main.rs:865:5:865:18 | match_pattern5 | main.rs:865:5:865:20 | match_pattern5(...) | | +| main.rs:865:5:865:20 | match_pattern5(...) | main.rs:866:5:866:21 | ExprStmt | | +| main.rs:865:5:865:21 | ExprStmt | main.rs:865:5:865:18 | match_pattern5 | | +| main.rs:866:5:866:18 | match_pattern6 | main.rs:866:5:866:20 | match_pattern6(...) | | +| main.rs:866:5:866:20 | match_pattern6(...) | main.rs:867:5:867:21 | ExprStmt | | +| main.rs:866:5:866:21 | ExprStmt | main.rs:866:5:866:18 | match_pattern6 | | +| main.rs:867:5:867:18 | match_pattern7 | main.rs:867:5:867:20 | match_pattern7(...) | | +| main.rs:867:5:867:20 | match_pattern7(...) | main.rs:868:5:868:21 | ExprStmt | | +| main.rs:867:5:867:21 | ExprStmt | main.rs:867:5:867:18 | match_pattern7 | | +| main.rs:868:5:868:18 | match_pattern8 | main.rs:868:5:868:20 | match_pattern8(...) | | +| main.rs:868:5:868:20 | match_pattern8(...) | main.rs:869:5:869:21 | ExprStmt | | +| main.rs:868:5:868:21 | ExprStmt | main.rs:868:5:868:18 | match_pattern8 | | +| main.rs:869:5:869:18 | match_pattern9 | main.rs:869:5:869:20 | match_pattern9(...) | | +| main.rs:869:5:869:20 | match_pattern9(...) | main.rs:870:5:870:22 | ExprStmt | | +| main.rs:869:5:869:21 | ExprStmt | main.rs:869:5:869:18 | match_pattern9 | | +| main.rs:870:5:870:19 | match_pattern10 | main.rs:870:5:870:21 | match_pattern10(...) | | +| main.rs:870:5:870:21 | match_pattern10(...) | main.rs:871:5:871:22 | ExprStmt | | +| main.rs:870:5:870:22 | ExprStmt | main.rs:870:5:870:19 | match_pattern10 | | +| main.rs:871:5:871:19 | match_pattern11 | main.rs:871:5:871:21 | match_pattern11(...) | | +| main.rs:871:5:871:21 | match_pattern11(...) | main.rs:872:5:872:22 | ExprStmt | | +| main.rs:871:5:871:22 | ExprStmt | main.rs:871:5:871:19 | match_pattern11 | | +| main.rs:872:5:872:19 | match_pattern12 | main.rs:872:5:872:21 | match_pattern12(...) | | +| main.rs:872:5:872:21 | match_pattern12(...) | main.rs:873:5:873:22 | ExprStmt | | +| main.rs:872:5:872:22 | ExprStmt | main.rs:872:5:872:19 | match_pattern12 | | +| main.rs:873:5:873:19 | match_pattern13 | main.rs:873:5:873:21 | match_pattern13(...) | | +| main.rs:873:5:873:21 | match_pattern13(...) | main.rs:874:5:874:22 | ExprStmt | | +| main.rs:873:5:873:22 | ExprStmt | main.rs:873:5:873:19 | match_pattern13 | | +| main.rs:874:5:874:19 | match_pattern14 | main.rs:874:5:874:21 | match_pattern14(...) | | +| main.rs:874:5:874:21 | match_pattern14(...) | main.rs:875:5:875:22 | ExprStmt | | +| main.rs:874:5:874:22 | ExprStmt | main.rs:874:5:874:19 | match_pattern14 | | +| main.rs:875:5:875:19 | match_pattern15 | main.rs:875:5:875:21 | match_pattern15(...) | | +| main.rs:875:5:875:21 | match_pattern15(...) | main.rs:876:5:876:22 | ExprStmt | | +| main.rs:875:5:875:22 | ExprStmt | main.rs:875:5:875:19 | match_pattern15 | | +| main.rs:876:5:876:19 | match_pattern16 | main.rs:876:5:876:21 | match_pattern16(...) | | +| main.rs:876:5:876:21 | match_pattern16(...) | main.rs:877:5:877:36 | ExprStmt | | +| main.rs:876:5:876:22 | ExprStmt | main.rs:876:5:876:19 | match_pattern16 | | +| main.rs:877:5:877:18 | param_pattern1 | main.rs:877:20:877:22 | "a" | | +| main.rs:877:5:877:35 | param_pattern1(...) | main.rs:878:5:878:37 | ExprStmt | | +| main.rs:877:5:877:36 | ExprStmt | main.rs:877:5:877:18 | param_pattern1 | | +| main.rs:877:20:877:22 | "a" | main.rs:877:26:877:28 | "b" | | +| main.rs:877:25:877:34 | TupleExpr | main.rs:877:5:877:35 | param_pattern1(...) | | +| main.rs:877:26:877:28 | "b" | main.rs:877:31:877:33 | "c" | | +| main.rs:877:31:877:33 | "c" | main.rs:877:25:877:34 | TupleExpr | | +| main.rs:878:5:878:18 | param_pattern2 | main.rs:878:20:878:31 | ...::Left | | +| main.rs:878:5:878:36 | param_pattern2(...) | main.rs:879:5:879:26 | ExprStmt | | +| main.rs:878:5:878:37 | ExprStmt | main.rs:878:5:878:18 | param_pattern2 | | +| main.rs:878:20:878:31 | ...::Left | main.rs:878:33:878:34 | 45 | | +| main.rs:878:20:878:35 | ...::Left(...) | main.rs:878:5:878:36 | param_pattern2(...) | | +| main.rs:878:33:878:34 | 45 | main.rs:878:20:878:35 | ...::Left(...) | | +| main.rs:879:5:879:23 | destruct_assignment | main.rs:879:5:879:25 | destruct_assignment(...) | | +| main.rs:879:5:879:25 | destruct_assignment(...) | main.rs:880:5:880:23 | ExprStmt | | +| main.rs:879:5:879:26 | ExprStmt | main.rs:879:5:879:23 | destruct_assignment | | +| main.rs:880:5:880:20 | closure_variable | main.rs:880:5:880:22 | closure_variable(...) | | +| main.rs:880:5:880:22 | closure_variable(...) | main.rs:881:5:881:22 | ExprStmt | | +| main.rs:880:5:880:23 | ExprStmt | main.rs:880:5:880:20 | closure_variable | | +| main.rs:881:5:881:19 | nested_function | main.rs:881:5:881:21 | nested_function(...) | | +| main.rs:881:5:881:21 | nested_function(...) | main.rs:882:5:882:19 | ExprStmt | | +| main.rs:881:5:881:22 | ExprStmt | main.rs:881:5:881:19 | nested_function | | +| main.rs:882:5:882:16 | for_variable | main.rs:882:5:882:18 | for_variable(...) | | +| main.rs:882:5:882:18 | for_variable(...) | main.rs:883:5:883:17 | ExprStmt | | +| main.rs:882:5:882:19 | ExprStmt | main.rs:882:5:882:16 | for_variable | | +| main.rs:883:5:883:14 | add_assign | main.rs:883:5:883:16 | add_assign(...) | | +| main.rs:883:5:883:16 | add_assign(...) | main.rs:884:5:884:13 | ExprStmt | | +| main.rs:883:5:883:17 | ExprStmt | main.rs:883:5:883:14 | add_assign | | +| main.rs:884:5:884:10 | mutate | main.rs:884:5:884:12 | mutate(...) | | +| main.rs:884:5:884:12 | mutate(...) | main.rs:885:5:885:17 | ExprStmt | | +| main.rs:884:5:884:13 | ExprStmt | main.rs:884:5:884:10 | mutate | | +| main.rs:885:5:885:14 | mutate_arg | main.rs:885:5:885:16 | mutate_arg(...) | | +| main.rs:885:5:885:16 | mutate_arg(...) | main.rs:886:5:886:12 | ExprStmt | | +| main.rs:885:5:885:17 | ExprStmt | main.rs:885:5:885:14 | mutate_arg | | +| main.rs:886:5:886:9 | alias | main.rs:886:5:886:11 | alias(...) | | +| main.rs:886:5:886:11 | alias(...) | main.rs:887:5:887:18 | ExprStmt | | +| main.rs:886:5:886:12 | ExprStmt | main.rs:886:5:886:9 | alias | | +| main.rs:887:5:887:15 | capture_mut | main.rs:887:5:887:17 | capture_mut(...) | | +| main.rs:887:5:887:17 | capture_mut(...) | main.rs:888:5:888:20 | ExprStmt | | +| main.rs:887:5:887:18 | ExprStmt | main.rs:887:5:887:15 | capture_mut | | +| main.rs:888:5:888:17 | capture_immut | main.rs:888:5:888:19 | capture_immut(...) | | +| main.rs:888:5:888:19 | capture_immut(...) | main.rs:889:5:889:26 | ExprStmt | | +| main.rs:888:5:888:20 | ExprStmt | main.rs:888:5:888:17 | capture_immut | | +| main.rs:889:5:889:23 | async_block_capture | main.rs:889:5:889:25 | async_block_capture(...) | | +| main.rs:889:5:889:25 | async_block_capture(...) | main.rs:890:5:890:14 | ExprStmt | | +| main.rs:889:5:889:26 | ExprStmt | main.rs:889:5:889:23 | async_block_capture | | +| main.rs:890:5:890:11 | structs | main.rs:890:5:890:13 | structs(...) | | +| main.rs:890:5:890:13 | structs(...) | main.rs:891:5:891:14 | ExprStmt | | +| main.rs:890:5:890:14 | ExprStmt | main.rs:890:5:890:11 | structs | | +| main.rs:891:5:891:11 | ref_arg | main.rs:891:5:891:13 | ref_arg(...) | | +| main.rs:891:5:891:13 | ref_arg(...) | main.rs:892:5:892:30 | ExprStmt | | +| main.rs:891:5:891:14 | ExprStmt | main.rs:891:5:891:11 | ref_arg | | +| main.rs:892:5:892:27 | ref_methodcall_receiver | main.rs:892:5:892:29 | ref_methodcall_receiver(...) | | +| main.rs:892:5:892:29 | ref_methodcall_receiver(...) | main.rs:893:5:893:23 | ExprStmt | | +| main.rs:892:5:892:30 | ExprStmt | main.rs:892:5:892:27 | ref_methodcall_receiver | | +| main.rs:893:5:893:20 | macro_invocation | main.rs:893:5:893:22 | macro_invocation(...) | | +| main.rs:893:5:893:22 | macro_invocation(...) | main.rs:894:5:894:18 | ExprStmt | | +| main.rs:893:5:893:23 | ExprStmt | main.rs:893:5:893:20 | macro_invocation | | +| main.rs:894:5:894:15 | capture_phi | main.rs:894:5:894:17 | capture_phi(...) | | +| main.rs:894:5:894:17 | capture_phi(...) | main.rs:895:5:895:27 | ExprStmt | | +| main.rs:894:5:894:18 | ExprStmt | main.rs:894:5:894:15 | capture_phi | | +| main.rs:895:5:895:24 | let_in_block_in_cond | main.rs:895:5:895:26 | let_in_block_in_cond(...) | | +| main.rs:895:5:895:26 | let_in_block_in_cond(...) | main.rs:849:11:896:1 | { ... } | | +| main.rs:895:5:895:27 | ExprStmt | main.rs:895:5:895:24 | let_in_block_in_cond | | breakTarget -| main.rs:326:9:326:13 | break | main.rs:317:5:327:5 | while ... { ... } | +| main.rs:361:9:361:13 | break | main.rs:352:5:362:5 | while ... { ... } | continueTarget diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index 0acf3e94c5b..d428d49cf1d 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -24,185 +24,197 @@ definition | main.rs:100:9:100:9 | x | main.rs:100:9:100:9 | x | | main.rs:101:14:101:14 | x | main.rs:101:14:101:14 | x | | main.rs:104:13:104:13 | x | main.rs:104:13:104:13 | x | -| main.rs:113:9:113:10 | s1 | main.rs:113:9:113:10 | s1 | -| main.rs:115:24:115:25 | s2 | main.rs:115:24:115:25 | s2 | -| main.rs:122:9:122:10 | x6 | main.rs:122:9:122:10 | x6 | -| main.rs:123:9:123:10 | y1 | main.rs:123:9:123:10 | y1 | -| main.rs:127:14:127:15 | y1 | main.rs:127:14:127:15 | y1 | -| main.rs:139:9:139:15 | numbers | main.rs:139:9:139:15 | numbers | -| main.rs:144:13:144:17 | first | main.rs:144:13:144:17 | first | -| main.rs:146:13:146:17 | third | main.rs:146:13:146:17 | third | -| main.rs:148:13:148:17 | fifth | main.rs:148:13:148:17 | fifth | -| main.rs:159:13:159:17 | first | main.rs:159:13:159:17 | first | -| main.rs:161:13:161:16 | last | main.rs:161:13:161:16 | last | -| main.rs:170:9:170:10 | p2 | main.rs:170:9:170:10 | p2 | -| main.rs:174:16:174:17 | x7 | main.rs:174:16:174:17 | x7 | -| main.rs:184:9:184:11 | msg | main.rs:184:9:184:11 | msg | -| main.rs:189:17:189:27 | id_variable | main.rs:189:17:189:27 | id_variable | -| main.rs:194:26:194:27 | id | main.rs:194:26:194:27 | id | -| main.rs:208:9:208:14 | either | main.rs:208:9:208:14 | either | -| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:9:210:44 | a3 | -| main.rs:210:22:210:23 | a3 | main.rs:210:9:210:44 | a3 | -| main.rs:210:42:210:43 | a3 | main.rs:210:9:210:44 | a3 | -| main.rs:222:9:222:10 | tv | main.rs:222:9:222:10 | tv | -| main.rs:224:9:224:81 | SSA phi(a4) | main.rs:224:9:224:81 | a4 | -| main.rs:224:28:224:29 | a4 | main.rs:224:9:224:81 | a4 | -| main.rs:224:54:224:55 | a4 | main.rs:224:9:224:81 | a4 | -| main.rs:224:79:224:80 | a4 | main.rs:224:9:224:81 | a4 | -| main.rs:228:9:228:83 | SSA phi(a5) | main.rs:228:9:228:83 | a5 | -| main.rs:228:10:228:57 | [match(true)] SSA phi(a5) | main.rs:228:9:228:83 | a5 | -| main.rs:228:29:228:30 | a5 | main.rs:228:9:228:83 | a5 | -| main.rs:228:55:228:56 | a5 | main.rs:228:9:228:83 | a5 | -| main.rs:228:81:228:82 | a5 | main.rs:228:9:228:83 | a5 | -| main.rs:232:9:232:83 | SSA phi(a6) | main.rs:232:9:232:83 | a6 | -| main.rs:232:28:232:29 | a6 | main.rs:232:9:232:83 | a6 | -| main.rs:232:35:232:82 | SSA phi(a6) | main.rs:232:9:232:83 | a6 | -| main.rs:232:55:232:56 | a6 | main.rs:232:9:232:83 | a6 | -| main.rs:232:80:232:81 | a6 | main.rs:232:9:232:83 | a6 | -| main.rs:238:9:238:14 | either | main.rs:238:9:238:14 | either | -| main.rs:240:9:240:44 | [match(true)] SSA phi(a7) | main.rs:240:9:240:44 | a7 | -| main.rs:240:22:240:23 | a7 | main.rs:240:9:240:44 | a7 | -| main.rs:240:42:240:43 | a7 | main.rs:240:9:240:44 | a7 | -| main.rs:248:9:248:14 | either | main.rs:248:9:248:14 | either | -| main.rs:251:13:251:13 | e | main.rs:251:13:251:13 | e | -| main.rs:252:14:252:51 | [match(true)] SSA phi(a11) | main.rs:252:14:252:51 | a11 | -| main.rs:252:27:252:29 | a11 | main.rs:252:14:252:51 | a11 | -| main.rs:252:48:252:50 | a11 | main.rs:252:14:252:51 | a11 | -| main.rs:255:33:255:35 | a12 | main.rs:255:33:255:35 | a12 | -| main.rs:272:9:272:10 | fv | main.rs:272:9:272:10 | fv | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:9:274:109 | a13 | -| main.rs:274:27:274:29 | a13 | main.rs:274:9:274:109 | a13 | -| main.rs:274:35:274:82 | [match(true)] SSA phi(a13) | main.rs:274:9:274:109 | a13 | -| main.rs:274:54:274:56 | a13 | main.rs:274:9:274:109 | a13 | -| main.rs:274:79:274:81 | a13 | main.rs:274:9:274:109 | a13 | -| main.rs:274:106:274:108 | a13 | main.rs:274:9:274:109 | a13 | -| main.rs:281:9:281:9 | x | main.rs:281:9:281:9 | x | -| main.rs:282:17:282:17 | x | main.rs:282:17:282:17 | x | -| main.rs:289:13:289:13 | x | main.rs:289:13:289:13 | x | -| main.rs:297:9:297:9 | x | main.rs:297:9:297:9 | x | -| main.rs:298:17:298:17 | x | main.rs:298:17:298:17 | x | -| main.rs:301:14:301:14 | x | main.rs:301:14:301:14 | x | -| main.rs:308:13:308:13 | x | main.rs:308:13:308:13 | x | +| main.rs:113:9:113:9 | s | main.rs:113:9:113:9 | s | +| main.rs:115:24:115:24 | s | main.rs:115:24:115:24 | s | +| main.rs:123:17:123:17 | x | main.rs:123:17:123:17 | x | +| main.rs:124:19:124:19 | x | main.rs:124:19:124:19 | x | +| main.rs:133:9:133:9 | x | main.rs:133:9:133:9 | x | +| main.rs:134:12:134:12 | x | main.rs:134:12:134:12 | x | +| main.rs:136:12:136:12 | x | main.rs:136:12:136:12 | x | +| main.rs:138:12:138:12 | x | main.rs:138:12:138:12 | x | +| main.rs:140:12:140:12 | x | main.rs:140:12:140:12 | x | +| main.rs:142:12:142:12 | x | main.rs:142:12:142:12 | x | +| main.rs:144:12:144:12 | x | main.rs:144:12:144:12 | x | +| main.rs:146:12:146:12 | x | main.rs:146:12:146:12 | x | +| main.rs:157:9:157:10 | x6 | main.rs:157:9:157:10 | x6 | +| main.rs:158:9:158:10 | y1 | main.rs:158:9:158:10 | y1 | +| main.rs:162:14:162:15 | y1 | main.rs:162:14:162:15 | y1 | +| main.rs:174:9:174:15 | numbers | main.rs:174:9:174:15 | numbers | +| main.rs:179:13:179:17 | first | main.rs:179:13:179:17 | first | +| main.rs:181:13:181:17 | third | main.rs:181:13:181:17 | third | +| main.rs:183:13:183:17 | fifth | main.rs:183:13:183:17 | fifth | +| main.rs:194:13:194:17 | first | main.rs:194:13:194:17 | first | +| main.rs:196:13:196:16 | last | main.rs:196:13:196:16 | last | +| main.rs:205:9:205:10 | p2 | main.rs:205:9:205:10 | p2 | +| main.rs:209:16:209:17 | x7 | main.rs:209:16:209:17 | x7 | +| main.rs:219:9:219:11 | msg | main.rs:219:9:219:11 | msg | +| main.rs:224:17:224:27 | id_variable | main.rs:224:17:224:27 | id_variable | +| main.rs:229:26:229:27 | id | main.rs:229:26:229:27 | id | +| main.rs:243:9:243:14 | either | main.rs:243:9:243:14 | either | +| main.rs:245:9:245:44 | SSA phi(a3) | main.rs:245:9:245:44 | a3 | +| main.rs:245:22:245:23 | a3 | main.rs:245:9:245:44 | a3 | +| main.rs:245:42:245:43 | a3 | main.rs:245:9:245:44 | a3 | +| main.rs:257:9:257:10 | tv | main.rs:257:9:257:10 | tv | +| main.rs:259:9:259:81 | SSA phi(a4) | main.rs:259:9:259:81 | a4 | +| main.rs:259:28:259:29 | a4 | main.rs:259:9:259:81 | a4 | +| main.rs:259:54:259:55 | a4 | main.rs:259:9:259:81 | a4 | +| main.rs:259:79:259:80 | a4 | main.rs:259:9:259:81 | a4 | +| main.rs:263:9:263:83 | SSA phi(a5) | main.rs:263:9:263:83 | a5 | +| main.rs:263:10:263:57 | [match(true)] SSA phi(a5) | main.rs:263:9:263:83 | a5 | +| main.rs:263:29:263:30 | a5 | main.rs:263:9:263:83 | a5 | +| main.rs:263:55:263:56 | a5 | main.rs:263:9:263:83 | a5 | +| main.rs:263:81:263:82 | a5 | main.rs:263:9:263:83 | a5 | +| main.rs:267:9:267:83 | SSA phi(a6) | main.rs:267:9:267:83 | a6 | +| main.rs:267:28:267:29 | a6 | main.rs:267:9:267:83 | a6 | +| main.rs:267:35:267:82 | SSA phi(a6) | main.rs:267:9:267:83 | a6 | +| main.rs:267:55:267:56 | a6 | main.rs:267:9:267:83 | a6 | +| main.rs:267:80:267:81 | a6 | main.rs:267:9:267:83 | a6 | +| main.rs:273:9:273:14 | either | main.rs:273:9:273:14 | either | +| main.rs:275:9:275:44 | [match(true)] SSA phi(a7) | main.rs:275:9:275:44 | a7 | +| main.rs:275:22:275:23 | a7 | main.rs:275:9:275:44 | a7 | +| main.rs:275:42:275:43 | a7 | main.rs:275:9:275:44 | a7 | +| main.rs:283:9:283:14 | either | main.rs:283:9:283:14 | either | +| main.rs:286:13:286:13 | e | main.rs:286:13:286:13 | e | +| main.rs:287:14:287:51 | [match(true)] SSA phi(a11) | main.rs:287:14:287:51 | a11 | +| main.rs:287:27:287:29 | a11 | main.rs:287:14:287:51 | a11 | +| main.rs:287:48:287:50 | a11 | main.rs:287:14:287:51 | a11 | +| main.rs:290:33:290:35 | a12 | main.rs:290:33:290:35 | a12 | +| main.rs:307:9:307:10 | fv | main.rs:307:9:307:10 | fv | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:9:309:109 | a13 | +| main.rs:309:27:309:29 | a13 | main.rs:309:9:309:109 | a13 | +| main.rs:309:35:309:82 | [match(true)] SSA phi(a13) | main.rs:309:9:309:109 | a13 | +| main.rs:309:54:309:56 | a13 | main.rs:309:9:309:109 | a13 | +| main.rs:309:79:309:81 | a13 | main.rs:309:9:309:109 | a13 | +| main.rs:309:106:309:108 | a13 | main.rs:309:9:309:109 | a13 | | main.rs:316:9:316:9 | x | main.rs:316:9:316:9 | x | -| main.rs:317:20:317:20 | x | main.rs:317:20:317:20 | x | -| main.rs:320:14:320:14 | x | main.rs:320:14:320:14 | x | -| main.rs:334:9:334:9 | x | main.rs:334:9:334:9 | x | +| main.rs:317:17:317:17 | x | main.rs:317:17:317:17 | x | +| main.rs:324:13:324:13 | x | main.rs:324:13:324:13 | x | +| main.rs:332:9:332:9 | x | main.rs:332:9:332:9 | x | +| main.rs:333:17:333:17 | x | main.rs:333:17:333:17 | x | | main.rs:336:14:336:14 | x | main.rs:336:14:336:14 | x | -| main.rs:337:20:337:20 | x | main.rs:337:20:337:20 | x | -| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | -| main.rs:349:16:349:16 | x | main.rs:349:16:349:16 | x | -| main.rs:354:20:354:20 | x | main.rs:354:20:354:20 | x | -| main.rs:364:9:364:9 | x | main.rs:364:9:364:9 | x | -| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | -| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | -| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | -| main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y | -| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | -| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | -| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | -| main.rs:395:20:395:55 | SSA phi(a9) | main.rs:395:20:395:55 | a9 | -| main.rs:395:33:395:34 | a9 | main.rs:395:20:395:55 | a9 | -| main.rs:395:53:395:54 | a9 | main.rs:395:20:395:55 | a9 | -| main.rs:402:13:402:15 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:403:13:403:14 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:404:13:404:14 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:411:9:411:10 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:412:9:412:10 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:413:9:413:11 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:425:13:425:15 | a10 | main.rs:425:13:425:15 | a10 | -| main.rs:426:13:426:14 | b4 | main.rs:426:13:426:14 | b4 | -| main.rs:438:9:438:23 | example_closure | main.rs:438:9:438:23 | example_closure | -| main.rs:439:10:439:10 | x | main.rs:439:10:439:10 | x | -| main.rs:441:9:441:10 | n1 | main.rs:441:9:441:10 | n1 | -| main.rs:446:9:446:26 | immutable_variable | main.rs:446:9:446:26 | immutable_variable | -| main.rs:447:6:447:6 | x | main.rs:447:6:447:6 | x | -| main.rs:449:9:449:10 | n2 | main.rs:449:9:449:10 | n2 | -| main.rs:456:9:456:9 | f | main.rs:456:9:456:9 | f | -| main.rs:457:10:457:10 | x | main.rs:457:10:457:10 | x | -| main.rs:461:10:461:10 | x | main.rs:461:10:461:10 | x | -| main.rs:470:14:470:14 | x | main.rs:470:14:470:14 | x | -| main.rs:479:13:479:13 | f | main.rs:479:13:479:13 | f | -| main.rs:480:14:480:14 | x | main.rs:480:14:480:14 | x | -| main.rs:487:9:487:9 | v | main.rs:487:9:487:9 | v | -| main.rs:489:9:489:12 | text | main.rs:489:9:489:12 | text | -| main.rs:496:13:496:13 | a | main.rs:496:13:496:13 | a | -| main.rs:497:5:497:5 | a | main.rs:496:13:496:13 | a | -| main.rs:499:6:499:11 | &mut a | main.rs:496:13:496:13 | a | -| main.rs:504:13:504:13 | i | main.rs:504:13:504:13 | i | -| main.rs:505:9:505:13 | ref_i | main.rs:505:9:505:13 | ref_i | -| main.rs:506:9:506:14 | &mut i | main.rs:504:13:504:13 | i | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | -| main.rs:518:38:518:38 | y | main.rs:518:38:518:38 | y | -| main.rs:527:13:527:13 | x | main.rs:527:13:527:13 | x | -| main.rs:528:9:528:9 | y | main.rs:528:9:528:9 | y | -| main.rs:529:22:529:27 | &mut x | main.rs:527:13:527:13 | x | -| main.rs:535:13:535:13 | z | main.rs:535:13:535:13 | z | -| main.rs:536:9:536:9 | w | main.rs:536:9:536:9 | w | -| main.rs:539:9:539:14 | &mut z | main.rs:535:13:535:13 | z | -| main.rs:549:13:549:13 | x | main.rs:549:13:549:13 | x | -| main.rs:550:9:550:9 | y | main.rs:550:9:550:9 | y | -| main.rs:551:9:551:14 | &mut x | main.rs:549:13:549:13 | x | -| main.rs:557:9:557:9 | x | main.rs:557:9:557:9 | x | -| main.rs:560:9:560:11 | cap | main.rs:560:9:560:11 | cap | -| main.rs:560:15:562:5 | x | main.rs:557:9:557:9 | x | -| main.rs:568:13:568:13 | x | main.rs:568:13:568:13 | x | -| main.rs:571:9:571:16 | closure1 | main.rs:571:9:571:16 | closure1 | -| main.rs:571:20:573:5 | x | main.rs:568:13:568:13 | x | -| main.rs:577:13:577:13 | y | main.rs:577:13:577:13 | y | -| main.rs:580:13:580:20 | closure2 | main.rs:580:13:580:20 | closure2 | -| main.rs:581:9:581:9 | y | main.rs:577:13:577:13 | y | -| main.rs:583:5:583:14 | y | main.rs:577:13:577:13 | y | -| main.rs:586:13:586:13 | z | main.rs:586:13:586:13 | z | -| main.rs:589:13:589:20 | closure3 | main.rs:589:13:589:20 | closure3 | -| main.rs:589:24:591:5 | z | main.rs:586:13:586:13 | z | -| main.rs:597:13:597:13 | i | main.rs:597:13:597:13 | i | -| main.rs:598:9:598:13 | block | main.rs:598:9:598:13 | block | -| main.rs:599:9:599:9 | i | main.rs:597:13:597:13 | i | -| main.rs:602:5:602:15 | i | main.rs:597:13:597:13 | i | -| main.rs:606:8:606:8 | b | main.rs:606:8:606:8 | b | -| main.rs:607:13:607:13 | x | main.rs:607:13:607:13 | x | -| main.rs:611:13:620:5 | SSA phi(x) | main.rs:607:13:607:13 | x | -| main.rs:613:9:613:9 | x | main.rs:607:13:607:13 | x | -| main.rs:617:9:617:9 | x | main.rs:607:13:607:13 | x | -| main.rs:624:13:624:14 | b1 | main.rs:624:13:624:14 | b1 | -| main.rs:624:23:624:24 | b2 | main.rs:624:23:624:24 | b2 | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | -| main.rs:648:20:648:23 | self | main.rs:648:20:648:23 | self | -| main.rs:652:11:652:14 | self | main.rs:652:11:652:14 | self | -| main.rs:656:23:656:26 | self | main.rs:656:23:656:26 | self | -| main.rs:657:17:657:17 | f | main.rs:657:17:657:17 | f | -| main.rs:657:21:660:9 | self | main.rs:656:23:656:26 | self | -| main.rs:657:22:657:22 | n | main.rs:657:22:657:22 | n | -| main.rs:667:13:667:13 | a | main.rs:667:13:667:13 | a | -| main.rs:668:15:668:15 | a | main.rs:667:13:667:13 | a | -| main.rs:671:5:671:5 | a | main.rs:667:13:667:13 | a | -| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | -| main.rs:680:5:680:5 | a | main.rs:676:13:676:13 | a | -| main.rs:685:9:685:9 | x | main.rs:685:9:685:9 | x | -| main.rs:689:9:689:9 | z | main.rs:689:9:689:9 | z | -| main.rs:698:17:698:20 | self | main.rs:698:17:698:20 | self | -| main.rs:704:13:704:13 | a | main.rs:704:13:704:13 | a | -| main.rs:705:5:705:5 | a | main.rs:704:13:704:13 | a | -| main.rs:726:9:726:22 | var_from_macro | main.rs:726:9:726:22 | var_from_macro | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:9:727:21 | var_in_macro | -| main.rs:729:9:729:20 | var_in_macro | main.rs:729:9:729:20 | var_in_macro | -| main.rs:734:15:734:28 | var_in_macro | main.rs:734:15:734:28 | var_in_macro | -| main.rs:740:5:740:5 | x | main.rs:739:9:739:9 | x | -| main.rs:745:13:745:13 | x | main.rs:745:13:745:13 | x | -| main.rs:746:13:746:15 | cap | main.rs:746:13:746:15 | cap | -| main.rs:746:19:751:5 | x | main.rs:745:13:745:13 | x | -| main.rs:746:20:746:20 | b | main.rs:746:20:746:20 | b | -| main.rs:748:17:750:9 | SSA phi(x) | main.rs:745:13:745:13 | x | -| main.rs:749:13:749:13 | x | main.rs:745:13:745:13 | x | -| main.rs:752:5:752:13 | x | main.rs:745:13:745:13 | x | -| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | -| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | -| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | -| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | -| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | -| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | -| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | +| main.rs:343:13:343:13 | x | main.rs:343:13:343:13 | x | +| main.rs:351:9:351:9 | x | main.rs:351:9:351:9 | x | +| main.rs:352:20:352:20 | x | main.rs:352:20:352:20 | x | +| main.rs:355:14:355:14 | x | main.rs:355:14:355:14 | x | +| main.rs:369:9:369:9 | x | main.rs:369:9:369:9 | x | +| main.rs:371:14:371:14 | x | main.rs:371:14:371:14 | x | +| main.rs:372:20:372:20 | x | main.rs:372:20:372:20 | x | +| main.rs:383:9:383:9 | x | main.rs:383:9:383:9 | x | +| main.rs:384:16:384:16 | x | main.rs:384:16:384:16 | x | +| main.rs:389:20:389:20 | x | main.rs:389:20:389:20 | x | +| main.rs:399:9:399:9 | x | main.rs:399:9:399:9 | x | +| main.rs:401:18:401:18 | x | main.rs:401:18:401:18 | x | +| main.rs:408:9:408:9 | x | main.rs:408:9:408:9 | x | +| main.rs:410:14:410:14 | y | main.rs:410:14:410:14 | y | +| main.rs:412:22:412:22 | y | main.rs:412:22:412:22 | y | +| main.rs:420:5:420:6 | a8 | main.rs:420:5:420:6 | a8 | +| main.rs:422:9:422:10 | b3 | main.rs:422:9:422:10 | b3 | +| main.rs:423:9:423:10 | c1 | main.rs:423:9:423:10 | c1 | +| main.rs:431:20:431:55 | SSA phi(a9) | main.rs:431:20:431:55 | a9 | +| main.rs:431:33:431:34 | a9 | main.rs:431:20:431:55 | a9 | +| main.rs:431:53:431:54 | a9 | main.rs:431:20:431:55 | a9 | +| main.rs:438:13:438:15 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:439:13:439:14 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:440:13:440:14 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:447:9:447:10 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:448:9:448:10 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:449:9:449:11 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:461:13:461:15 | a10 | main.rs:461:13:461:15 | a10 | +| main.rs:462:13:462:14 | b4 | main.rs:462:13:462:14 | b4 | +| main.rs:474:9:474:23 | example_closure | main.rs:474:9:474:23 | example_closure | +| main.rs:475:10:475:10 | x | main.rs:475:10:475:10 | x | +| main.rs:477:9:477:10 | n1 | main.rs:477:9:477:10 | n1 | +| main.rs:482:9:482:26 | immutable_variable | main.rs:482:9:482:26 | immutable_variable | +| main.rs:483:6:483:6 | x | main.rs:483:6:483:6 | x | +| main.rs:485:9:485:10 | n2 | main.rs:485:9:485:10 | n2 | +| main.rs:492:9:492:9 | f | main.rs:492:9:492:9 | f | +| main.rs:493:10:493:10 | x | main.rs:493:10:493:10 | x | +| main.rs:497:10:497:10 | x | main.rs:497:10:497:10 | x | +| main.rs:506:14:506:14 | x | main.rs:506:14:506:14 | x | +| main.rs:515:13:515:13 | f | main.rs:515:13:515:13 | f | +| main.rs:516:14:516:14 | x | main.rs:516:14:516:14 | x | +| main.rs:523:9:523:9 | v | main.rs:523:9:523:9 | v | +| main.rs:525:9:525:12 | text | main.rs:525:9:525:12 | text | +| main.rs:532:13:532:13 | a | main.rs:532:13:532:13 | a | +| main.rs:533:5:533:5 | a | main.rs:532:13:532:13 | a | +| main.rs:535:6:535:11 | &mut a | main.rs:532:13:532:13 | a | +| main.rs:540:13:540:13 | i | main.rs:540:13:540:13 | i | +| main.rs:541:9:541:13 | ref_i | main.rs:541:9:541:13 | ref_i | +| main.rs:542:9:542:14 | &mut i | main.rs:540:13:540:13 | i | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | +| main.rs:554:38:554:38 | y | main.rs:554:38:554:38 | y | +| main.rs:563:13:563:13 | x | main.rs:563:13:563:13 | x | +| main.rs:564:9:564:9 | y | main.rs:564:9:564:9 | y | +| main.rs:565:22:565:27 | &mut x | main.rs:563:13:563:13 | x | +| main.rs:571:13:571:13 | z | main.rs:571:13:571:13 | z | +| main.rs:572:9:572:9 | w | main.rs:572:9:572:9 | w | +| main.rs:575:9:575:14 | &mut z | main.rs:571:13:571:13 | z | +| main.rs:585:13:585:13 | x | main.rs:585:13:585:13 | x | +| main.rs:586:9:586:9 | y | main.rs:586:9:586:9 | y | +| main.rs:587:9:587:14 | &mut x | main.rs:585:13:585:13 | x | +| main.rs:593:9:593:9 | x | main.rs:593:9:593:9 | x | +| main.rs:596:9:596:11 | cap | main.rs:596:9:596:11 | cap | +| main.rs:596:15:598:5 | x | main.rs:593:9:593:9 | x | +| main.rs:604:13:604:13 | x | main.rs:604:13:604:13 | x | +| main.rs:607:9:607:16 | closure1 | main.rs:607:9:607:16 | closure1 | +| main.rs:607:20:609:5 | x | main.rs:604:13:604:13 | x | +| main.rs:613:13:613:13 | y | main.rs:613:13:613:13 | y | +| main.rs:616:13:616:20 | closure2 | main.rs:616:13:616:20 | closure2 | +| main.rs:617:9:617:9 | y | main.rs:613:13:613:13 | y | +| main.rs:619:5:619:14 | y | main.rs:613:13:613:13 | y | +| main.rs:622:13:622:13 | z | main.rs:622:13:622:13 | z | +| main.rs:625:13:625:20 | closure3 | main.rs:625:13:625:20 | closure3 | +| main.rs:625:24:627:5 | z | main.rs:622:13:622:13 | z | +| main.rs:633:13:633:13 | i | main.rs:633:13:633:13 | i | +| main.rs:634:9:634:13 | block | main.rs:634:9:634:13 | block | +| main.rs:635:9:635:9 | i | main.rs:633:13:633:13 | i | +| main.rs:638:5:638:15 | i | main.rs:633:13:633:13 | i | +| main.rs:642:8:642:8 | b | main.rs:642:8:642:8 | b | +| main.rs:643:13:643:13 | x | main.rs:643:13:643:13 | x | +| main.rs:647:13:656:5 | SSA phi(x) | main.rs:643:13:643:13 | x | +| main.rs:649:9:649:9 | x | main.rs:643:13:643:13 | x | +| main.rs:653:9:653:9 | x | main.rs:643:13:643:13 | x | +| main.rs:660:13:660:14 | b1 | main.rs:660:13:660:14 | b1 | +| main.rs:660:23:660:24 | b2 | main.rs:660:23:660:24 | b2 | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | +| main.rs:684:20:684:23 | self | main.rs:684:20:684:23 | self | +| main.rs:688:11:688:14 | self | main.rs:688:11:688:14 | self | +| main.rs:692:23:692:26 | self | main.rs:692:23:692:26 | self | +| main.rs:693:17:693:17 | f | main.rs:693:17:693:17 | f | +| main.rs:693:21:696:9 | self | main.rs:692:23:692:26 | self | +| main.rs:693:22:693:22 | n | main.rs:693:22:693:22 | n | +| main.rs:703:13:703:13 | a | main.rs:703:13:703:13 | a | +| main.rs:704:15:704:15 | a | main.rs:703:13:703:13 | a | +| main.rs:707:5:707:5 | a | main.rs:703:13:703:13 | a | +| main.rs:712:13:712:13 | a | main.rs:712:13:712:13 | a | +| main.rs:716:5:716:5 | a | main.rs:712:13:712:13 | a | +| main.rs:721:9:721:9 | x | main.rs:721:9:721:9 | x | +| main.rs:725:9:725:9 | z | main.rs:725:9:725:9 | z | +| main.rs:734:17:734:20 | self | main.rs:734:17:734:20 | self | +| main.rs:740:13:740:13 | a | main.rs:740:13:740:13 | a | +| main.rs:741:5:741:5 | a | main.rs:740:13:740:13 | a | +| main.rs:762:9:762:22 | var_from_macro | main.rs:762:9:762:22 | var_from_macro | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:9:763:21 | var_in_macro | +| main.rs:765:9:765:20 | var_in_macro | main.rs:765:9:765:20 | var_in_macro | +| main.rs:770:15:770:28 | var_in_macro | main.rs:770:15:770:28 | var_in_macro | +| main.rs:776:5:776:5 | x | main.rs:775:9:775:9 | x | +| main.rs:781:13:781:13 | x | main.rs:781:13:781:13 | x | +| main.rs:782:13:782:15 | cap | main.rs:782:13:782:15 | cap | +| main.rs:782:19:787:5 | x | main.rs:781:13:781:13 | x | +| main.rs:782:20:782:20 | b | main.rs:782:20:782:20 | b | +| main.rs:784:17:786:9 | SSA phi(x) | main.rs:781:13:781:13 | x | +| main.rs:785:13:785:13 | x | main.rs:781:13:781:13 | x | +| main.rs:788:5:788:13 | x | main.rs:781:13:781:13 | x | +| main.rs:795:13:795:13 | x | main.rs:795:13:795:13 | x | +| main.rs:796:13:796:13 | y | main.rs:796:13:796:13 | y | +| main.rs:805:13:805:16 | N0ne | main.rs:805:13:805:16 | N0ne | +| main.rs:812:13:812:22 | test_alias | main.rs:812:13:812:22 | test_alias | +| main.rs:814:13:814:16 | test | main.rs:814:13:814:16 | test | +| main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | +| main.rs:825:18:825:18 | x | main.rs:825:18:825:18 | x | +| main.rs:838:9:838:9 | x | main.rs:838:9:838:9 | x | +| main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | read | main.rs:5:14:5:14 | s | main.rs:5:14:5:14 | s | main.rs:7:20:7:20 | s | | main.rs:10:14:10:14 | i | main.rs:10:14:10:14 | i | main.rs:12:20:12:20 | i | @@ -233,192 +245,206 @@ read | main.rs:100:9:100:9 | x | main.rs:100:9:100:9 | x | main.rs:105:13:105:13 | x | | main.rs:101:14:101:14 | x | main.rs:101:14:101:14 | x | main.rs:109:15:109:15 | x | | main.rs:104:13:104:13 | x | main.rs:104:13:104:13 | x | main.rs:106:19:106:19 | x | -| main.rs:113:9:113:10 | s1 | main.rs:113:9:113:10 | s1 | main.rs:116:11:116:12 | s1 | -| main.rs:115:24:115:25 | s2 | main.rs:115:24:115:25 | s2 | main.rs:117:19:117:20 | s2 | -| main.rs:122:9:122:10 | x6 | main.rs:122:9:122:10 | x6 | main.rs:125:11:125:12 | x6 | -| main.rs:123:9:123:10 | y1 | main.rs:123:9:123:10 | y1 | main.rs:135:15:135:16 | y1 | -| main.rs:127:14:127:15 | y1 | main.rs:127:14:127:15 | y1 | main.rs:130:23:130:24 | y1 | -| main.rs:139:9:139:15 | numbers | main.rs:139:9:139:15 | numbers | main.rs:141:11:141:17 | numbers | -| main.rs:139:9:139:15 | numbers | main.rs:139:9:139:15 | numbers | main.rs:156:11:156:17 | numbers | -| main.rs:144:13:144:17 | first | main.rs:144:13:144:17 | first | main.rs:150:23:150:27 | first | -| main.rs:146:13:146:17 | third | main.rs:146:13:146:17 | third | main.rs:151:23:151:27 | third | -| main.rs:148:13:148:17 | fifth | main.rs:148:13:148:17 | fifth | main.rs:152:23:152:27 | fifth | -| main.rs:159:13:159:17 | first | main.rs:159:13:159:17 | first | main.rs:163:23:163:27 | first | -| main.rs:161:13:161:16 | last | main.rs:161:13:161:16 | last | main.rs:164:23:164:26 | last | -| main.rs:170:9:170:10 | p2 | main.rs:170:9:170:10 | p2 | main.rs:172:11:172:12 | p2 | -| main.rs:174:16:174:17 | x7 | main.rs:174:16:174:17 | x7 | main.rs:175:24:175:25 | x7 | -| main.rs:184:9:184:11 | msg | main.rs:184:9:184:11 | msg | main.rs:186:11:186:13 | msg | -| main.rs:189:17:189:27 | id_variable | main.rs:189:17:189:27 | id_variable | main.rs:190:24:190:34 | id_variable | -| main.rs:194:26:194:27 | id | main.rs:194:26:194:27 | id | main.rs:197:23:197:24 | id | -| main.rs:208:9:208:14 | either | main.rs:208:9:208:14 | either | main.rs:209:11:209:16 | either | -| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:9:210:44 | a3 | main.rs:211:26:211:27 | a3 | -| main.rs:222:9:222:10 | tv | main.rs:222:9:222:10 | tv | main.rs:223:11:223:12 | tv | -| main.rs:222:9:222:10 | tv | main.rs:222:9:222:10 | tv | main.rs:227:11:227:12 | tv | -| main.rs:222:9:222:10 | tv | main.rs:222:9:222:10 | tv | main.rs:231:11:231:12 | tv | -| main.rs:224:9:224:81 | SSA phi(a4) | main.rs:224:9:224:81 | a4 | main.rs:225:26:225:27 | a4 | -| main.rs:228:9:228:83 | SSA phi(a5) | main.rs:228:9:228:83 | a5 | main.rs:229:26:229:27 | a5 | -| main.rs:232:9:232:83 | SSA phi(a6) | main.rs:232:9:232:83 | a6 | main.rs:233:26:233:27 | a6 | -| main.rs:238:9:238:14 | either | main.rs:238:9:238:14 | either | main.rs:239:11:239:16 | either | -| main.rs:240:9:240:44 | [match(true)] SSA phi(a7) | main.rs:240:9:240:44 | a7 | main.rs:241:16:241:17 | a7 | -| main.rs:240:9:240:44 | [match(true)] SSA phi(a7) | main.rs:240:9:240:44 | a7 | main.rs:242:26:242:27 | a7 | -| main.rs:248:9:248:14 | either | main.rs:248:9:248:14 | either | main.rs:250:11:250:16 | either | -| main.rs:251:13:251:13 | e | main.rs:251:13:251:13 | e | main.rs:256:15:256:15 | e | -| main.rs:252:14:252:51 | [match(true)] SSA phi(a11) | main.rs:252:14:252:51 | a11 | main.rs:254:23:254:25 | a11 | -| main.rs:255:33:255:35 | a12 | main.rs:255:33:255:35 | a12 | main.rs:257:28:257:30 | a12 | -| main.rs:272:9:272:10 | fv | main.rs:272:9:272:10 | fv | main.rs:273:11:273:12 | fv | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:9:274:109 | a13 | main.rs:275:26:275:28 | a13 | -| main.rs:281:9:281:9 | x | main.rs:281:9:281:9 | x | main.rs:283:7:283:7 | x | -| main.rs:281:9:281:9 | x | main.rs:281:9:281:9 | x | main.rs:290:13:290:13 | x | -| main.rs:282:17:282:17 | x | main.rs:282:17:282:17 | x | main.rs:285:5:285:5 | x | -| main.rs:282:17:282:17 | x | main.rs:282:17:282:17 | x | main.rs:287:19:287:19 | x | -| main.rs:289:13:289:13 | x | main.rs:289:13:289:13 | x | main.rs:291:19:291:19 | x | -| main.rs:297:9:297:9 | x | main.rs:297:9:297:9 | x | main.rs:299:7:299:7 | x | -| main.rs:297:9:297:9 | x | main.rs:297:9:297:9 | x | main.rs:309:13:309:13 | x | -| main.rs:298:17:298:17 | x | main.rs:298:17:298:17 | x | main.rs:302:12:302:12 | x | -| main.rs:301:14:301:14 | x | main.rs:301:14:301:14 | x | main.rs:304:5:304:5 | x | -| main.rs:301:14:301:14 | x | main.rs:301:14:301:14 | x | main.rs:306:19:306:19 | x | -| main.rs:308:13:308:13 | x | main.rs:308:13:308:13 | x | main.rs:310:19:310:19 | x | +| main.rs:113:9:113:9 | s | main.rs:113:9:113:9 | s | main.rs:116:11:116:11 | s | +| main.rs:115:24:115:24 | s | main.rs:115:24:115:24 | s | main.rs:117:19:117:19 | s | +| main.rs:123:17:123:17 | x | main.rs:123:17:123:17 | x | main.rs:125:25:125:25 | x | +| main.rs:124:19:124:19 | x | main.rs:124:19:124:19 | x | main.rs:127:19:127:19 | x | +| main.rs:133:9:133:9 | x | main.rs:133:9:133:9 | x | main.rs:135:9:135:9 | x | +| main.rs:134:12:134:12 | x | main.rs:134:12:134:12 | x | main.rs:137:9:137:9 | x | +| main.rs:136:12:136:12 | x | main.rs:136:12:136:12 | x | main.rs:139:9:139:9 | x | +| main.rs:138:12:138:12 | x | main.rs:138:12:138:12 | x | main.rs:141:9:141:9 | x | +| main.rs:140:12:140:12 | x | main.rs:140:12:140:12 | x | main.rs:143:9:143:9 | x | +| main.rs:142:12:142:12 | x | main.rs:142:12:142:12 | x | main.rs:145:9:145:9 | x | +| main.rs:144:12:144:12 | x | main.rs:144:12:144:12 | x | main.rs:147:9:147:9 | x | +| main.rs:146:12:146:12 | x | main.rs:146:12:146:12 | x | main.rs:149:19:149:19 | x | +| main.rs:157:9:157:10 | x6 | main.rs:157:9:157:10 | x6 | main.rs:160:11:160:12 | x6 | +| main.rs:158:9:158:10 | y1 | main.rs:158:9:158:10 | y1 | main.rs:170:15:170:16 | y1 | +| main.rs:162:14:162:15 | y1 | main.rs:162:14:162:15 | y1 | main.rs:165:23:165:24 | y1 | +| main.rs:174:9:174:15 | numbers | main.rs:174:9:174:15 | numbers | main.rs:176:11:176:17 | numbers | +| main.rs:174:9:174:15 | numbers | main.rs:174:9:174:15 | numbers | main.rs:191:11:191:17 | numbers | +| main.rs:179:13:179:17 | first | main.rs:179:13:179:17 | first | main.rs:185:23:185:27 | first | +| main.rs:181:13:181:17 | third | main.rs:181:13:181:17 | third | main.rs:186:23:186:27 | third | +| main.rs:183:13:183:17 | fifth | main.rs:183:13:183:17 | fifth | main.rs:187:23:187:27 | fifth | +| main.rs:194:13:194:17 | first | main.rs:194:13:194:17 | first | main.rs:198:23:198:27 | first | +| main.rs:196:13:196:16 | last | main.rs:196:13:196:16 | last | main.rs:199:23:199:26 | last | +| main.rs:205:9:205:10 | p2 | main.rs:205:9:205:10 | p2 | main.rs:207:11:207:12 | p2 | +| main.rs:209:16:209:17 | x7 | main.rs:209:16:209:17 | x7 | main.rs:210:24:210:25 | x7 | +| main.rs:219:9:219:11 | msg | main.rs:219:9:219:11 | msg | main.rs:221:11:221:13 | msg | +| main.rs:224:17:224:27 | id_variable | main.rs:224:17:224:27 | id_variable | main.rs:225:24:225:34 | id_variable | +| main.rs:229:26:229:27 | id | main.rs:229:26:229:27 | id | main.rs:232:23:232:24 | id | +| main.rs:243:9:243:14 | either | main.rs:243:9:243:14 | either | main.rs:244:11:244:16 | either | +| main.rs:245:9:245:44 | SSA phi(a3) | main.rs:245:9:245:44 | a3 | main.rs:246:26:246:27 | a3 | +| main.rs:257:9:257:10 | tv | main.rs:257:9:257:10 | tv | main.rs:258:11:258:12 | tv | +| main.rs:257:9:257:10 | tv | main.rs:257:9:257:10 | tv | main.rs:262:11:262:12 | tv | +| main.rs:257:9:257:10 | tv | main.rs:257:9:257:10 | tv | main.rs:266:11:266:12 | tv | +| main.rs:259:9:259:81 | SSA phi(a4) | main.rs:259:9:259:81 | a4 | main.rs:260:26:260:27 | a4 | +| main.rs:263:9:263:83 | SSA phi(a5) | main.rs:263:9:263:83 | a5 | main.rs:264:26:264:27 | a5 | +| main.rs:267:9:267:83 | SSA phi(a6) | main.rs:267:9:267:83 | a6 | main.rs:268:26:268:27 | a6 | +| main.rs:273:9:273:14 | either | main.rs:273:9:273:14 | either | main.rs:274:11:274:16 | either | +| main.rs:275:9:275:44 | [match(true)] SSA phi(a7) | main.rs:275:9:275:44 | a7 | main.rs:276:16:276:17 | a7 | +| main.rs:275:9:275:44 | [match(true)] SSA phi(a7) | main.rs:275:9:275:44 | a7 | main.rs:277:26:277:27 | a7 | +| main.rs:283:9:283:14 | either | main.rs:283:9:283:14 | either | main.rs:285:11:285:16 | either | +| main.rs:286:13:286:13 | e | main.rs:286:13:286:13 | e | main.rs:291:15:291:15 | e | +| main.rs:287:14:287:51 | [match(true)] SSA phi(a11) | main.rs:287:14:287:51 | a11 | main.rs:289:23:289:25 | a11 | +| main.rs:290:33:290:35 | a12 | main.rs:290:33:290:35 | a12 | main.rs:292:28:292:30 | a12 | +| main.rs:307:9:307:10 | fv | main.rs:307:9:307:10 | fv | main.rs:308:11:308:12 | fv | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:9:309:109 | a13 | main.rs:310:26:310:28 | a13 | | main.rs:316:9:316:9 | x | main.rs:316:9:316:9 | x | main.rs:318:7:318:7 | x | -| main.rs:316:9:316:9 | x | main.rs:316:9:316:9 | x | main.rs:329:15:329:15 | x | -| main.rs:317:20:317:20 | x | main.rs:317:20:317:20 | x | main.rs:321:12:321:12 | x | -| main.rs:320:14:320:14 | x | main.rs:320:14:320:14 | x | main.rs:323:5:323:5 | x | -| main.rs:320:14:320:14 | x | main.rs:320:14:320:14 | x | main.rs:325:19:325:19 | x | -| main.rs:334:9:334:9 | x | main.rs:334:9:334:9 | x | main.rs:335:11:335:11 | x | -| main.rs:334:9:334:9 | x | main.rs:334:9:334:9 | x | main.rs:343:15:343:15 | x | -| main.rs:336:14:336:14 | x | main.rs:336:14:336:14 | x | main.rs:338:18:338:18 | x | -| main.rs:337:20:337:20 | x | main.rs:337:20:337:20 | x | main.rs:339:19:339:19 | x | -| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:350:7:350:7 | x | -| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:355:7:355:7 | x | -| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:359:19:359:19 | x | -| main.rs:349:16:349:16 | x | main.rs:349:16:349:16 | x | main.rs:352:19:352:19 | x | -| main.rs:354:20:354:20 | x | main.rs:354:20:354:20 | x | main.rs:357:19:357:19 | x | -| main.rs:364:9:364:9 | x | main.rs:364:9:364:9 | x | main.rs:365:11:365:11 | x | -| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | main.rs:367:20:367:20 | x | -| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | main.rs:374:11:374:11 | x | -| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y | -| main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y | main.rs:378:26:378:26 | y | -| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | main.rs:390:15:390:16 | a8 | -| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | main.rs:391:15:391:16 | b3 | -| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | main.rs:392:15:392:16 | c1 | -| main.rs:395:20:395:55 | SSA phi(a9) | main.rs:395:20:395:55 | a9 | main.rs:397:15:397:16 | a9 | -| main.rs:402:13:402:15 | a10 | main.rs:402:13:402:15 | a10 | main.rs:406:15:406:17 | a10 | -| main.rs:402:13:402:15 | a10 | main.rs:402:13:402:15 | a10 | main.rs:415:9:415:11 | a10 | -| main.rs:403:13:403:14 | b4 | main.rs:403:13:403:14 | b4 | main.rs:407:15:407:16 | b4 | -| main.rs:403:13:403:14 | b4 | main.rs:403:13:403:14 | b4 | main.rs:416:9:416:10 | b4 | -| main.rs:404:13:404:14 | c2 | main.rs:404:13:404:14 | c2 | main.rs:408:15:408:16 | c2 | -| main.rs:404:13:404:14 | c2 | main.rs:404:13:404:14 | c2 | main.rs:417:9:417:10 | c2 | -| main.rs:411:9:411:10 | c2 | main.rs:404:13:404:14 | c2 | main.rs:421:15:421:16 | c2 | -| main.rs:412:9:412:10 | b4 | main.rs:403:13:403:14 | b4 | main.rs:420:15:420:16 | b4 | -| main.rs:412:9:412:10 | b4 | main.rs:403:13:403:14 | b4 | main.rs:434:15:434:16 | b4 | -| main.rs:413:9:413:11 | a10 | main.rs:402:13:402:15 | a10 | main.rs:419:15:419:17 | a10 | -| main.rs:413:9:413:11 | a10 | main.rs:402:13:402:15 | a10 | main.rs:433:15:433:17 | a10 | -| main.rs:425:13:425:15 | a10 | main.rs:425:13:425:15 | a10 | main.rs:428:23:428:25 | a10 | -| main.rs:426:13:426:14 | b4 | main.rs:426:13:426:14 | b4 | main.rs:429:23:429:24 | b4 | -| main.rs:438:9:438:23 | example_closure | main.rs:438:9:438:23 | example_closure | main.rs:442:9:442:23 | example_closure | -| main.rs:439:10:439:10 | x | main.rs:439:10:439:10 | x | main.rs:440:9:440:9 | x | -| main.rs:441:9:441:10 | n1 | main.rs:441:9:441:10 | n1 | main.rs:443:15:443:16 | n1 | -| main.rs:446:9:446:26 | immutable_variable | main.rs:446:9:446:26 | immutable_variable | main.rs:450:9:450:26 | immutable_variable | -| main.rs:447:6:447:6 | x | main.rs:447:6:447:6 | x | main.rs:448:9:448:9 | x | -| main.rs:449:9:449:10 | n2 | main.rs:449:9:449:10 | n2 | main.rs:451:15:451:16 | n2 | -| main.rs:456:9:456:9 | f | main.rs:456:9:456:9 | f | main.rs:459:15:459:15 | f | -| main.rs:456:9:456:9 | f | main.rs:456:9:456:9 | f | main.rs:466:15:466:15 | f | -| main.rs:457:10:457:10 | x | main.rs:457:10:457:10 | x | main.rs:458:9:458:9 | x | -| main.rs:461:10:461:10 | x | main.rs:461:10:461:10 | x | main.rs:463:9:463:9 | x | -| main.rs:470:14:470:14 | x | main.rs:470:14:470:14 | x | main.rs:472:17:472:17 | x | -| main.rs:479:13:479:13 | f | main.rs:479:13:479:13 | f | main.rs:482:19:482:19 | f | -| main.rs:480:14:480:14 | x | main.rs:480:14:480:14 | x | main.rs:481:13:481:13 | x | -| main.rs:487:9:487:9 | v | main.rs:487:9:487:9 | v | main.rs:490:12:490:12 | v | -| main.rs:489:9:489:12 | text | main.rs:489:9:489:12 | text | main.rs:491:19:491:22 | text | -| main.rs:496:13:496:13 | a | main.rs:496:13:496:13 | a | main.rs:497:5:497:5 | a | -| main.rs:497:5:497:5 | a | main.rs:496:13:496:13 | a | main.rs:498:15:498:15 | a | -| main.rs:497:5:497:5 | a | main.rs:496:13:496:13 | a | main.rs:499:11:499:11 | a | -| main.rs:499:6:499:11 | &mut a | main.rs:496:13:496:13 | a | main.rs:500:15:500:15 | a | -| main.rs:504:13:504:13 | i | main.rs:504:13:504:13 | i | main.rs:506:14:506:14 | i | -| main.rs:505:9:505:13 | ref_i | main.rs:505:9:505:13 | ref_i | main.rs:507:6:507:10 | ref_i | -| main.rs:506:9:506:14 | &mut i | main.rs:504:13:504:13 | i | main.rs:508:15:508:15 | i | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | main.rs:512:6:512:6 | x | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | main.rs:513:10:513:10 | x | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | main.rs:514:10:514:10 | x | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | main.rs:515:12:515:12 | x | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | main.rs:519:6:519:6 | x | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | main.rs:520:10:520:10 | x | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | main.rs:521:10:521:10 | x | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | main.rs:523:9:523:9 | x | -| main.rs:518:38:518:38 | y | main.rs:518:38:518:38 | y | main.rs:522:6:522:6 | y | -| main.rs:527:13:527:13 | x | main.rs:527:13:527:13 | x | main.rs:529:27:529:27 | x | -| main.rs:528:9:528:9 | y | main.rs:528:9:528:9 | y | main.rs:530:6:530:6 | y | -| main.rs:529:22:529:27 | &mut x | main.rs:527:13:527:13 | x | main.rs:533:15:533:15 | x | -| main.rs:529:22:529:27 | &mut x | main.rs:527:13:527:13 | x | main.rs:537:19:537:19 | x | -| main.rs:535:13:535:13 | z | main.rs:535:13:535:13 | z | main.rs:539:14:539:14 | z | -| main.rs:536:9:536:9 | w | main.rs:536:9:536:9 | w | main.rs:540:9:540:9 | w | -| main.rs:536:9:536:9 | w | main.rs:536:9:536:9 | w | main.rs:542:7:542:7 | w | -| main.rs:539:9:539:14 | &mut z | main.rs:535:13:535:13 | z | main.rs:545:15:545:15 | z | -| main.rs:549:13:549:13 | x | main.rs:549:13:549:13 | x | main.rs:551:14:551:14 | x | -| main.rs:550:9:550:9 | y | main.rs:550:9:550:9 | y | main.rs:552:6:552:6 | y | -| main.rs:551:9:551:14 | &mut x | main.rs:549:13:549:13 | x | main.rs:553:15:553:15 | x | -| main.rs:557:9:557:9 | x | main.rs:557:9:557:9 | x | main.rs:564:15:564:15 | x | -| main.rs:560:9:560:11 | cap | main.rs:560:9:560:11 | cap | main.rs:563:5:563:7 | cap | -| main.rs:560:15:562:5 | x | main.rs:557:9:557:9 | x | main.rs:561:19:561:19 | x | -| main.rs:568:13:568:13 | x | main.rs:568:13:568:13 | x | main.rs:575:15:575:15 | x | -| main.rs:571:9:571:16 | closure1 | main.rs:571:9:571:16 | closure1 | main.rs:574:5:574:12 | closure1 | -| main.rs:571:20:573:5 | x | main.rs:568:13:568:13 | x | main.rs:572:19:572:19 | x | -| main.rs:580:13:580:20 | closure2 | main.rs:580:13:580:20 | closure2 | main.rs:583:5:583:12 | closure2 | -| main.rs:583:5:583:14 | y | main.rs:577:13:577:13 | y | main.rs:584:15:584:15 | y | -| main.rs:586:13:586:13 | z | main.rs:586:13:586:13 | z | main.rs:593:15:593:15 | z | -| main.rs:589:13:589:20 | closure3 | main.rs:589:13:589:20 | closure3 | main.rs:592:5:592:12 | closure3 | -| main.rs:589:24:591:5 | z | main.rs:586:13:586:13 | z | main.rs:590:9:590:9 | z | -| main.rs:598:9:598:13 | block | main.rs:598:9:598:13 | block | main.rs:602:5:602:9 | block | -| main.rs:602:5:602:15 | i | main.rs:597:13:597:13 | i | main.rs:603:15:603:15 | i | -| main.rs:606:8:606:8 | b | main.rs:606:8:606:8 | b | main.rs:611:16:611:16 | b | -| main.rs:607:13:607:13 | x | main.rs:607:13:607:13 | x | main.rs:608:15:608:15 | x | -| main.rs:607:13:607:13 | x | main.rs:607:13:607:13 | x | main.rs:609:15:609:15 | x | -| main.rs:611:13:620:5 | SSA phi(x) | main.rs:607:13:607:13 | x | main.rs:621:15:621:15 | x | -| main.rs:613:9:613:9 | x | main.rs:607:13:607:13 | x | main.rs:614:19:614:19 | x | -| main.rs:613:9:613:9 | x | main.rs:607:13:607:13 | x | main.rs:615:19:615:19 | x | -| main.rs:617:9:617:9 | x | main.rs:607:13:607:13 | x | main.rs:618:19:618:19 | x | -| main.rs:617:9:617:9 | x | main.rs:607:13:607:13 | x | main.rs:619:19:619:19 | x | -| main.rs:624:13:624:14 | b1 | main.rs:624:13:624:14 | b1 | main.rs:627:16:627:17 | b1 | -| main.rs:624:23:624:24 | b2 | main.rs:624:23:624:24 | b2 | main.rs:635:16:635:17 | b2 | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:629:19:629:19 | x | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:631:19:631:19 | x | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:637:19:637:19 | x | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:639:19:639:19 | x | -| main.rs:648:20:648:23 | self | main.rs:648:20:648:23 | self | main.rs:649:16:649:19 | self | -| main.rs:652:11:652:14 | self | main.rs:652:11:652:14 | self | main.rs:653:9:653:12 | self | -| main.rs:657:17:657:17 | f | main.rs:657:17:657:17 | f | main.rs:661:9:661:9 | f | -| main.rs:657:17:657:17 | f | main.rs:657:17:657:17 | f | main.rs:662:9:662:9 | f | -| main.rs:657:21:660:9 | self | main.rs:656:23:656:26 | self | main.rs:659:13:659:16 | self | -| main.rs:657:22:657:22 | n | main.rs:657:22:657:22 | n | main.rs:659:25:659:25 | n | -| main.rs:667:13:667:13 | a | main.rs:667:13:667:13 | a | main.rs:668:15:668:15 | a | -| main.rs:668:15:668:15 | a | main.rs:667:13:667:13 | a | main.rs:669:5:669:5 | a | -| main.rs:668:15:668:15 | a | main.rs:667:13:667:13 | a | main.rs:670:15:670:15 | a | -| main.rs:671:5:671:5 | a | main.rs:667:13:667:13 | a | main.rs:672:15:672:15 | a | -| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:677:15:677:15 | a | -| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:678:5:678:5 | a | -| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:679:15:679:15 | a | -| main.rs:680:5:680:5 | a | main.rs:676:13:676:13 | a | main.rs:681:15:681:15 | a | -| main.rs:685:9:685:9 | x | main.rs:685:9:685:9 | x | main.rs:686:20:686:20 | x | -| main.rs:685:9:685:9 | x | main.rs:685:9:685:9 | x | main.rs:687:15:687:15 | x | -| main.rs:689:9:689:9 | z | main.rs:689:9:689:9 | z | main.rs:690:20:690:20 | z | -| main.rs:698:17:698:20 | self | main.rs:698:17:698:20 | self | main.rs:699:10:699:13 | self | -| main.rs:704:13:704:13 | a | main.rs:704:13:704:13 | a | main.rs:705:5:705:5 | a | -| main.rs:705:5:705:5 | a | main.rs:704:13:704:13 | a | main.rs:708:15:708:15 | a | -| main.rs:726:9:726:22 | var_from_macro | main.rs:726:9:726:22 | var_from_macro | main.rs:728:15:728:28 | var_from_macro | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:9:727:21 | var_in_macro | main.rs:727:9:727:21 | var_in_macro | -| main.rs:729:9:729:20 | var_in_macro | main.rs:729:9:729:20 | var_in_macro | main.rs:735:15:735:26 | var_in_macro | -| main.rs:734:15:734:28 | var_in_macro | main.rs:734:15:734:28 | var_in_macro | main.rs:734:30:734:41 | var_in_macro | -| main.rs:740:5:740:5 | x | main.rs:739:9:739:9 | x | main.rs:741:15:741:15 | x | -| main.rs:746:13:746:15 | cap | main.rs:746:13:746:15 | cap | main.rs:752:5:752:7 | cap | -| main.rs:746:20:746:20 | b | main.rs:746:20:746:20 | b | main.rs:748:20:748:20 | b | -| main.rs:752:5:752:13 | x | main.rs:745:13:745:13 | x | main.rs:753:15:753:15 | x | -| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | main.rs:761:19:761:19 | x | -| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y | -| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | main.rs:770:17:770:20 | N0ne | -| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | main.rs:779:13:779:22 | test_alias | -| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test | -| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x | -| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:793:15:793:15 | x | -| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x | +| main.rs:316:9:316:9 | x | main.rs:316:9:316:9 | x | main.rs:325:13:325:13 | x | +| main.rs:317:17:317:17 | x | main.rs:317:17:317:17 | x | main.rs:320:5:320:5 | x | +| main.rs:317:17:317:17 | x | main.rs:317:17:317:17 | x | main.rs:322:19:322:19 | x | +| main.rs:324:13:324:13 | x | main.rs:324:13:324:13 | x | main.rs:326:19:326:19 | x | +| main.rs:332:9:332:9 | x | main.rs:332:9:332:9 | x | main.rs:334:7:334:7 | x | +| main.rs:332:9:332:9 | x | main.rs:332:9:332:9 | x | main.rs:344:13:344:13 | x | +| main.rs:333:17:333:17 | x | main.rs:333:17:333:17 | x | main.rs:337:12:337:12 | x | +| main.rs:336:14:336:14 | x | main.rs:336:14:336:14 | x | main.rs:339:5:339:5 | x | +| main.rs:336:14:336:14 | x | main.rs:336:14:336:14 | x | main.rs:341:19:341:19 | x | +| main.rs:343:13:343:13 | x | main.rs:343:13:343:13 | x | main.rs:345:19:345:19 | x | +| main.rs:351:9:351:9 | x | main.rs:351:9:351:9 | x | main.rs:353:7:353:7 | x | +| main.rs:351:9:351:9 | x | main.rs:351:9:351:9 | x | main.rs:364:15:364:15 | x | +| main.rs:352:20:352:20 | x | main.rs:352:20:352:20 | x | main.rs:356:12:356:12 | x | +| main.rs:355:14:355:14 | x | main.rs:355:14:355:14 | x | main.rs:358:5:358:5 | x | +| main.rs:355:14:355:14 | x | main.rs:355:14:355:14 | x | main.rs:360:19:360:19 | x | +| main.rs:369:9:369:9 | x | main.rs:369:9:369:9 | x | main.rs:370:11:370:11 | x | +| main.rs:369:9:369:9 | x | main.rs:369:9:369:9 | x | main.rs:378:15:378:15 | x | +| main.rs:371:14:371:14 | x | main.rs:371:14:371:14 | x | main.rs:373:18:373:18 | x | +| main.rs:372:20:372:20 | x | main.rs:372:20:372:20 | x | main.rs:374:19:374:19 | x | +| main.rs:383:9:383:9 | x | main.rs:383:9:383:9 | x | main.rs:385:7:385:7 | x | +| main.rs:383:9:383:9 | x | main.rs:383:9:383:9 | x | main.rs:390:7:390:7 | x | +| main.rs:383:9:383:9 | x | main.rs:383:9:383:9 | x | main.rs:394:19:394:19 | x | +| main.rs:384:16:384:16 | x | main.rs:384:16:384:16 | x | main.rs:387:19:387:19 | x | +| main.rs:389:20:389:20 | x | main.rs:389:20:389:20 | x | main.rs:392:19:392:19 | x | +| main.rs:399:9:399:9 | x | main.rs:399:9:399:9 | x | main.rs:400:11:400:11 | x | +| main.rs:401:18:401:18 | x | main.rs:401:18:401:18 | x | main.rs:402:20:402:20 | x | +| main.rs:408:9:408:9 | x | main.rs:408:9:408:9 | x | main.rs:409:11:409:11 | x | +| main.rs:410:14:410:14 | y | main.rs:410:14:410:14 | y | main.rs:411:16:411:16 | y | +| main.rs:410:14:410:14 | y | main.rs:410:14:410:14 | y | main.rs:413:22:413:22 | y | +| main.rs:412:22:412:22 | y | main.rs:412:22:412:22 | y | main.rs:414:26:414:26 | y | +| main.rs:420:5:420:6 | a8 | main.rs:420:5:420:6 | a8 | main.rs:426:15:426:16 | a8 | +| main.rs:422:9:422:10 | b3 | main.rs:422:9:422:10 | b3 | main.rs:427:15:427:16 | b3 | +| main.rs:423:9:423:10 | c1 | main.rs:423:9:423:10 | c1 | main.rs:428:15:428:16 | c1 | +| main.rs:431:20:431:55 | SSA phi(a9) | main.rs:431:20:431:55 | a9 | main.rs:433:15:433:16 | a9 | +| main.rs:438:13:438:15 | a10 | main.rs:438:13:438:15 | a10 | main.rs:442:15:442:17 | a10 | +| main.rs:438:13:438:15 | a10 | main.rs:438:13:438:15 | a10 | main.rs:451:9:451:11 | a10 | +| main.rs:439:13:439:14 | b4 | main.rs:439:13:439:14 | b4 | main.rs:443:15:443:16 | b4 | +| main.rs:439:13:439:14 | b4 | main.rs:439:13:439:14 | b4 | main.rs:452:9:452:10 | b4 | +| main.rs:440:13:440:14 | c2 | main.rs:440:13:440:14 | c2 | main.rs:444:15:444:16 | c2 | +| main.rs:440:13:440:14 | c2 | main.rs:440:13:440:14 | c2 | main.rs:453:9:453:10 | c2 | +| main.rs:447:9:447:10 | c2 | main.rs:440:13:440:14 | c2 | main.rs:457:15:457:16 | c2 | +| main.rs:448:9:448:10 | b4 | main.rs:439:13:439:14 | b4 | main.rs:456:15:456:16 | b4 | +| main.rs:448:9:448:10 | b4 | main.rs:439:13:439:14 | b4 | main.rs:470:15:470:16 | b4 | +| main.rs:449:9:449:11 | a10 | main.rs:438:13:438:15 | a10 | main.rs:455:15:455:17 | a10 | +| main.rs:449:9:449:11 | a10 | main.rs:438:13:438:15 | a10 | main.rs:469:15:469:17 | a10 | +| main.rs:461:13:461:15 | a10 | main.rs:461:13:461:15 | a10 | main.rs:464:23:464:25 | a10 | +| main.rs:462:13:462:14 | b4 | main.rs:462:13:462:14 | b4 | main.rs:465:23:465:24 | b4 | +| main.rs:474:9:474:23 | example_closure | main.rs:474:9:474:23 | example_closure | main.rs:478:9:478:23 | example_closure | +| main.rs:475:10:475:10 | x | main.rs:475:10:475:10 | x | main.rs:476:9:476:9 | x | +| main.rs:477:9:477:10 | n1 | main.rs:477:9:477:10 | n1 | main.rs:479:15:479:16 | n1 | +| main.rs:482:9:482:26 | immutable_variable | main.rs:482:9:482:26 | immutable_variable | main.rs:486:9:486:26 | immutable_variable | +| main.rs:483:6:483:6 | x | main.rs:483:6:483:6 | x | main.rs:484:9:484:9 | x | +| main.rs:485:9:485:10 | n2 | main.rs:485:9:485:10 | n2 | main.rs:487:15:487:16 | n2 | +| main.rs:492:9:492:9 | f | main.rs:492:9:492:9 | f | main.rs:495:15:495:15 | f | +| main.rs:492:9:492:9 | f | main.rs:492:9:492:9 | f | main.rs:502:15:502:15 | f | +| main.rs:493:10:493:10 | x | main.rs:493:10:493:10 | x | main.rs:494:9:494:9 | x | +| main.rs:497:10:497:10 | x | main.rs:497:10:497:10 | x | main.rs:499:9:499:9 | x | +| main.rs:506:14:506:14 | x | main.rs:506:14:506:14 | x | main.rs:508:17:508:17 | x | +| main.rs:515:13:515:13 | f | main.rs:515:13:515:13 | f | main.rs:518:19:518:19 | f | +| main.rs:516:14:516:14 | x | main.rs:516:14:516:14 | x | main.rs:517:13:517:13 | x | +| main.rs:523:9:523:9 | v | main.rs:523:9:523:9 | v | main.rs:526:12:526:12 | v | +| main.rs:525:9:525:12 | text | main.rs:525:9:525:12 | text | main.rs:527:19:527:22 | text | +| main.rs:532:13:532:13 | a | main.rs:532:13:532:13 | a | main.rs:533:5:533:5 | a | +| main.rs:533:5:533:5 | a | main.rs:532:13:532:13 | a | main.rs:534:15:534:15 | a | +| main.rs:533:5:533:5 | a | main.rs:532:13:532:13 | a | main.rs:535:11:535:11 | a | +| main.rs:535:6:535:11 | &mut a | main.rs:532:13:532:13 | a | main.rs:536:15:536:15 | a | +| main.rs:540:13:540:13 | i | main.rs:540:13:540:13 | i | main.rs:542:14:542:14 | i | +| main.rs:541:9:541:13 | ref_i | main.rs:541:9:541:13 | ref_i | main.rs:543:6:543:10 | ref_i | +| main.rs:542:9:542:14 | &mut i | main.rs:540:13:540:13 | i | main.rs:544:15:544:15 | i | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | main.rs:548:6:548:6 | x | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | main.rs:549:10:549:10 | x | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | main.rs:550:10:550:10 | x | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | main.rs:551:12:551:12 | x | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | main.rs:555:6:555:6 | x | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | main.rs:556:10:556:10 | x | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | main.rs:557:10:557:10 | x | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | main.rs:559:9:559:9 | x | +| main.rs:554:38:554:38 | y | main.rs:554:38:554:38 | y | main.rs:558:6:558:6 | y | +| main.rs:563:13:563:13 | x | main.rs:563:13:563:13 | x | main.rs:565:27:565:27 | x | +| main.rs:564:9:564:9 | y | main.rs:564:9:564:9 | y | main.rs:566:6:566:6 | y | +| main.rs:565:22:565:27 | &mut x | main.rs:563:13:563:13 | x | main.rs:569:15:569:15 | x | +| main.rs:565:22:565:27 | &mut x | main.rs:563:13:563:13 | x | main.rs:573:19:573:19 | x | +| main.rs:571:13:571:13 | z | main.rs:571:13:571:13 | z | main.rs:575:14:575:14 | z | +| main.rs:572:9:572:9 | w | main.rs:572:9:572:9 | w | main.rs:576:9:576:9 | w | +| main.rs:572:9:572:9 | w | main.rs:572:9:572:9 | w | main.rs:578:7:578:7 | w | +| main.rs:575:9:575:14 | &mut z | main.rs:571:13:571:13 | z | main.rs:581:15:581:15 | z | +| main.rs:585:13:585:13 | x | main.rs:585:13:585:13 | x | main.rs:587:14:587:14 | x | +| main.rs:586:9:586:9 | y | main.rs:586:9:586:9 | y | main.rs:588:6:588:6 | y | +| main.rs:587:9:587:14 | &mut x | main.rs:585:13:585:13 | x | main.rs:589:15:589:15 | x | +| main.rs:593:9:593:9 | x | main.rs:593:9:593:9 | x | main.rs:600:15:600:15 | x | +| main.rs:596:9:596:11 | cap | main.rs:596:9:596:11 | cap | main.rs:599:5:599:7 | cap | +| main.rs:596:15:598:5 | x | main.rs:593:9:593:9 | x | main.rs:597:19:597:19 | x | +| main.rs:604:13:604:13 | x | main.rs:604:13:604:13 | x | main.rs:611:15:611:15 | x | +| main.rs:607:9:607:16 | closure1 | main.rs:607:9:607:16 | closure1 | main.rs:610:5:610:12 | closure1 | +| main.rs:607:20:609:5 | x | main.rs:604:13:604:13 | x | main.rs:608:19:608:19 | x | +| main.rs:616:13:616:20 | closure2 | main.rs:616:13:616:20 | closure2 | main.rs:619:5:619:12 | closure2 | +| main.rs:619:5:619:14 | y | main.rs:613:13:613:13 | y | main.rs:620:15:620:15 | y | +| main.rs:622:13:622:13 | z | main.rs:622:13:622:13 | z | main.rs:629:15:629:15 | z | +| main.rs:625:13:625:20 | closure3 | main.rs:625:13:625:20 | closure3 | main.rs:628:5:628:12 | closure3 | +| main.rs:625:24:627:5 | z | main.rs:622:13:622:13 | z | main.rs:626:9:626:9 | z | +| main.rs:634:9:634:13 | block | main.rs:634:9:634:13 | block | main.rs:638:5:638:9 | block | +| main.rs:638:5:638:15 | i | main.rs:633:13:633:13 | i | main.rs:639:15:639:15 | i | +| main.rs:642:8:642:8 | b | main.rs:642:8:642:8 | b | main.rs:647:16:647:16 | b | +| main.rs:643:13:643:13 | x | main.rs:643:13:643:13 | x | main.rs:644:15:644:15 | x | +| main.rs:643:13:643:13 | x | main.rs:643:13:643:13 | x | main.rs:645:15:645:15 | x | +| main.rs:647:13:656:5 | SSA phi(x) | main.rs:643:13:643:13 | x | main.rs:657:15:657:15 | x | +| main.rs:649:9:649:9 | x | main.rs:643:13:643:13 | x | main.rs:650:19:650:19 | x | +| main.rs:649:9:649:9 | x | main.rs:643:13:643:13 | x | main.rs:651:19:651:19 | x | +| main.rs:653:9:653:9 | x | main.rs:643:13:643:13 | x | main.rs:654:19:654:19 | x | +| main.rs:653:9:653:9 | x | main.rs:643:13:643:13 | x | main.rs:655:19:655:19 | x | +| main.rs:660:13:660:14 | b1 | main.rs:660:13:660:14 | b1 | main.rs:663:16:663:17 | b1 | +| main.rs:660:23:660:24 | b2 | main.rs:660:23:660:24 | b2 | main.rs:671:16:671:17 | b2 | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:665:19:665:19 | x | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:667:19:667:19 | x | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:673:19:673:19 | x | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:675:19:675:19 | x | +| main.rs:684:20:684:23 | self | main.rs:684:20:684:23 | self | main.rs:685:16:685:19 | self | +| main.rs:688:11:688:14 | self | main.rs:688:11:688:14 | self | main.rs:689:9:689:12 | self | +| main.rs:693:17:693:17 | f | main.rs:693:17:693:17 | f | main.rs:697:9:697:9 | f | +| main.rs:693:17:693:17 | f | main.rs:693:17:693:17 | f | main.rs:698:9:698:9 | f | +| main.rs:693:21:696:9 | self | main.rs:692:23:692:26 | self | main.rs:695:13:695:16 | self | +| main.rs:693:22:693:22 | n | main.rs:693:22:693:22 | n | main.rs:695:25:695:25 | n | +| main.rs:703:13:703:13 | a | main.rs:703:13:703:13 | a | main.rs:704:15:704:15 | a | +| main.rs:704:15:704:15 | a | main.rs:703:13:703:13 | a | main.rs:705:5:705:5 | a | +| main.rs:704:15:704:15 | a | main.rs:703:13:703:13 | a | main.rs:706:15:706:15 | a | +| main.rs:707:5:707:5 | a | main.rs:703:13:703:13 | a | main.rs:708:15:708:15 | a | +| main.rs:712:13:712:13 | a | main.rs:712:13:712:13 | a | main.rs:713:15:713:15 | a | +| main.rs:712:13:712:13 | a | main.rs:712:13:712:13 | a | main.rs:714:5:714:5 | a | +| main.rs:712:13:712:13 | a | main.rs:712:13:712:13 | a | main.rs:715:15:715:15 | a | +| main.rs:716:5:716:5 | a | main.rs:712:13:712:13 | a | main.rs:717:15:717:15 | a | +| main.rs:721:9:721:9 | x | main.rs:721:9:721:9 | x | main.rs:722:20:722:20 | x | +| main.rs:721:9:721:9 | x | main.rs:721:9:721:9 | x | main.rs:723:15:723:15 | x | +| main.rs:725:9:725:9 | z | main.rs:725:9:725:9 | z | main.rs:726:20:726:20 | z | +| main.rs:734:17:734:20 | self | main.rs:734:17:734:20 | self | main.rs:735:10:735:13 | self | +| main.rs:740:13:740:13 | a | main.rs:740:13:740:13 | a | main.rs:741:5:741:5 | a | +| main.rs:741:5:741:5 | a | main.rs:740:13:740:13 | a | main.rs:744:15:744:15 | a | +| main.rs:762:9:762:22 | var_from_macro | main.rs:762:9:762:22 | var_from_macro | main.rs:764:15:764:28 | var_from_macro | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:9:763:21 | var_in_macro | main.rs:763:9:763:21 | var_in_macro | +| main.rs:765:9:765:20 | var_in_macro | main.rs:765:9:765:20 | var_in_macro | main.rs:771:15:771:26 | var_in_macro | +| main.rs:770:15:770:28 | var_in_macro | main.rs:770:15:770:28 | var_in_macro | main.rs:770:30:770:41 | var_in_macro | +| main.rs:776:5:776:5 | x | main.rs:775:9:775:9 | x | main.rs:777:15:777:15 | x | +| main.rs:782:13:782:15 | cap | main.rs:782:13:782:15 | cap | main.rs:788:5:788:7 | cap | +| main.rs:782:20:782:20 | b | main.rs:782:20:782:20 | b | main.rs:784:20:784:20 | b | +| main.rs:788:5:788:13 | x | main.rs:781:13:781:13 | x | main.rs:789:15:789:15 | x | +| main.rs:795:13:795:13 | x | main.rs:795:13:795:13 | x | main.rs:797:19:797:19 | x | +| main.rs:796:13:796:13 | y | main.rs:796:13:796:13 | y | main.rs:804:15:804:15 | y | +| main.rs:805:13:805:16 | N0ne | main.rs:805:13:805:16 | N0ne | main.rs:806:17:806:20 | N0ne | +| main.rs:812:13:812:22 | test_alias | main.rs:812:13:812:22 | test_alias | main.rs:815:13:815:22 | test_alias | +| main.rs:814:13:814:16 | test | main.rs:814:13:814:16 | test | main.rs:816:9:816:12 | test | +| main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | main.rs:824:15:824:15 | x | +| main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | main.rs:829:15:829:15 | x | +| main.rs:825:18:825:18 | x | main.rs:825:18:825:18 | x | main.rs:826:20:826:20 | x | +| main.rs:838:9:838:9 | x | main.rs:838:9:838:9 | x | main.rs:845:19:845:19 | x | +| main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | main.rs:841:9:841:9 | x | +| main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | main.rs:843:19:843:19 | x | firstRead | main.rs:5:14:5:14 | s | main.rs:5:14:5:14 | s | main.rs:7:20:7:20 | s | | main.rs:10:14:10:14 | i | main.rs:10:14:10:14 | i | main.rs:12:20:12:20 | i | @@ -445,273 +471,287 @@ firstRead | main.rs:100:9:100:9 | x | main.rs:100:9:100:9 | x | main.rs:102:7:102:7 | x | | main.rs:101:14:101:14 | x | main.rs:101:14:101:14 | x | main.rs:109:15:109:15 | x | | main.rs:104:13:104:13 | x | main.rs:104:13:104:13 | x | main.rs:106:19:106:19 | x | -| main.rs:113:9:113:10 | s1 | main.rs:113:9:113:10 | s1 | main.rs:116:11:116:12 | s1 | -| main.rs:115:24:115:25 | s2 | main.rs:115:24:115:25 | s2 | main.rs:117:19:117:20 | s2 | -| main.rs:122:9:122:10 | x6 | main.rs:122:9:122:10 | x6 | main.rs:125:11:125:12 | x6 | -| main.rs:123:9:123:10 | y1 | main.rs:123:9:123:10 | y1 | main.rs:135:15:135:16 | y1 | -| main.rs:127:14:127:15 | y1 | main.rs:127:14:127:15 | y1 | main.rs:130:23:130:24 | y1 | -| main.rs:139:9:139:15 | numbers | main.rs:139:9:139:15 | numbers | main.rs:141:11:141:17 | numbers | -| main.rs:144:13:144:17 | first | main.rs:144:13:144:17 | first | main.rs:150:23:150:27 | first | -| main.rs:146:13:146:17 | third | main.rs:146:13:146:17 | third | main.rs:151:23:151:27 | third | -| main.rs:148:13:148:17 | fifth | main.rs:148:13:148:17 | fifth | main.rs:152:23:152:27 | fifth | -| main.rs:159:13:159:17 | first | main.rs:159:13:159:17 | first | main.rs:163:23:163:27 | first | -| main.rs:161:13:161:16 | last | main.rs:161:13:161:16 | last | main.rs:164:23:164:26 | last | -| main.rs:170:9:170:10 | p2 | main.rs:170:9:170:10 | p2 | main.rs:172:11:172:12 | p2 | -| main.rs:174:16:174:17 | x7 | main.rs:174:16:174:17 | x7 | main.rs:175:24:175:25 | x7 | -| main.rs:184:9:184:11 | msg | main.rs:184:9:184:11 | msg | main.rs:186:11:186:13 | msg | -| main.rs:189:17:189:27 | id_variable | main.rs:189:17:189:27 | id_variable | main.rs:190:24:190:34 | id_variable | -| main.rs:194:26:194:27 | id | main.rs:194:26:194:27 | id | main.rs:197:23:197:24 | id | -| main.rs:208:9:208:14 | either | main.rs:208:9:208:14 | either | main.rs:209:11:209:16 | either | -| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:9:210:44 | a3 | main.rs:211:26:211:27 | a3 | -| main.rs:222:9:222:10 | tv | main.rs:222:9:222:10 | tv | main.rs:223:11:223:12 | tv | -| main.rs:224:9:224:81 | SSA phi(a4) | main.rs:224:9:224:81 | a4 | main.rs:225:26:225:27 | a4 | -| main.rs:228:9:228:83 | SSA phi(a5) | main.rs:228:9:228:83 | a5 | main.rs:229:26:229:27 | a5 | -| main.rs:232:9:232:83 | SSA phi(a6) | main.rs:232:9:232:83 | a6 | main.rs:233:26:233:27 | a6 | -| main.rs:238:9:238:14 | either | main.rs:238:9:238:14 | either | main.rs:239:11:239:16 | either | -| main.rs:240:9:240:44 | [match(true)] SSA phi(a7) | main.rs:240:9:240:44 | a7 | main.rs:241:16:241:17 | a7 | -| main.rs:248:9:248:14 | either | main.rs:248:9:248:14 | either | main.rs:250:11:250:16 | either | -| main.rs:251:13:251:13 | e | main.rs:251:13:251:13 | e | main.rs:256:15:256:15 | e | -| main.rs:252:14:252:51 | [match(true)] SSA phi(a11) | main.rs:252:14:252:51 | a11 | main.rs:254:23:254:25 | a11 | -| main.rs:255:33:255:35 | a12 | main.rs:255:33:255:35 | a12 | main.rs:257:28:257:30 | a12 | -| main.rs:272:9:272:10 | fv | main.rs:272:9:272:10 | fv | main.rs:273:11:273:12 | fv | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:9:274:109 | a13 | main.rs:275:26:275:28 | a13 | -| main.rs:281:9:281:9 | x | main.rs:281:9:281:9 | x | main.rs:283:7:283:7 | x | -| main.rs:282:17:282:17 | x | main.rs:282:17:282:17 | x | main.rs:285:5:285:5 | x | -| main.rs:289:13:289:13 | x | main.rs:289:13:289:13 | x | main.rs:291:19:291:19 | x | -| main.rs:297:9:297:9 | x | main.rs:297:9:297:9 | x | main.rs:299:7:299:7 | x | -| main.rs:298:17:298:17 | x | main.rs:298:17:298:17 | x | main.rs:302:12:302:12 | x | -| main.rs:301:14:301:14 | x | main.rs:301:14:301:14 | x | main.rs:304:5:304:5 | x | -| main.rs:308:13:308:13 | x | main.rs:308:13:308:13 | x | main.rs:310:19:310:19 | x | +| main.rs:113:9:113:9 | s | main.rs:113:9:113:9 | s | main.rs:116:11:116:11 | s | +| main.rs:115:24:115:24 | s | main.rs:115:24:115:24 | s | main.rs:117:19:117:19 | s | +| main.rs:123:17:123:17 | x | main.rs:123:17:123:17 | x | main.rs:125:25:125:25 | x | +| main.rs:124:19:124:19 | x | main.rs:124:19:124:19 | x | main.rs:127:19:127:19 | x | +| main.rs:133:9:133:9 | x | main.rs:133:9:133:9 | x | main.rs:135:9:135:9 | x | +| main.rs:134:12:134:12 | x | main.rs:134:12:134:12 | x | main.rs:137:9:137:9 | x | +| main.rs:136:12:136:12 | x | main.rs:136:12:136:12 | x | main.rs:139:9:139:9 | x | +| main.rs:138:12:138:12 | x | main.rs:138:12:138:12 | x | main.rs:141:9:141:9 | x | +| main.rs:140:12:140:12 | x | main.rs:140:12:140:12 | x | main.rs:143:9:143:9 | x | +| main.rs:142:12:142:12 | x | main.rs:142:12:142:12 | x | main.rs:145:9:145:9 | x | +| main.rs:144:12:144:12 | x | main.rs:144:12:144:12 | x | main.rs:147:9:147:9 | x | +| main.rs:146:12:146:12 | x | main.rs:146:12:146:12 | x | main.rs:149:19:149:19 | x | +| main.rs:157:9:157:10 | x6 | main.rs:157:9:157:10 | x6 | main.rs:160:11:160:12 | x6 | +| main.rs:158:9:158:10 | y1 | main.rs:158:9:158:10 | y1 | main.rs:170:15:170:16 | y1 | +| main.rs:162:14:162:15 | y1 | main.rs:162:14:162:15 | y1 | main.rs:165:23:165:24 | y1 | +| main.rs:174:9:174:15 | numbers | main.rs:174:9:174:15 | numbers | main.rs:176:11:176:17 | numbers | +| main.rs:179:13:179:17 | first | main.rs:179:13:179:17 | first | main.rs:185:23:185:27 | first | +| main.rs:181:13:181:17 | third | main.rs:181:13:181:17 | third | main.rs:186:23:186:27 | third | +| main.rs:183:13:183:17 | fifth | main.rs:183:13:183:17 | fifth | main.rs:187:23:187:27 | fifth | +| main.rs:194:13:194:17 | first | main.rs:194:13:194:17 | first | main.rs:198:23:198:27 | first | +| main.rs:196:13:196:16 | last | main.rs:196:13:196:16 | last | main.rs:199:23:199:26 | last | +| main.rs:205:9:205:10 | p2 | main.rs:205:9:205:10 | p2 | main.rs:207:11:207:12 | p2 | +| main.rs:209:16:209:17 | x7 | main.rs:209:16:209:17 | x7 | main.rs:210:24:210:25 | x7 | +| main.rs:219:9:219:11 | msg | main.rs:219:9:219:11 | msg | main.rs:221:11:221:13 | msg | +| main.rs:224:17:224:27 | id_variable | main.rs:224:17:224:27 | id_variable | main.rs:225:24:225:34 | id_variable | +| main.rs:229:26:229:27 | id | main.rs:229:26:229:27 | id | main.rs:232:23:232:24 | id | +| main.rs:243:9:243:14 | either | main.rs:243:9:243:14 | either | main.rs:244:11:244:16 | either | +| main.rs:245:9:245:44 | SSA phi(a3) | main.rs:245:9:245:44 | a3 | main.rs:246:26:246:27 | a3 | +| main.rs:257:9:257:10 | tv | main.rs:257:9:257:10 | tv | main.rs:258:11:258:12 | tv | +| main.rs:259:9:259:81 | SSA phi(a4) | main.rs:259:9:259:81 | a4 | main.rs:260:26:260:27 | a4 | +| main.rs:263:9:263:83 | SSA phi(a5) | main.rs:263:9:263:83 | a5 | main.rs:264:26:264:27 | a5 | +| main.rs:267:9:267:83 | SSA phi(a6) | main.rs:267:9:267:83 | a6 | main.rs:268:26:268:27 | a6 | +| main.rs:273:9:273:14 | either | main.rs:273:9:273:14 | either | main.rs:274:11:274:16 | either | +| main.rs:275:9:275:44 | [match(true)] SSA phi(a7) | main.rs:275:9:275:44 | a7 | main.rs:276:16:276:17 | a7 | +| main.rs:283:9:283:14 | either | main.rs:283:9:283:14 | either | main.rs:285:11:285:16 | either | +| main.rs:286:13:286:13 | e | main.rs:286:13:286:13 | e | main.rs:291:15:291:15 | e | +| main.rs:287:14:287:51 | [match(true)] SSA phi(a11) | main.rs:287:14:287:51 | a11 | main.rs:289:23:289:25 | a11 | +| main.rs:290:33:290:35 | a12 | main.rs:290:33:290:35 | a12 | main.rs:292:28:292:30 | a12 | +| main.rs:307:9:307:10 | fv | main.rs:307:9:307:10 | fv | main.rs:308:11:308:12 | fv | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:9:309:109 | a13 | main.rs:310:26:310:28 | a13 | | main.rs:316:9:316:9 | x | main.rs:316:9:316:9 | x | main.rs:318:7:318:7 | x | -| main.rs:317:20:317:20 | x | main.rs:317:20:317:20 | x | main.rs:321:12:321:12 | x | -| main.rs:320:14:320:14 | x | main.rs:320:14:320:14 | x | main.rs:323:5:323:5 | x | -| main.rs:334:9:334:9 | x | main.rs:334:9:334:9 | x | main.rs:335:11:335:11 | x | -| main.rs:336:14:336:14 | x | main.rs:336:14:336:14 | x | main.rs:338:18:338:18 | x | -| main.rs:337:20:337:20 | x | main.rs:337:20:337:20 | x | main.rs:339:19:339:19 | x | -| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:350:7:350:7 | x | -| main.rs:349:16:349:16 | x | main.rs:349:16:349:16 | x | main.rs:352:19:352:19 | x | -| main.rs:354:20:354:20 | x | main.rs:354:20:354:20 | x | main.rs:357:19:357:19 | x | -| main.rs:364:9:364:9 | x | main.rs:364:9:364:9 | x | main.rs:365:11:365:11 | x | -| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | main.rs:367:20:367:20 | x | -| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | main.rs:374:11:374:11 | x | -| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y | -| main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y | main.rs:378:26:378:26 | y | -| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | main.rs:390:15:390:16 | a8 | -| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | main.rs:391:15:391:16 | b3 | -| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | main.rs:392:15:392:16 | c1 | -| main.rs:395:20:395:55 | SSA phi(a9) | main.rs:395:20:395:55 | a9 | main.rs:397:15:397:16 | a9 | -| main.rs:402:13:402:15 | a10 | main.rs:402:13:402:15 | a10 | main.rs:406:15:406:17 | a10 | -| main.rs:403:13:403:14 | b4 | main.rs:403:13:403:14 | b4 | main.rs:407:15:407:16 | b4 | -| main.rs:404:13:404:14 | c2 | main.rs:404:13:404:14 | c2 | main.rs:408:15:408:16 | c2 | -| main.rs:411:9:411:10 | c2 | main.rs:404:13:404:14 | c2 | main.rs:421:15:421:16 | c2 | -| main.rs:412:9:412:10 | b4 | main.rs:403:13:403:14 | b4 | main.rs:420:15:420:16 | b4 | -| main.rs:413:9:413:11 | a10 | main.rs:402:13:402:15 | a10 | main.rs:419:15:419:17 | a10 | -| main.rs:425:13:425:15 | a10 | main.rs:425:13:425:15 | a10 | main.rs:428:23:428:25 | a10 | -| main.rs:426:13:426:14 | b4 | main.rs:426:13:426:14 | b4 | main.rs:429:23:429:24 | b4 | -| main.rs:438:9:438:23 | example_closure | main.rs:438:9:438:23 | example_closure | main.rs:442:9:442:23 | example_closure | -| main.rs:439:10:439:10 | x | main.rs:439:10:439:10 | x | main.rs:440:9:440:9 | x | -| main.rs:441:9:441:10 | n1 | main.rs:441:9:441:10 | n1 | main.rs:443:15:443:16 | n1 | -| main.rs:446:9:446:26 | immutable_variable | main.rs:446:9:446:26 | immutable_variable | main.rs:450:9:450:26 | immutable_variable | -| main.rs:447:6:447:6 | x | main.rs:447:6:447:6 | x | main.rs:448:9:448:9 | x | -| main.rs:449:9:449:10 | n2 | main.rs:449:9:449:10 | n2 | main.rs:451:15:451:16 | n2 | -| main.rs:456:9:456:9 | f | main.rs:456:9:456:9 | f | main.rs:459:15:459:15 | f | -| main.rs:457:10:457:10 | x | main.rs:457:10:457:10 | x | main.rs:458:9:458:9 | x | -| main.rs:461:10:461:10 | x | main.rs:461:10:461:10 | x | main.rs:463:9:463:9 | x | -| main.rs:470:14:470:14 | x | main.rs:470:14:470:14 | x | main.rs:472:17:472:17 | x | -| main.rs:479:13:479:13 | f | main.rs:479:13:479:13 | f | main.rs:482:19:482:19 | f | -| main.rs:480:14:480:14 | x | main.rs:480:14:480:14 | x | main.rs:481:13:481:13 | x | -| main.rs:487:9:487:9 | v | main.rs:487:9:487:9 | v | main.rs:490:12:490:12 | v | -| main.rs:489:9:489:12 | text | main.rs:489:9:489:12 | text | main.rs:491:19:491:22 | text | -| main.rs:496:13:496:13 | a | main.rs:496:13:496:13 | a | main.rs:497:5:497:5 | a | -| main.rs:497:5:497:5 | a | main.rs:496:13:496:13 | a | main.rs:498:15:498:15 | a | -| main.rs:499:6:499:11 | &mut a | main.rs:496:13:496:13 | a | main.rs:500:15:500:15 | a | -| main.rs:504:13:504:13 | i | main.rs:504:13:504:13 | i | main.rs:506:14:506:14 | i | -| main.rs:505:9:505:13 | ref_i | main.rs:505:9:505:13 | ref_i | main.rs:507:6:507:10 | ref_i | -| main.rs:506:9:506:14 | &mut i | main.rs:504:13:504:13 | i | main.rs:508:15:508:15 | i | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | main.rs:512:6:512:6 | x | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | main.rs:519:6:519:6 | x | -| main.rs:518:38:518:38 | y | main.rs:518:38:518:38 | y | main.rs:522:6:522:6 | y | -| main.rs:527:13:527:13 | x | main.rs:527:13:527:13 | x | main.rs:529:27:529:27 | x | -| main.rs:528:9:528:9 | y | main.rs:528:9:528:9 | y | main.rs:530:6:530:6 | y | -| main.rs:529:22:529:27 | &mut x | main.rs:527:13:527:13 | x | main.rs:533:15:533:15 | x | -| main.rs:535:13:535:13 | z | main.rs:535:13:535:13 | z | main.rs:539:14:539:14 | z | -| main.rs:536:9:536:9 | w | main.rs:536:9:536:9 | w | main.rs:540:9:540:9 | w | -| main.rs:539:9:539:14 | &mut z | main.rs:535:13:535:13 | z | main.rs:545:15:545:15 | z | -| main.rs:549:13:549:13 | x | main.rs:549:13:549:13 | x | main.rs:551:14:551:14 | x | -| main.rs:550:9:550:9 | y | main.rs:550:9:550:9 | y | main.rs:552:6:552:6 | y | -| main.rs:551:9:551:14 | &mut x | main.rs:549:13:549:13 | x | main.rs:553:15:553:15 | x | -| main.rs:557:9:557:9 | x | main.rs:557:9:557:9 | x | main.rs:564:15:564:15 | x | -| main.rs:560:9:560:11 | cap | main.rs:560:9:560:11 | cap | main.rs:563:5:563:7 | cap | -| main.rs:560:15:562:5 | x | main.rs:557:9:557:9 | x | main.rs:561:19:561:19 | x | -| main.rs:568:13:568:13 | x | main.rs:568:13:568:13 | x | main.rs:575:15:575:15 | x | -| main.rs:571:9:571:16 | closure1 | main.rs:571:9:571:16 | closure1 | main.rs:574:5:574:12 | closure1 | -| main.rs:571:20:573:5 | x | main.rs:568:13:568:13 | x | main.rs:572:19:572:19 | x | -| main.rs:580:13:580:20 | closure2 | main.rs:580:13:580:20 | closure2 | main.rs:583:5:583:12 | closure2 | -| main.rs:583:5:583:14 | y | main.rs:577:13:577:13 | y | main.rs:584:15:584:15 | y | -| main.rs:586:13:586:13 | z | main.rs:586:13:586:13 | z | main.rs:593:15:593:15 | z | -| main.rs:589:13:589:20 | closure3 | main.rs:589:13:589:20 | closure3 | main.rs:592:5:592:12 | closure3 | -| main.rs:589:24:591:5 | z | main.rs:586:13:586:13 | z | main.rs:590:9:590:9 | z | -| main.rs:598:9:598:13 | block | main.rs:598:9:598:13 | block | main.rs:602:5:602:9 | block | -| main.rs:602:5:602:15 | i | main.rs:597:13:597:13 | i | main.rs:603:15:603:15 | i | -| main.rs:606:8:606:8 | b | main.rs:606:8:606:8 | b | main.rs:611:16:611:16 | b | -| main.rs:607:13:607:13 | x | main.rs:607:13:607:13 | x | main.rs:608:15:608:15 | x | -| main.rs:611:13:620:5 | SSA phi(x) | main.rs:607:13:607:13 | x | main.rs:621:15:621:15 | x | -| main.rs:613:9:613:9 | x | main.rs:607:13:607:13 | x | main.rs:614:19:614:19 | x | -| main.rs:617:9:617:9 | x | main.rs:607:13:607:13 | x | main.rs:618:19:618:19 | x | -| main.rs:624:13:624:14 | b1 | main.rs:624:13:624:14 | b1 | main.rs:627:16:627:17 | b1 | -| main.rs:624:23:624:24 | b2 | main.rs:624:23:624:24 | b2 | main.rs:635:16:635:17 | b2 | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:629:19:629:19 | x | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:631:19:631:19 | x | -| main.rs:648:20:648:23 | self | main.rs:648:20:648:23 | self | main.rs:649:16:649:19 | self | -| main.rs:652:11:652:14 | self | main.rs:652:11:652:14 | self | main.rs:653:9:653:12 | self | -| main.rs:657:17:657:17 | f | main.rs:657:17:657:17 | f | main.rs:661:9:661:9 | f | -| main.rs:657:21:660:9 | self | main.rs:656:23:656:26 | self | main.rs:659:13:659:16 | self | -| main.rs:657:22:657:22 | n | main.rs:657:22:657:22 | n | main.rs:659:25:659:25 | n | -| main.rs:667:13:667:13 | a | main.rs:667:13:667:13 | a | main.rs:668:15:668:15 | a | -| main.rs:668:15:668:15 | a | main.rs:667:13:667:13 | a | main.rs:669:5:669:5 | a | -| main.rs:671:5:671:5 | a | main.rs:667:13:667:13 | a | main.rs:672:15:672:15 | a | -| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:677:15:677:15 | a | -| main.rs:680:5:680:5 | a | main.rs:676:13:676:13 | a | main.rs:681:15:681:15 | a | -| main.rs:685:9:685:9 | x | main.rs:685:9:685:9 | x | main.rs:686:20:686:20 | x | -| main.rs:689:9:689:9 | z | main.rs:689:9:689:9 | z | main.rs:690:20:690:20 | z | -| main.rs:698:17:698:20 | self | main.rs:698:17:698:20 | self | main.rs:699:10:699:13 | self | -| main.rs:704:13:704:13 | a | main.rs:704:13:704:13 | a | main.rs:705:5:705:5 | a | -| main.rs:705:5:705:5 | a | main.rs:704:13:704:13 | a | main.rs:708:15:708:15 | a | -| main.rs:726:9:726:22 | var_from_macro | main.rs:726:9:726:22 | var_from_macro | main.rs:728:15:728:28 | var_from_macro | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:9:727:21 | var_in_macro | main.rs:727:9:727:21 | var_in_macro | -| main.rs:729:9:729:20 | var_in_macro | main.rs:729:9:729:20 | var_in_macro | main.rs:735:15:735:26 | var_in_macro | -| main.rs:734:15:734:28 | var_in_macro | main.rs:734:15:734:28 | var_in_macro | main.rs:734:30:734:41 | var_in_macro | -| main.rs:740:5:740:5 | x | main.rs:739:9:739:9 | x | main.rs:741:15:741:15 | x | -| main.rs:746:13:746:15 | cap | main.rs:746:13:746:15 | cap | main.rs:752:5:752:7 | cap | -| main.rs:746:20:746:20 | b | main.rs:746:20:746:20 | b | main.rs:748:20:748:20 | b | -| main.rs:752:5:752:13 | x | main.rs:745:13:745:13 | x | main.rs:753:15:753:15 | x | -| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | main.rs:761:19:761:19 | x | -| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y | -| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | main.rs:770:17:770:20 | N0ne | -| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | main.rs:779:13:779:22 | test_alias | -| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test | -| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x | -| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x | +| main.rs:317:17:317:17 | x | main.rs:317:17:317:17 | x | main.rs:320:5:320:5 | x | +| main.rs:324:13:324:13 | x | main.rs:324:13:324:13 | x | main.rs:326:19:326:19 | x | +| main.rs:332:9:332:9 | x | main.rs:332:9:332:9 | x | main.rs:334:7:334:7 | x | +| main.rs:333:17:333:17 | x | main.rs:333:17:333:17 | x | main.rs:337:12:337:12 | x | +| main.rs:336:14:336:14 | x | main.rs:336:14:336:14 | x | main.rs:339:5:339:5 | x | +| main.rs:343:13:343:13 | x | main.rs:343:13:343:13 | x | main.rs:345:19:345:19 | x | +| main.rs:351:9:351:9 | x | main.rs:351:9:351:9 | x | main.rs:353:7:353:7 | x | +| main.rs:352:20:352:20 | x | main.rs:352:20:352:20 | x | main.rs:356:12:356:12 | x | +| main.rs:355:14:355:14 | x | main.rs:355:14:355:14 | x | main.rs:358:5:358:5 | x | +| main.rs:369:9:369:9 | x | main.rs:369:9:369:9 | x | main.rs:370:11:370:11 | x | +| main.rs:371:14:371:14 | x | main.rs:371:14:371:14 | x | main.rs:373:18:373:18 | x | +| main.rs:372:20:372:20 | x | main.rs:372:20:372:20 | x | main.rs:374:19:374:19 | x | +| main.rs:383:9:383:9 | x | main.rs:383:9:383:9 | x | main.rs:385:7:385:7 | x | +| main.rs:384:16:384:16 | x | main.rs:384:16:384:16 | x | main.rs:387:19:387:19 | x | +| main.rs:389:20:389:20 | x | main.rs:389:20:389:20 | x | main.rs:392:19:392:19 | x | +| main.rs:399:9:399:9 | x | main.rs:399:9:399:9 | x | main.rs:400:11:400:11 | x | +| main.rs:401:18:401:18 | x | main.rs:401:18:401:18 | x | main.rs:402:20:402:20 | x | +| main.rs:408:9:408:9 | x | main.rs:408:9:408:9 | x | main.rs:409:11:409:11 | x | +| main.rs:410:14:410:14 | y | main.rs:410:14:410:14 | y | main.rs:411:16:411:16 | y | +| main.rs:412:22:412:22 | y | main.rs:412:22:412:22 | y | main.rs:414:26:414:26 | y | +| main.rs:420:5:420:6 | a8 | main.rs:420:5:420:6 | a8 | main.rs:426:15:426:16 | a8 | +| main.rs:422:9:422:10 | b3 | main.rs:422:9:422:10 | b3 | main.rs:427:15:427:16 | b3 | +| main.rs:423:9:423:10 | c1 | main.rs:423:9:423:10 | c1 | main.rs:428:15:428:16 | c1 | +| main.rs:431:20:431:55 | SSA phi(a9) | main.rs:431:20:431:55 | a9 | main.rs:433:15:433:16 | a9 | +| main.rs:438:13:438:15 | a10 | main.rs:438:13:438:15 | a10 | main.rs:442:15:442:17 | a10 | +| main.rs:439:13:439:14 | b4 | main.rs:439:13:439:14 | b4 | main.rs:443:15:443:16 | b4 | +| main.rs:440:13:440:14 | c2 | main.rs:440:13:440:14 | c2 | main.rs:444:15:444:16 | c2 | +| main.rs:447:9:447:10 | c2 | main.rs:440:13:440:14 | c2 | main.rs:457:15:457:16 | c2 | +| main.rs:448:9:448:10 | b4 | main.rs:439:13:439:14 | b4 | main.rs:456:15:456:16 | b4 | +| main.rs:449:9:449:11 | a10 | main.rs:438:13:438:15 | a10 | main.rs:455:15:455:17 | a10 | +| main.rs:461:13:461:15 | a10 | main.rs:461:13:461:15 | a10 | main.rs:464:23:464:25 | a10 | +| main.rs:462:13:462:14 | b4 | main.rs:462:13:462:14 | b4 | main.rs:465:23:465:24 | b4 | +| main.rs:474:9:474:23 | example_closure | main.rs:474:9:474:23 | example_closure | main.rs:478:9:478:23 | example_closure | +| main.rs:475:10:475:10 | x | main.rs:475:10:475:10 | x | main.rs:476:9:476:9 | x | +| main.rs:477:9:477:10 | n1 | main.rs:477:9:477:10 | n1 | main.rs:479:15:479:16 | n1 | +| main.rs:482:9:482:26 | immutable_variable | main.rs:482:9:482:26 | immutable_variable | main.rs:486:9:486:26 | immutable_variable | +| main.rs:483:6:483:6 | x | main.rs:483:6:483:6 | x | main.rs:484:9:484:9 | x | +| main.rs:485:9:485:10 | n2 | main.rs:485:9:485:10 | n2 | main.rs:487:15:487:16 | n2 | +| main.rs:492:9:492:9 | f | main.rs:492:9:492:9 | f | main.rs:495:15:495:15 | f | +| main.rs:493:10:493:10 | x | main.rs:493:10:493:10 | x | main.rs:494:9:494:9 | x | +| main.rs:497:10:497:10 | x | main.rs:497:10:497:10 | x | main.rs:499:9:499:9 | x | +| main.rs:506:14:506:14 | x | main.rs:506:14:506:14 | x | main.rs:508:17:508:17 | x | +| main.rs:515:13:515:13 | f | main.rs:515:13:515:13 | f | main.rs:518:19:518:19 | f | +| main.rs:516:14:516:14 | x | main.rs:516:14:516:14 | x | main.rs:517:13:517:13 | x | +| main.rs:523:9:523:9 | v | main.rs:523:9:523:9 | v | main.rs:526:12:526:12 | v | +| main.rs:525:9:525:12 | text | main.rs:525:9:525:12 | text | main.rs:527:19:527:22 | text | +| main.rs:532:13:532:13 | a | main.rs:532:13:532:13 | a | main.rs:533:5:533:5 | a | +| main.rs:533:5:533:5 | a | main.rs:532:13:532:13 | a | main.rs:534:15:534:15 | a | +| main.rs:535:6:535:11 | &mut a | main.rs:532:13:532:13 | a | main.rs:536:15:536:15 | a | +| main.rs:540:13:540:13 | i | main.rs:540:13:540:13 | i | main.rs:542:14:542:14 | i | +| main.rs:541:9:541:13 | ref_i | main.rs:541:9:541:13 | ref_i | main.rs:543:6:543:10 | ref_i | +| main.rs:542:9:542:14 | &mut i | main.rs:540:13:540:13 | i | main.rs:544:15:544:15 | i | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | main.rs:548:6:548:6 | x | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | main.rs:555:6:555:6 | x | +| main.rs:554:38:554:38 | y | main.rs:554:38:554:38 | y | main.rs:558:6:558:6 | y | +| main.rs:563:13:563:13 | x | main.rs:563:13:563:13 | x | main.rs:565:27:565:27 | x | +| main.rs:564:9:564:9 | y | main.rs:564:9:564:9 | y | main.rs:566:6:566:6 | y | +| main.rs:565:22:565:27 | &mut x | main.rs:563:13:563:13 | x | main.rs:569:15:569:15 | x | +| main.rs:571:13:571:13 | z | main.rs:571:13:571:13 | z | main.rs:575:14:575:14 | z | +| main.rs:572:9:572:9 | w | main.rs:572:9:572:9 | w | main.rs:576:9:576:9 | w | +| main.rs:575:9:575:14 | &mut z | main.rs:571:13:571:13 | z | main.rs:581:15:581:15 | z | +| main.rs:585:13:585:13 | x | main.rs:585:13:585:13 | x | main.rs:587:14:587:14 | x | +| main.rs:586:9:586:9 | y | main.rs:586:9:586:9 | y | main.rs:588:6:588:6 | y | +| main.rs:587:9:587:14 | &mut x | main.rs:585:13:585:13 | x | main.rs:589:15:589:15 | x | +| main.rs:593:9:593:9 | x | main.rs:593:9:593:9 | x | main.rs:600:15:600:15 | x | +| main.rs:596:9:596:11 | cap | main.rs:596:9:596:11 | cap | main.rs:599:5:599:7 | cap | +| main.rs:596:15:598:5 | x | main.rs:593:9:593:9 | x | main.rs:597:19:597:19 | x | +| main.rs:604:13:604:13 | x | main.rs:604:13:604:13 | x | main.rs:611:15:611:15 | x | +| main.rs:607:9:607:16 | closure1 | main.rs:607:9:607:16 | closure1 | main.rs:610:5:610:12 | closure1 | +| main.rs:607:20:609:5 | x | main.rs:604:13:604:13 | x | main.rs:608:19:608:19 | x | +| main.rs:616:13:616:20 | closure2 | main.rs:616:13:616:20 | closure2 | main.rs:619:5:619:12 | closure2 | +| main.rs:619:5:619:14 | y | main.rs:613:13:613:13 | y | main.rs:620:15:620:15 | y | +| main.rs:622:13:622:13 | z | main.rs:622:13:622:13 | z | main.rs:629:15:629:15 | z | +| main.rs:625:13:625:20 | closure3 | main.rs:625:13:625:20 | closure3 | main.rs:628:5:628:12 | closure3 | +| main.rs:625:24:627:5 | z | main.rs:622:13:622:13 | z | main.rs:626:9:626:9 | z | +| main.rs:634:9:634:13 | block | main.rs:634:9:634:13 | block | main.rs:638:5:638:9 | block | +| main.rs:638:5:638:15 | i | main.rs:633:13:633:13 | i | main.rs:639:15:639:15 | i | +| main.rs:642:8:642:8 | b | main.rs:642:8:642:8 | b | main.rs:647:16:647:16 | b | +| main.rs:643:13:643:13 | x | main.rs:643:13:643:13 | x | main.rs:644:15:644:15 | x | +| main.rs:647:13:656:5 | SSA phi(x) | main.rs:643:13:643:13 | x | main.rs:657:15:657:15 | x | +| main.rs:649:9:649:9 | x | main.rs:643:13:643:13 | x | main.rs:650:19:650:19 | x | +| main.rs:653:9:653:9 | x | main.rs:643:13:643:13 | x | main.rs:654:19:654:19 | x | +| main.rs:660:13:660:14 | b1 | main.rs:660:13:660:14 | b1 | main.rs:663:16:663:17 | b1 | +| main.rs:660:23:660:24 | b2 | main.rs:660:23:660:24 | b2 | main.rs:671:16:671:17 | b2 | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:665:19:665:19 | x | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:667:19:667:19 | x | +| main.rs:684:20:684:23 | self | main.rs:684:20:684:23 | self | main.rs:685:16:685:19 | self | +| main.rs:688:11:688:14 | self | main.rs:688:11:688:14 | self | main.rs:689:9:689:12 | self | +| main.rs:693:17:693:17 | f | main.rs:693:17:693:17 | f | main.rs:697:9:697:9 | f | +| main.rs:693:21:696:9 | self | main.rs:692:23:692:26 | self | main.rs:695:13:695:16 | self | +| main.rs:693:22:693:22 | n | main.rs:693:22:693:22 | n | main.rs:695:25:695:25 | n | +| main.rs:703:13:703:13 | a | main.rs:703:13:703:13 | a | main.rs:704:15:704:15 | a | +| main.rs:704:15:704:15 | a | main.rs:703:13:703:13 | a | main.rs:705:5:705:5 | a | +| main.rs:707:5:707:5 | a | main.rs:703:13:703:13 | a | main.rs:708:15:708:15 | a | +| main.rs:712:13:712:13 | a | main.rs:712:13:712:13 | a | main.rs:713:15:713:15 | a | +| main.rs:716:5:716:5 | a | main.rs:712:13:712:13 | a | main.rs:717:15:717:15 | a | +| main.rs:721:9:721:9 | x | main.rs:721:9:721:9 | x | main.rs:722:20:722:20 | x | +| main.rs:725:9:725:9 | z | main.rs:725:9:725:9 | z | main.rs:726:20:726:20 | z | +| main.rs:734:17:734:20 | self | main.rs:734:17:734:20 | self | main.rs:735:10:735:13 | self | +| main.rs:740:13:740:13 | a | main.rs:740:13:740:13 | a | main.rs:741:5:741:5 | a | +| main.rs:741:5:741:5 | a | main.rs:740:13:740:13 | a | main.rs:744:15:744:15 | a | +| main.rs:762:9:762:22 | var_from_macro | main.rs:762:9:762:22 | var_from_macro | main.rs:764:15:764:28 | var_from_macro | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:9:763:21 | var_in_macro | main.rs:763:9:763:21 | var_in_macro | +| main.rs:765:9:765:20 | var_in_macro | main.rs:765:9:765:20 | var_in_macro | main.rs:771:15:771:26 | var_in_macro | +| main.rs:770:15:770:28 | var_in_macro | main.rs:770:15:770:28 | var_in_macro | main.rs:770:30:770:41 | var_in_macro | +| main.rs:776:5:776:5 | x | main.rs:775:9:775:9 | x | main.rs:777:15:777:15 | x | +| main.rs:782:13:782:15 | cap | main.rs:782:13:782:15 | cap | main.rs:788:5:788:7 | cap | +| main.rs:782:20:782:20 | b | main.rs:782:20:782:20 | b | main.rs:784:20:784:20 | b | +| main.rs:788:5:788:13 | x | main.rs:781:13:781:13 | x | main.rs:789:15:789:15 | x | +| main.rs:795:13:795:13 | x | main.rs:795:13:795:13 | x | main.rs:797:19:797:19 | x | +| main.rs:796:13:796:13 | y | main.rs:796:13:796:13 | y | main.rs:804:15:804:15 | y | +| main.rs:805:13:805:16 | N0ne | main.rs:805:13:805:16 | N0ne | main.rs:806:17:806:20 | N0ne | +| main.rs:812:13:812:22 | test_alias | main.rs:812:13:812:22 | test_alias | main.rs:815:13:815:22 | test_alias | +| main.rs:814:13:814:16 | test | main.rs:814:13:814:16 | test | main.rs:816:9:816:12 | test | +| main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | main.rs:824:15:824:15 | x | +| main.rs:825:18:825:18 | x | main.rs:825:18:825:18 | x | main.rs:826:20:826:20 | x | +| main.rs:838:9:838:9 | x | main.rs:838:9:838:9 | x | main.rs:845:19:845:19 | x | +| main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | main.rs:841:9:841:9 | x | adjacentReads | main.rs:27:5:27:6 | x2 | main.rs:25:13:25:14 | x2 | main.rs:28:15:28:16 | x2 | main.rs:29:10:29:11 | x2 | | main.rs:41:9:41:10 | x3 | main.rs:41:9:41:10 | x3 | main.rs:42:15:42:16 | x3 | main.rs:44:9:44:10 | x3 | | main.rs:49:9:49:10 | x4 | main.rs:49:9:49:10 | x4 | main.rs:50:15:50:16 | x4 | main.rs:55:15:55:16 | x4 | | main.rs:100:9:100:9 | x | main.rs:100:9:100:9 | x | main.rs:102:7:102:7 | x | main.rs:105:13:105:13 | x | -| main.rs:113:9:113:10 | s1 | main.rs:113:9:113:10 | s1 | main.rs:116:11:116:12 | s1 | main.rs:116:11:116:12 | s1 | -| main.rs:139:9:139:15 | numbers | main.rs:139:9:139:15 | numbers | main.rs:141:11:141:17 | numbers | main.rs:156:11:156:17 | numbers | -| main.rs:222:9:222:10 | tv | main.rs:222:9:222:10 | tv | main.rs:223:11:223:12 | tv | main.rs:227:11:227:12 | tv | -| main.rs:222:9:222:10 | tv | main.rs:222:9:222:10 | tv | main.rs:227:11:227:12 | tv | main.rs:231:11:231:12 | tv | -| main.rs:240:9:240:44 | [match(true)] SSA phi(a7) | main.rs:240:9:240:44 | a7 | main.rs:241:16:241:17 | a7 | main.rs:242:26:242:27 | a7 | -| main.rs:281:9:281:9 | x | main.rs:281:9:281:9 | x | main.rs:283:7:283:7 | x | main.rs:290:13:290:13 | x | -| main.rs:282:17:282:17 | x | main.rs:282:17:282:17 | x | main.rs:285:5:285:5 | x | main.rs:287:19:287:19 | x | -| main.rs:297:9:297:9 | x | main.rs:297:9:297:9 | x | main.rs:299:7:299:7 | x | main.rs:309:13:309:13 | x | -| main.rs:301:14:301:14 | x | main.rs:301:14:301:14 | x | main.rs:304:5:304:5 | x | main.rs:306:19:306:19 | x | -| main.rs:316:9:316:9 | x | main.rs:316:9:316:9 | x | main.rs:318:7:318:7 | x | main.rs:329:15:329:15 | x | -| main.rs:320:14:320:14 | x | main.rs:320:14:320:14 | x | main.rs:323:5:323:5 | x | main.rs:325:19:325:19 | x | -| main.rs:334:9:334:9 | x | main.rs:334:9:334:9 | x | main.rs:335:11:335:11 | x | main.rs:343:15:343:15 | x | -| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:350:7:350:7 | x | main.rs:355:7:355:7 | x | -| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:355:7:355:7 | x | main.rs:359:19:359:19 | x | -| main.rs:402:13:402:15 | a10 | main.rs:402:13:402:15 | a10 | main.rs:406:15:406:17 | a10 | main.rs:415:9:415:11 | a10 | -| main.rs:403:13:403:14 | b4 | main.rs:403:13:403:14 | b4 | main.rs:407:15:407:16 | b4 | main.rs:416:9:416:10 | b4 | -| main.rs:404:13:404:14 | c2 | main.rs:404:13:404:14 | c2 | main.rs:408:15:408:16 | c2 | main.rs:417:9:417:10 | c2 | -| main.rs:412:9:412:10 | b4 | main.rs:403:13:403:14 | b4 | main.rs:420:15:420:16 | b4 | main.rs:434:15:434:16 | b4 | -| main.rs:413:9:413:11 | a10 | main.rs:402:13:402:15 | a10 | main.rs:419:15:419:17 | a10 | main.rs:433:15:433:17 | a10 | -| main.rs:456:9:456:9 | f | main.rs:456:9:456:9 | f | main.rs:459:15:459:15 | f | main.rs:466:15:466:15 | f | -| main.rs:497:5:497:5 | a | main.rs:496:13:496:13 | a | main.rs:498:15:498:15 | a | main.rs:499:11:499:11 | a | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | main.rs:512:6:512:6 | x | main.rs:513:10:513:10 | x | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | main.rs:513:10:513:10 | x | main.rs:514:10:514:10 | x | -| main.rs:511:17:511:17 | x | main.rs:511:17:511:17 | x | main.rs:514:10:514:10 | x | main.rs:515:12:515:12 | x | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | main.rs:519:6:519:6 | x | main.rs:520:10:520:10 | x | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | main.rs:520:10:520:10 | x | main.rs:521:10:521:10 | x | -| main.rs:518:22:518:22 | x | main.rs:518:22:518:22 | x | main.rs:521:10:521:10 | x | main.rs:523:9:523:9 | x | -| main.rs:529:22:529:27 | &mut x | main.rs:527:13:527:13 | x | main.rs:533:15:533:15 | x | main.rs:537:19:537:19 | x | -| main.rs:536:9:536:9 | w | main.rs:536:9:536:9 | w | main.rs:540:9:540:9 | w | main.rs:542:7:542:7 | w | -| main.rs:607:13:607:13 | x | main.rs:607:13:607:13 | x | main.rs:608:15:608:15 | x | main.rs:609:15:609:15 | x | -| main.rs:613:9:613:9 | x | main.rs:607:13:607:13 | x | main.rs:614:19:614:19 | x | main.rs:615:19:615:19 | x | -| main.rs:617:9:617:9 | x | main.rs:607:13:607:13 | x | main.rs:618:19:618:19 | x | main.rs:619:19:619:19 | x | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:629:19:629:19 | x | main.rs:637:19:637:19 | x | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:629:19:629:19 | x | main.rs:639:19:639:19 | x | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:631:19:631:19 | x | main.rs:637:19:637:19 | x | -| main.rs:625:9:625:9 | x | main.rs:625:9:625:9 | x | main.rs:631:19:631:19 | x | main.rs:639:19:639:19 | x | -| main.rs:657:17:657:17 | f | main.rs:657:17:657:17 | f | main.rs:661:9:661:9 | f | main.rs:662:9:662:9 | f | -| main.rs:668:15:668:15 | a | main.rs:667:13:667:13 | a | main.rs:669:5:669:5 | a | main.rs:670:15:670:15 | a | -| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:677:15:677:15 | a | main.rs:678:5:678:5 | a | -| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:678:5:678:5 | a | main.rs:679:15:679:15 | a | -| main.rs:685:9:685:9 | x | main.rs:685:9:685:9 | x | main.rs:686:20:686:20 | x | main.rs:687:15:687:15 | x | -| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x | main.rs:793:15:793:15 | x | +| main.rs:113:9:113:9 | s | main.rs:113:9:113:9 | s | main.rs:116:11:116:11 | s | main.rs:116:11:116:11 | s | +| main.rs:174:9:174:15 | numbers | main.rs:174:9:174:15 | numbers | main.rs:176:11:176:17 | numbers | main.rs:191:11:191:17 | numbers | +| main.rs:257:9:257:10 | tv | main.rs:257:9:257:10 | tv | main.rs:258:11:258:12 | tv | main.rs:262:11:262:12 | tv | +| main.rs:257:9:257:10 | tv | main.rs:257:9:257:10 | tv | main.rs:262:11:262:12 | tv | main.rs:266:11:266:12 | tv | +| main.rs:275:9:275:44 | [match(true)] SSA phi(a7) | main.rs:275:9:275:44 | a7 | main.rs:276:16:276:17 | a7 | main.rs:277:26:277:27 | a7 | +| main.rs:316:9:316:9 | x | main.rs:316:9:316:9 | x | main.rs:318:7:318:7 | x | main.rs:325:13:325:13 | x | +| main.rs:317:17:317:17 | x | main.rs:317:17:317:17 | x | main.rs:320:5:320:5 | x | main.rs:322:19:322:19 | x | +| main.rs:332:9:332:9 | x | main.rs:332:9:332:9 | x | main.rs:334:7:334:7 | x | main.rs:344:13:344:13 | x | +| main.rs:336:14:336:14 | x | main.rs:336:14:336:14 | x | main.rs:339:5:339:5 | x | main.rs:341:19:341:19 | x | +| main.rs:351:9:351:9 | x | main.rs:351:9:351:9 | x | main.rs:353:7:353:7 | x | main.rs:364:15:364:15 | x | +| main.rs:355:14:355:14 | x | main.rs:355:14:355:14 | x | main.rs:358:5:358:5 | x | main.rs:360:19:360:19 | x | +| main.rs:369:9:369:9 | x | main.rs:369:9:369:9 | x | main.rs:370:11:370:11 | x | main.rs:378:15:378:15 | x | +| main.rs:383:9:383:9 | x | main.rs:383:9:383:9 | x | main.rs:385:7:385:7 | x | main.rs:390:7:390:7 | x | +| main.rs:383:9:383:9 | x | main.rs:383:9:383:9 | x | main.rs:390:7:390:7 | x | main.rs:394:19:394:19 | x | +| main.rs:410:14:410:14 | y | main.rs:410:14:410:14 | y | main.rs:411:16:411:16 | y | main.rs:413:22:413:22 | y | +| main.rs:438:13:438:15 | a10 | main.rs:438:13:438:15 | a10 | main.rs:442:15:442:17 | a10 | main.rs:451:9:451:11 | a10 | +| main.rs:439:13:439:14 | b4 | main.rs:439:13:439:14 | b4 | main.rs:443:15:443:16 | b4 | main.rs:452:9:452:10 | b4 | +| main.rs:440:13:440:14 | c2 | main.rs:440:13:440:14 | c2 | main.rs:444:15:444:16 | c2 | main.rs:453:9:453:10 | c2 | +| main.rs:448:9:448:10 | b4 | main.rs:439:13:439:14 | b4 | main.rs:456:15:456:16 | b4 | main.rs:470:15:470:16 | b4 | +| main.rs:449:9:449:11 | a10 | main.rs:438:13:438:15 | a10 | main.rs:455:15:455:17 | a10 | main.rs:469:15:469:17 | a10 | +| main.rs:492:9:492:9 | f | main.rs:492:9:492:9 | f | main.rs:495:15:495:15 | f | main.rs:502:15:502:15 | f | +| main.rs:533:5:533:5 | a | main.rs:532:13:532:13 | a | main.rs:534:15:534:15 | a | main.rs:535:11:535:11 | a | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | main.rs:548:6:548:6 | x | main.rs:549:10:549:10 | x | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | main.rs:549:10:549:10 | x | main.rs:550:10:550:10 | x | +| main.rs:547:17:547:17 | x | main.rs:547:17:547:17 | x | main.rs:550:10:550:10 | x | main.rs:551:12:551:12 | x | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | main.rs:555:6:555:6 | x | main.rs:556:10:556:10 | x | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | main.rs:556:10:556:10 | x | main.rs:557:10:557:10 | x | +| main.rs:554:22:554:22 | x | main.rs:554:22:554:22 | x | main.rs:557:10:557:10 | x | main.rs:559:9:559:9 | x | +| main.rs:565:22:565:27 | &mut x | main.rs:563:13:563:13 | x | main.rs:569:15:569:15 | x | main.rs:573:19:573:19 | x | +| main.rs:572:9:572:9 | w | main.rs:572:9:572:9 | w | main.rs:576:9:576:9 | w | main.rs:578:7:578:7 | w | +| main.rs:643:13:643:13 | x | main.rs:643:13:643:13 | x | main.rs:644:15:644:15 | x | main.rs:645:15:645:15 | x | +| main.rs:649:9:649:9 | x | main.rs:643:13:643:13 | x | main.rs:650:19:650:19 | x | main.rs:651:19:651:19 | x | +| main.rs:653:9:653:9 | x | main.rs:643:13:643:13 | x | main.rs:654:19:654:19 | x | main.rs:655:19:655:19 | x | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:665:19:665:19 | x | main.rs:673:19:673:19 | x | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:665:19:665:19 | x | main.rs:675:19:675:19 | x | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:667:19:667:19 | x | main.rs:673:19:673:19 | x | +| main.rs:661:9:661:9 | x | main.rs:661:9:661:9 | x | main.rs:667:19:667:19 | x | main.rs:675:19:675:19 | x | +| main.rs:693:17:693:17 | f | main.rs:693:17:693:17 | f | main.rs:697:9:697:9 | f | main.rs:698:9:698:9 | f | +| main.rs:704:15:704:15 | a | main.rs:703:13:703:13 | a | main.rs:705:5:705:5 | a | main.rs:706:15:706:15 | a | +| main.rs:712:13:712:13 | a | main.rs:712:13:712:13 | a | main.rs:713:15:713:15 | a | main.rs:714:5:714:5 | a | +| main.rs:712:13:712:13 | a | main.rs:712:13:712:13 | a | main.rs:714:5:714:5 | a | main.rs:715:15:715:15 | a | +| main.rs:721:9:721:9 | x | main.rs:721:9:721:9 | x | main.rs:722:20:722:20 | x | main.rs:723:15:723:15 | x | +| main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | main.rs:824:15:824:15 | x | main.rs:829:15:829:15 | x | +| main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | main.rs:841:9:841:9 | x | main.rs:843:19:843:19 | x | phi -| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:9:210:44 | a3 | main.rs:210:22:210:23 | a3 | -| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:9:210:44 | a3 | main.rs:210:42:210:43 | a3 | -| main.rs:224:9:224:81 | SSA phi(a4) | main.rs:224:9:224:81 | a4 | main.rs:224:28:224:29 | a4 | -| main.rs:224:9:224:81 | SSA phi(a4) | main.rs:224:9:224:81 | a4 | main.rs:224:54:224:55 | a4 | -| main.rs:224:9:224:81 | SSA phi(a4) | main.rs:224:9:224:81 | a4 | main.rs:224:79:224:80 | a4 | -| main.rs:228:9:228:83 | SSA phi(a5) | main.rs:228:9:228:83 | a5 | main.rs:228:10:228:57 | [match(true)] SSA phi(a5) | -| main.rs:228:9:228:83 | SSA phi(a5) | main.rs:228:9:228:83 | a5 | main.rs:228:81:228:82 | a5 | -| main.rs:228:10:228:57 | [match(true)] SSA phi(a5) | main.rs:228:9:228:83 | a5 | main.rs:228:29:228:30 | a5 | -| main.rs:228:10:228:57 | [match(true)] SSA phi(a5) | main.rs:228:9:228:83 | a5 | main.rs:228:55:228:56 | a5 | -| main.rs:232:9:232:83 | SSA phi(a6) | main.rs:232:9:232:83 | a6 | main.rs:232:28:232:29 | a6 | -| main.rs:232:9:232:83 | SSA phi(a6) | main.rs:232:9:232:83 | a6 | main.rs:232:35:232:82 | SSA phi(a6) | -| main.rs:232:35:232:82 | SSA phi(a6) | main.rs:232:9:232:83 | a6 | main.rs:232:55:232:56 | a6 | -| main.rs:232:35:232:82 | SSA phi(a6) | main.rs:232:9:232:83 | a6 | main.rs:232:80:232:81 | a6 | -| main.rs:240:9:240:44 | [match(true)] SSA phi(a7) | main.rs:240:9:240:44 | a7 | main.rs:240:22:240:23 | a7 | -| main.rs:240:9:240:44 | [match(true)] SSA phi(a7) | main.rs:240:9:240:44 | a7 | main.rs:240:42:240:43 | a7 | -| main.rs:252:14:252:51 | [match(true)] SSA phi(a11) | main.rs:252:14:252:51 | a11 | main.rs:252:27:252:29 | a11 | -| main.rs:252:14:252:51 | [match(true)] SSA phi(a11) | main.rs:252:14:252:51 | a11 | main.rs:252:48:252:50 | a11 | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:9:274:109 | a13 | main.rs:274:27:274:29 | a13 | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:9:274:109 | a13 | main.rs:274:35:274:82 | [match(true)] SSA phi(a13) | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:9:274:109 | a13 | main.rs:274:106:274:108 | a13 | -| main.rs:274:35:274:82 | [match(true)] SSA phi(a13) | main.rs:274:9:274:109 | a13 | main.rs:274:54:274:56 | a13 | -| main.rs:274:35:274:82 | [match(true)] SSA phi(a13) | main.rs:274:9:274:109 | a13 | main.rs:274:79:274:81 | a13 | -| main.rs:395:20:395:55 | SSA phi(a9) | main.rs:395:20:395:55 | a9 | main.rs:395:33:395:34 | a9 | -| main.rs:395:20:395:55 | SSA phi(a9) | main.rs:395:20:395:55 | a9 | main.rs:395:53:395:54 | a9 | -| main.rs:611:13:620:5 | SSA phi(x) | main.rs:607:13:607:13 | x | main.rs:613:9:613:9 | x | -| main.rs:611:13:620:5 | SSA phi(x) | main.rs:607:13:607:13 | x | main.rs:617:9:617:9 | x | -| main.rs:748:17:750:9 | SSA phi(x) | main.rs:745:13:745:13 | x | main.rs:746:19:751:5 | x | -| main.rs:748:17:750:9 | SSA phi(x) | main.rs:745:13:745:13 | x | main.rs:749:13:749:13 | x | +| main.rs:245:9:245:44 | SSA phi(a3) | main.rs:245:9:245:44 | a3 | main.rs:245:22:245:23 | a3 | +| main.rs:245:9:245:44 | SSA phi(a3) | main.rs:245:9:245:44 | a3 | main.rs:245:42:245:43 | a3 | +| main.rs:259:9:259:81 | SSA phi(a4) | main.rs:259:9:259:81 | a4 | main.rs:259:28:259:29 | a4 | +| main.rs:259:9:259:81 | SSA phi(a4) | main.rs:259:9:259:81 | a4 | main.rs:259:54:259:55 | a4 | +| main.rs:259:9:259:81 | SSA phi(a4) | main.rs:259:9:259:81 | a4 | main.rs:259:79:259:80 | a4 | +| main.rs:263:9:263:83 | SSA phi(a5) | main.rs:263:9:263:83 | a5 | main.rs:263:10:263:57 | [match(true)] SSA phi(a5) | +| main.rs:263:9:263:83 | SSA phi(a5) | main.rs:263:9:263:83 | a5 | main.rs:263:81:263:82 | a5 | +| main.rs:263:10:263:57 | [match(true)] SSA phi(a5) | main.rs:263:9:263:83 | a5 | main.rs:263:29:263:30 | a5 | +| main.rs:263:10:263:57 | [match(true)] SSA phi(a5) | main.rs:263:9:263:83 | a5 | main.rs:263:55:263:56 | a5 | +| main.rs:267:9:267:83 | SSA phi(a6) | main.rs:267:9:267:83 | a6 | main.rs:267:28:267:29 | a6 | +| main.rs:267:9:267:83 | SSA phi(a6) | main.rs:267:9:267:83 | a6 | main.rs:267:35:267:82 | SSA phi(a6) | +| main.rs:267:35:267:82 | SSA phi(a6) | main.rs:267:9:267:83 | a6 | main.rs:267:55:267:56 | a6 | +| main.rs:267:35:267:82 | SSA phi(a6) | main.rs:267:9:267:83 | a6 | main.rs:267:80:267:81 | a6 | +| main.rs:275:9:275:44 | [match(true)] SSA phi(a7) | main.rs:275:9:275:44 | a7 | main.rs:275:22:275:23 | a7 | +| main.rs:275:9:275:44 | [match(true)] SSA phi(a7) | main.rs:275:9:275:44 | a7 | main.rs:275:42:275:43 | a7 | +| main.rs:287:14:287:51 | [match(true)] SSA phi(a11) | main.rs:287:14:287:51 | a11 | main.rs:287:27:287:29 | a11 | +| main.rs:287:14:287:51 | [match(true)] SSA phi(a11) | main.rs:287:14:287:51 | a11 | main.rs:287:48:287:50 | a11 | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:9:309:109 | a13 | main.rs:309:27:309:29 | a13 | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:9:309:109 | a13 | main.rs:309:35:309:82 | [match(true)] SSA phi(a13) | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:9:309:109 | a13 | main.rs:309:106:309:108 | a13 | +| main.rs:309:35:309:82 | [match(true)] SSA phi(a13) | main.rs:309:9:309:109 | a13 | main.rs:309:54:309:56 | a13 | +| main.rs:309:35:309:82 | [match(true)] SSA phi(a13) | main.rs:309:9:309:109 | a13 | main.rs:309:79:309:81 | a13 | +| main.rs:431:20:431:55 | SSA phi(a9) | main.rs:431:20:431:55 | a9 | main.rs:431:33:431:34 | a9 | +| main.rs:431:20:431:55 | SSA phi(a9) | main.rs:431:20:431:55 | a9 | main.rs:431:53:431:54 | a9 | +| main.rs:647:13:656:5 | SSA phi(x) | main.rs:643:13:643:13 | x | main.rs:649:9:649:9 | x | +| main.rs:647:13:656:5 | SSA phi(x) | main.rs:643:13:643:13 | x | main.rs:653:9:653:9 | x | +| main.rs:784:17:786:9 | SSA phi(x) | main.rs:781:13:781:13 | x | main.rs:782:19:787:5 | x | +| main.rs:784:17:786:9 | SSA phi(x) | main.rs:781:13:781:13 | x | main.rs:785:13:785:13 | x | phiReadNode -| main.rs:116:11:116:12 | SSA phi read(s1) | main.rs:113:9:113:10 | s1 | -| main.rs:627:13:632:5 | SSA phi read(x) | main.rs:625:9:625:9 | x | +| main.rs:116:11:116:11 | SSA phi read(s) | main.rs:113:9:113:9 | s | +| main.rs:663:13:668:5 | SSA phi read(x) | main.rs:661:9:661:9 | x | phiReadNodeFirstRead -| main.rs:116:11:116:12 | SSA phi read(s1) | main.rs:113:9:113:10 | s1 | main.rs:116:11:116:12 | s1 | -| main.rs:627:13:632:5 | SSA phi read(x) | main.rs:625:9:625:9 | x | main.rs:637:19:637:19 | x | -| main.rs:627:13:632:5 | SSA phi read(x) | main.rs:625:9:625:9 | x | main.rs:639:19:639:19 | x | +| main.rs:116:11:116:11 | SSA phi read(s) | main.rs:113:9:113:9 | s | main.rs:116:11:116:11 | s | +| main.rs:663:13:668:5 | SSA phi read(x) | main.rs:661:9:661:9 | x | main.rs:673:19:673:19 | x | +| main.rs:663:13:668:5 | SSA phi read(x) | main.rs:661:9:661:9 | x | main.rs:675:19:675:19 | x | phiReadInput -| main.rs:116:11:116:12 | SSA phi read(s1) | main.rs:113:9:113:10 | s1 | -| main.rs:116:11:116:12 | SSA phi read(s1) | main.rs:116:11:116:12 | SSA read(s1) | -| main.rs:627:13:632:5 | SSA phi read(x) | main.rs:629:19:629:19 | SSA read(x) | -| main.rs:627:13:632:5 | SSA phi read(x) | main.rs:631:19:631:19 | SSA read(x) | +| main.rs:116:11:116:11 | SSA phi read(s) | main.rs:113:9:113:9 | s | +| main.rs:116:11:116:11 | SSA phi read(s) | main.rs:116:11:116:11 | SSA read(s) | +| main.rs:663:13:668:5 | SSA phi read(x) | main.rs:665:19:665:19 | SSA read(x) | +| main.rs:663:13:668:5 | SSA phi read(x) | main.rs:667:19:667:19 | SSA read(x) | ultimateDef -| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:22:210:23 | a3 | -| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:42:210:43 | a3 | -| main.rs:224:9:224:81 | SSA phi(a4) | main.rs:224:28:224:29 | a4 | -| main.rs:224:9:224:81 | SSA phi(a4) | main.rs:224:54:224:55 | a4 | -| main.rs:224:9:224:81 | SSA phi(a4) | main.rs:224:79:224:80 | a4 | -| main.rs:228:9:228:83 | SSA phi(a5) | main.rs:228:29:228:30 | a5 | -| main.rs:228:9:228:83 | SSA phi(a5) | main.rs:228:55:228:56 | a5 | -| main.rs:228:9:228:83 | SSA phi(a5) | main.rs:228:81:228:82 | a5 | -| main.rs:228:10:228:57 | [match(true)] SSA phi(a5) | main.rs:228:29:228:30 | a5 | -| main.rs:228:10:228:57 | [match(true)] SSA phi(a5) | main.rs:228:55:228:56 | a5 | -| main.rs:232:9:232:83 | SSA phi(a6) | main.rs:232:28:232:29 | a6 | -| main.rs:232:9:232:83 | SSA phi(a6) | main.rs:232:55:232:56 | a6 | -| main.rs:232:9:232:83 | SSA phi(a6) | main.rs:232:80:232:81 | a6 | -| main.rs:232:35:232:82 | SSA phi(a6) | main.rs:232:55:232:56 | a6 | -| main.rs:232:35:232:82 | SSA phi(a6) | main.rs:232:80:232:81 | a6 | -| main.rs:240:9:240:44 | [match(true)] SSA phi(a7) | main.rs:240:22:240:23 | a7 | -| main.rs:240:9:240:44 | [match(true)] SSA phi(a7) | main.rs:240:42:240:43 | a7 | -| main.rs:252:14:252:51 | [match(true)] SSA phi(a11) | main.rs:252:27:252:29 | a11 | -| main.rs:252:14:252:51 | [match(true)] SSA phi(a11) | main.rs:252:48:252:50 | a11 | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:27:274:29 | a13 | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:54:274:56 | a13 | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:79:274:81 | a13 | -| main.rs:274:9:274:109 | SSA phi(a13) | main.rs:274:106:274:108 | a13 | -| main.rs:274:35:274:82 | [match(true)] SSA phi(a13) | main.rs:274:54:274:56 | a13 | -| main.rs:274:35:274:82 | [match(true)] SSA phi(a13) | main.rs:274:79:274:81 | a13 | -| main.rs:395:20:395:55 | SSA phi(a9) | main.rs:395:33:395:34 | a9 | -| main.rs:395:20:395:55 | SSA phi(a9) | main.rs:395:53:395:54 | a9 | -| main.rs:611:13:620:5 | SSA phi(x) | main.rs:613:9:613:9 | x | -| main.rs:611:13:620:5 | SSA phi(x) | main.rs:617:9:617:9 | x | -| main.rs:748:17:750:9 | SSA phi(x) | main.rs:746:19:751:5 | x | -| main.rs:748:17:750:9 | SSA phi(x) | main.rs:749:13:749:13 | x | +| main.rs:245:9:245:44 | SSA phi(a3) | main.rs:245:22:245:23 | a3 | +| main.rs:245:9:245:44 | SSA phi(a3) | main.rs:245:42:245:43 | a3 | +| main.rs:259:9:259:81 | SSA phi(a4) | main.rs:259:28:259:29 | a4 | +| main.rs:259:9:259:81 | SSA phi(a4) | main.rs:259:54:259:55 | a4 | +| main.rs:259:9:259:81 | SSA phi(a4) | main.rs:259:79:259:80 | a4 | +| main.rs:263:9:263:83 | SSA phi(a5) | main.rs:263:29:263:30 | a5 | +| main.rs:263:9:263:83 | SSA phi(a5) | main.rs:263:55:263:56 | a5 | +| main.rs:263:9:263:83 | SSA phi(a5) | main.rs:263:81:263:82 | a5 | +| main.rs:263:10:263:57 | [match(true)] SSA phi(a5) | main.rs:263:29:263:30 | a5 | +| main.rs:263:10:263:57 | [match(true)] SSA phi(a5) | main.rs:263:55:263:56 | a5 | +| main.rs:267:9:267:83 | SSA phi(a6) | main.rs:267:28:267:29 | a6 | +| main.rs:267:9:267:83 | SSA phi(a6) | main.rs:267:55:267:56 | a6 | +| main.rs:267:9:267:83 | SSA phi(a6) | main.rs:267:80:267:81 | a6 | +| main.rs:267:35:267:82 | SSA phi(a6) | main.rs:267:55:267:56 | a6 | +| main.rs:267:35:267:82 | SSA phi(a6) | main.rs:267:80:267:81 | a6 | +| main.rs:275:9:275:44 | [match(true)] SSA phi(a7) | main.rs:275:22:275:23 | a7 | +| main.rs:275:9:275:44 | [match(true)] SSA phi(a7) | main.rs:275:42:275:43 | a7 | +| main.rs:287:14:287:51 | [match(true)] SSA phi(a11) | main.rs:287:27:287:29 | a11 | +| main.rs:287:14:287:51 | [match(true)] SSA phi(a11) | main.rs:287:48:287:50 | a11 | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:27:309:29 | a13 | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:54:309:56 | a13 | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:79:309:81 | a13 | +| main.rs:309:9:309:109 | SSA phi(a13) | main.rs:309:106:309:108 | a13 | +| main.rs:309:35:309:82 | [match(true)] SSA phi(a13) | main.rs:309:54:309:56 | a13 | +| main.rs:309:35:309:82 | [match(true)] SSA phi(a13) | main.rs:309:79:309:81 | a13 | +| main.rs:431:20:431:55 | SSA phi(a9) | main.rs:431:33:431:34 | a9 | +| main.rs:431:20:431:55 | SSA phi(a9) | main.rs:431:53:431:54 | a9 | +| main.rs:647:13:656:5 | SSA phi(x) | main.rs:649:9:649:9 | x | +| main.rs:647:13:656:5 | SSA phi(x) | main.rs:653:9:653:9 | x | +| main.rs:784:17:786:9 | SSA phi(x) | main.rs:782:19:787:5 | x | +| main.rs:784:17:786:9 | SSA phi(x) | main.rs:785:13:785:13 | x | assigns | main.rs:20:9:20:10 | x1 | main.rs:20:14:20:16 | "a" | | main.rs:25:13:25:14 | x2 | main.rs:25:18:25:18 | 4 | @@ -727,77 +767,87 @@ assigns | main.rs:91:9:91:10 | s1 | main.rs:91:14:91:41 | Some(...) | | main.rs:100:9:100:9 | x | main.rs:100:13:100:22 | Some(...) | | main.rs:104:13:104:13 | x | main.rs:105:13:105:13 | x | -| main.rs:113:9:113:10 | s1 | main.rs:113:14:113:41 | Some(...) | -| main.rs:122:9:122:10 | x6 | main.rs:122:14:122:20 | Some(...) | -| main.rs:123:9:123:10 | y1 | main.rs:123:14:123:15 | 10 | -| main.rs:139:9:139:15 | numbers | main.rs:139:19:139:35 | TupleExpr | -| main.rs:170:9:170:10 | p2 | main.rs:170:14:170:37 | Point {...} | -| main.rs:184:9:184:11 | msg | main.rs:184:15:184:38 | ...::Hello {...} | -| main.rs:208:9:208:14 | either | main.rs:208:18:208:33 | ...::Left(...) | -| main.rs:222:9:222:10 | tv | main.rs:222:14:222:36 | ...::Second(...) | -| main.rs:238:9:238:14 | either | main.rs:238:18:238:33 | ...::Left(...) | -| main.rs:248:9:248:14 | either | main.rs:248:18:248:33 | ...::Left(...) | -| main.rs:272:9:272:10 | fv | main.rs:272:14:272:35 | ...::Second(...) | -| main.rs:281:9:281:9 | x | main.rs:281:12:281:19 | Some(...) | -| main.rs:289:13:289:13 | x | main.rs:290:13:290:13 | x | -| main.rs:297:9:297:9 | x | main.rs:297:13:297:20 | Some(...) | -| main.rs:308:13:308:13 | x | main.rs:309:13:309:13 | x | -| main.rs:316:9:316:9 | x | main.rs:316:13:316:20 | Some(...) | -| main.rs:334:9:334:9 | x | main.rs:334:13:334:20 | Some(...) | -| main.rs:337:20:337:20 | x | main.rs:338:18:338:18 | x | -| main.rs:348:9:348:9 | x | main.rs:348:13:348:18 | Ok(...) | -| main.rs:364:9:364:9 | x | main.rs:364:13:364:19 | Some(...) | -| main.rs:373:9:373:9 | x | main.rs:373:13:373:20 | Some(...) | -| main.rs:438:9:438:23 | example_closure | main.rs:439:9:440:9 | \|...\| x | -| main.rs:441:9:441:10 | n1 | main.rs:442:9:442:26 | example_closure(...) | -| main.rs:446:9:446:26 | immutable_variable | main.rs:447:5:448:9 | \|...\| x | -| main.rs:449:9:449:10 | n2 | main.rs:450:9:450:29 | immutable_variable(...) | -| main.rs:456:9:456:9 | f | main.rs:457:9:458:9 | \|...\| x | -| main.rs:479:13:479:13 | f | main.rs:480:13:481:13 | \|...\| x | -| main.rs:487:9:487:9 | v | main.rs:487:13:487:41 | &... | -| main.rs:496:13:496:13 | a | main.rs:496:17:496:17 | 0 | -| main.rs:504:13:504:13 | i | main.rs:504:17:504:17 | 1 | -| main.rs:505:9:505:13 | ref_i | main.rs:506:9:506:14 | &mut i | -| main.rs:527:13:527:13 | x | main.rs:527:17:527:17 | 2 | -| main.rs:528:9:528:9 | y | main.rs:529:9:529:28 | mutate_param(...) | -| main.rs:535:13:535:13 | z | main.rs:535:17:535:17 | 4 | -| main.rs:536:9:536:9 | w | main.rs:537:9:537:19 | &mut ... | -| main.rs:549:13:549:13 | x | main.rs:549:17:549:17 | 1 | -| main.rs:550:9:550:9 | y | main.rs:551:9:551:14 | &mut x | -| main.rs:557:9:557:9 | x | main.rs:557:13:557:15 | 100 | -| main.rs:560:9:560:11 | cap | main.rs:560:15:562:5 | \|...\| ... | -| main.rs:568:13:568:13 | x | main.rs:568:17:568:17 | 1 | -| main.rs:571:9:571:16 | closure1 | main.rs:571:20:573:5 | \|...\| ... | -| main.rs:577:13:577:13 | y | main.rs:577:17:577:17 | 2 | -| main.rs:580:13:580:20 | closure2 | main.rs:580:24:582:5 | \|...\| ... | -| main.rs:581:9:581:9 | y | main.rs:581:13:581:13 | 3 | -| main.rs:586:13:586:13 | z | main.rs:586:17:586:17 | 2 | -| main.rs:589:13:589:20 | closure3 | main.rs:589:24:591:5 | \|...\| ... | -| main.rs:597:13:597:13 | i | main.rs:597:22:597:22 | 0 | -| main.rs:598:9:598:13 | block | main.rs:598:17:600:5 | { ... } | -| main.rs:599:9:599:9 | i | main.rs:599:13:599:13 | 1 | -| main.rs:607:13:607:13 | x | main.rs:607:17:607:17 | 1 | -| main.rs:613:9:613:9 | x | main.rs:613:13:613:13 | 2 | -| main.rs:617:9:617:9 | x | main.rs:617:13:617:13 | 3 | -| main.rs:625:9:625:9 | x | main.rs:625:13:625:13 | 1 | -| main.rs:657:17:657:17 | f | main.rs:657:21:660:9 | \|...\| ... | -| main.rs:667:13:667:13 | a | main.rs:667:17:667:35 | MyStruct {...} | -| main.rs:671:5:671:5 | a | main.rs:671:9:671:27 | MyStruct {...} | -| main.rs:676:13:676:13 | a | main.rs:676:17:676:25 | [...] | -| main.rs:680:5:680:5 | a | main.rs:680:9:680:17 | [...] | -| main.rs:685:9:685:9 | x | main.rs:685:13:685:14 | 16 | -| main.rs:689:9:689:9 | z | main.rs:689:13:689:14 | 17 | -| main.rs:704:13:704:13 | a | main.rs:704:17:704:35 | MyStruct {...} | -| main.rs:726:9:726:22 | var_from_macro | main.rs:727:9:727:25 | MacroExpr | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:23:727:24 | 37 | -| main.rs:729:9:729:20 | var_in_macro | main.rs:729:24:729:25 | 33 | -| main.rs:734:15:734:28 | var_in_macro | main.rs:734:15:734:28 | 0 | -| main.rs:740:5:740:5 | x | main.rs:740:9:740:9 | 1 | -| main.rs:745:13:745:13 | x | main.rs:745:17:745:19 | 100 | -| main.rs:746:13:746:15 | cap | main.rs:746:19:751:5 | \|...\| ... | -| main.rs:749:13:749:13 | x | main.rs:749:17:749:19 | 200 | -| main.rs:759:13:759:13 | x | main.rs:759:17:759:24 | Some(...) | -| main.rs:760:13:760:13 | y | main.rs:761:13:767:9 | match x { ... } | -| main.rs:776:13:776:22 | test_alias | main.rs:777:13:777:16 | test | -| main.rs:778:13:778:16 | test | main.rs:779:13:779:24 | test_alias(...) | -| main.rs:787:13:787:13 | x | main.rs:787:17:787:23 | Some(...) | +| main.rs:113:9:113:9 | s | main.rs:113:13:113:40 | Some(...) | +| main.rs:133:9:133:9 | x | main.rs:133:13:133:13 | 1 | +| main.rs:134:12:134:12 | x | main.rs:135:9:135:13 | ... + ... | +| main.rs:136:12:136:12 | x | main.rs:137:9:137:13 | ... + ... | +| main.rs:138:12:138:12 | x | main.rs:139:9:139:13 | ... + ... | +| main.rs:140:12:140:12 | x | main.rs:141:9:141:13 | ... + ... | +| main.rs:142:12:142:12 | x | main.rs:143:9:143:13 | ... + ... | +| main.rs:144:12:144:12 | x | main.rs:145:9:145:13 | ... + ... | +| main.rs:146:12:146:12 | x | main.rs:147:9:147:13 | ... + ... | +| main.rs:157:9:157:10 | x6 | main.rs:157:14:157:20 | Some(...) | +| main.rs:158:9:158:10 | y1 | main.rs:158:14:158:15 | 10 | +| main.rs:174:9:174:15 | numbers | main.rs:174:19:174:35 | TupleExpr | +| main.rs:205:9:205:10 | p2 | main.rs:205:14:205:37 | Point {...} | +| main.rs:219:9:219:11 | msg | main.rs:219:15:219:38 | ...::Hello {...} | +| main.rs:243:9:243:14 | either | main.rs:243:18:243:33 | ...::Left(...) | +| main.rs:257:9:257:10 | tv | main.rs:257:14:257:36 | ...::Second(...) | +| main.rs:273:9:273:14 | either | main.rs:273:18:273:33 | ...::Left(...) | +| main.rs:283:9:283:14 | either | main.rs:283:18:283:33 | ...::Left(...) | +| main.rs:307:9:307:10 | fv | main.rs:307:14:307:35 | ...::Second(...) | +| main.rs:316:9:316:9 | x | main.rs:316:12:316:19 | Some(...) | +| main.rs:324:13:324:13 | x | main.rs:325:13:325:13 | x | +| main.rs:332:9:332:9 | x | main.rs:332:13:332:20 | Some(...) | +| main.rs:343:13:343:13 | x | main.rs:344:13:344:13 | x | +| main.rs:351:9:351:9 | x | main.rs:351:13:351:20 | Some(...) | +| main.rs:369:9:369:9 | x | main.rs:369:13:369:20 | Some(...) | +| main.rs:372:20:372:20 | x | main.rs:373:18:373:18 | x | +| main.rs:383:9:383:9 | x | main.rs:383:13:383:18 | Ok(...) | +| main.rs:399:9:399:9 | x | main.rs:399:13:399:19 | Some(...) | +| main.rs:408:9:408:9 | x | main.rs:408:13:408:20 | Some(...) | +| main.rs:474:9:474:23 | example_closure | main.rs:475:9:476:9 | \|...\| x | +| main.rs:477:9:477:10 | n1 | main.rs:478:9:478:26 | example_closure(...) | +| main.rs:482:9:482:26 | immutable_variable | main.rs:483:5:484:9 | \|...\| x | +| main.rs:485:9:485:10 | n2 | main.rs:486:9:486:29 | immutable_variable(...) | +| main.rs:492:9:492:9 | f | main.rs:493:9:494:9 | \|...\| x | +| main.rs:515:13:515:13 | f | main.rs:516:13:517:13 | \|...\| x | +| main.rs:523:9:523:9 | v | main.rs:523:13:523:41 | &... | +| main.rs:532:13:532:13 | a | main.rs:532:17:532:17 | 0 | +| main.rs:540:13:540:13 | i | main.rs:540:17:540:17 | 1 | +| main.rs:541:9:541:13 | ref_i | main.rs:542:9:542:14 | &mut i | +| main.rs:563:13:563:13 | x | main.rs:563:17:563:17 | 2 | +| main.rs:564:9:564:9 | y | main.rs:565:9:565:28 | mutate_param(...) | +| main.rs:571:13:571:13 | z | main.rs:571:17:571:17 | 4 | +| main.rs:572:9:572:9 | w | main.rs:573:9:573:19 | &mut ... | +| main.rs:585:13:585:13 | x | main.rs:585:17:585:17 | 1 | +| main.rs:586:9:586:9 | y | main.rs:587:9:587:14 | &mut x | +| main.rs:593:9:593:9 | x | main.rs:593:13:593:15 | 100 | +| main.rs:596:9:596:11 | cap | main.rs:596:15:598:5 | \|...\| ... | +| main.rs:604:13:604:13 | x | main.rs:604:17:604:17 | 1 | +| main.rs:607:9:607:16 | closure1 | main.rs:607:20:609:5 | \|...\| ... | +| main.rs:613:13:613:13 | y | main.rs:613:17:613:17 | 2 | +| main.rs:616:13:616:20 | closure2 | main.rs:616:24:618:5 | \|...\| ... | +| main.rs:617:9:617:9 | y | main.rs:617:13:617:13 | 3 | +| main.rs:622:13:622:13 | z | main.rs:622:17:622:17 | 2 | +| main.rs:625:13:625:20 | closure3 | main.rs:625:24:627:5 | \|...\| ... | +| main.rs:633:13:633:13 | i | main.rs:633:22:633:22 | 0 | +| main.rs:634:9:634:13 | block | main.rs:634:17:636:5 | { ... } | +| main.rs:635:9:635:9 | i | main.rs:635:13:635:13 | 1 | +| main.rs:643:13:643:13 | x | main.rs:643:17:643:17 | 1 | +| main.rs:649:9:649:9 | x | main.rs:649:13:649:13 | 2 | +| main.rs:653:9:653:9 | x | main.rs:653:13:653:13 | 3 | +| main.rs:661:9:661:9 | x | main.rs:661:13:661:13 | 1 | +| main.rs:693:17:693:17 | f | main.rs:693:21:696:9 | \|...\| ... | +| main.rs:703:13:703:13 | a | main.rs:703:17:703:35 | MyStruct {...} | +| main.rs:707:5:707:5 | a | main.rs:707:9:707:27 | MyStruct {...} | +| main.rs:712:13:712:13 | a | main.rs:712:17:712:25 | [...] | +| main.rs:716:5:716:5 | a | main.rs:716:9:716:17 | [...] | +| main.rs:721:9:721:9 | x | main.rs:721:13:721:14 | 16 | +| main.rs:725:9:725:9 | z | main.rs:725:13:725:14 | 17 | +| main.rs:740:13:740:13 | a | main.rs:740:17:740:35 | MyStruct {...} | +| main.rs:762:9:762:22 | var_from_macro | main.rs:763:9:763:25 | MacroExpr | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:23:763:24 | 37 | +| main.rs:765:9:765:20 | var_in_macro | main.rs:765:24:765:25 | 33 | +| main.rs:770:15:770:28 | var_in_macro | main.rs:770:15:770:28 | 0 | +| main.rs:776:5:776:5 | x | main.rs:776:9:776:9 | 1 | +| main.rs:781:13:781:13 | x | main.rs:781:17:781:19 | 100 | +| main.rs:782:13:782:15 | cap | main.rs:782:19:787:5 | \|...\| ... | +| main.rs:785:13:785:13 | x | main.rs:785:17:785:19 | 200 | +| main.rs:795:13:795:13 | x | main.rs:795:17:795:24 | Some(...) | +| main.rs:796:13:796:13 | y | main.rs:797:13:803:9 | match x { ... } | +| main.rs:812:13:812:22 | test_alias | main.rs:813:13:813:16 | test | +| main.rs:814:13:814:16 | test | main.rs:815:13:815:24 | test_alias(...) | +| main.rs:823:13:823:13 | x | main.rs:823:17:823:23 | Some(...) | +| main.rs:838:9:838:9 | x | main.rs:838:13:838:13 | 1 | +| main.rs:840:13:840:13 | x | main.rs:840:17:840:17 | 1 | diff --git a/rust/ql/test/library-tests/variables/main.rs b/rust/ql/test/library-tests/variables/main.rs index fe13f89b177..c20f1fe42c3 100644 --- a/rust/ql/test/library-tests/variables/main.rs +++ b/rust/ql/test/library-tests/variables/main.rs @@ -110,11 +110,46 @@ fn let_pattern4() { } fn let_pattern5() { - let s1 = Some(String::from("Hello!")); // s1 + let s = Some(String::from("Hello!")); // s1 - while let Some(ref s2) // s2 - = s1 { // $ read_access=s1 - print_str(s2); // $ read_access=s2 + while let Some(ref s) // s2 + = s { // $ read_access=s1 + print_str(s); // $ read_access=s2 + } +} + +#[rustfmt::skip] +fn let_pattern6() { + if let Some(x) = Some(43) // x1 + && let Ok(x) = // x2 + Ok::<_, ()>(x) // $ read_access=x1 + { + print_i64(x); // $ read_access=x2 + } +} + +#[rustfmt::skip] +fn let_pattern7() { + let x = 1; // x1 + if let x = // x2 + x + 1 // $ read_access=x1 + && let x = // x3 + x + 1 // $ read_access=x2 + && let x = // x4 + x + 1 // $ read_access=x3 + && let x = // x5 + x + 1 // $ read_access=x4 + && let x = // x6 + x + 1 // $ read_access=x5 + && let x = // x7 + x + 1 // $ read_access=x6 + && let x = // x8 + x + 1 // $ read_access=x7 + { + print_i64(x); // $ read_access=x8 + } + else { + print_i64(x); // $ read_access=x1 } } @@ -373,7 +408,8 @@ fn match_pattern16() { let x = Some(32); match x { // $ read_access=x Some(y) // y1 - if let Some(y) = // y2 + if y > 0 && // $ read_access=y1 + let Some(y) = // y2 Some(y) // $ read_access=y1 => print_i64(y), // $ read_access=y2 _ => {}, @@ -798,6 +834,18 @@ mod patterns { } } +fn let_in_block_in_cond() { + let x = 1; // x1 + if { + let x = 1; // x2 + x > 0 // $ read_access=x2 + } { + print_i64(x); // $ SPURIOUS: read_access=x2 $ MISSING: read_access=x1 + } else { + print_i64(x); // $ read_access=x1 + } +} + fn main() { immutable_variable(); mutable_variable(); @@ -808,6 +856,8 @@ fn main() { let_pattern2(); let_pattern3(); let_pattern4(); + let_pattern5(); + let_pattern6(); match_pattern1(); match_pattern2(); match_pattern3(); @@ -842,4 +892,5 @@ fn main() { ref_methodcall_receiver(); macro_invocation(); capture_phi(); + let_in_block_in_cond(); } diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index ea360357d97..b28d16a5c34 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -22,134 +22,146 @@ variable | main.rs:100:9:100:9 | x | | main.rs:101:14:101:14 | x | | main.rs:104:13:104:13 | x | -| main.rs:113:9:113:10 | s1 | -| main.rs:115:24:115:25 | s2 | -| main.rs:122:9:122:10 | x6 | -| main.rs:123:9:123:10 | y1 | -| main.rs:127:14:127:15 | y1 | -| main.rs:139:9:139:15 | numbers | -| main.rs:144:13:144:17 | first | -| main.rs:146:13:146:17 | third | -| main.rs:148:13:148:17 | fifth | -| main.rs:159:13:159:17 | first | -| main.rs:161:13:161:16 | last | -| main.rs:170:9:170:10 | p2 | -| main.rs:174:16:174:17 | x7 | -| main.rs:184:9:184:11 | msg | -| main.rs:189:17:189:27 | id_variable | -| main.rs:194:26:194:27 | id | -| main.rs:208:9:208:14 | either | -| main.rs:210:9:210:44 | a3 | -| main.rs:222:9:222:10 | tv | -| main.rs:224:9:224:81 | a4 | -| main.rs:228:9:228:83 | a5 | -| main.rs:232:9:232:83 | a6 | -| main.rs:238:9:238:14 | either | -| main.rs:240:9:240:44 | a7 | -| main.rs:248:9:248:14 | either | -| main.rs:251:13:251:13 | e | -| main.rs:252:14:252:51 | a11 | -| main.rs:255:33:255:35 | a12 | -| main.rs:272:9:272:10 | fv | -| main.rs:274:9:274:109 | a13 | -| main.rs:281:9:281:9 | x | -| main.rs:282:17:282:17 | x | -| main.rs:289:13:289:13 | x | -| main.rs:297:9:297:9 | x | -| main.rs:298:17:298:17 | x | -| main.rs:301:14:301:14 | x | -| main.rs:308:13:308:13 | x | +| main.rs:113:9:113:9 | s | +| main.rs:115:24:115:24 | s | +| main.rs:123:17:123:17 | x | +| main.rs:124:19:124:19 | x | +| main.rs:133:9:133:9 | x | +| main.rs:134:12:134:12 | x | +| main.rs:136:12:136:12 | x | +| main.rs:138:12:138:12 | x | +| main.rs:140:12:140:12 | x | +| main.rs:142:12:142:12 | x | +| main.rs:144:12:144:12 | x | +| main.rs:146:12:146:12 | x | +| main.rs:157:9:157:10 | x6 | +| main.rs:158:9:158:10 | y1 | +| main.rs:162:14:162:15 | y1 | +| main.rs:174:9:174:15 | numbers | +| main.rs:179:13:179:17 | first | +| main.rs:181:13:181:17 | third | +| main.rs:183:13:183:17 | fifth | +| main.rs:194:13:194:17 | first | +| main.rs:196:13:196:16 | last | +| main.rs:205:9:205:10 | p2 | +| main.rs:209:16:209:17 | x7 | +| main.rs:219:9:219:11 | msg | +| main.rs:224:17:224:27 | id_variable | +| main.rs:229:26:229:27 | id | +| main.rs:243:9:243:14 | either | +| main.rs:245:9:245:44 | a3 | +| main.rs:257:9:257:10 | tv | +| main.rs:259:9:259:81 | a4 | +| main.rs:263:9:263:83 | a5 | +| main.rs:267:9:267:83 | a6 | +| main.rs:273:9:273:14 | either | +| main.rs:275:9:275:44 | a7 | +| main.rs:283:9:283:14 | either | +| main.rs:286:13:286:13 | e | +| main.rs:287:14:287:51 | a11 | +| main.rs:290:33:290:35 | a12 | +| main.rs:307:9:307:10 | fv | +| main.rs:309:9:309:109 | a13 | | main.rs:316:9:316:9 | x | -| main.rs:317:20:317:20 | x | -| main.rs:320:14:320:14 | x | -| main.rs:334:9:334:9 | x | +| main.rs:317:17:317:17 | x | +| main.rs:324:13:324:13 | x | +| main.rs:332:9:332:9 | x | +| main.rs:333:17:333:17 | x | | main.rs:336:14:336:14 | x | -| main.rs:337:20:337:20 | x | -| main.rs:348:9:348:9 | x | -| main.rs:349:16:349:16 | x | -| main.rs:354:20:354:20 | x | -| main.rs:364:9:364:9 | x | -| main.rs:366:18:366:18 | x | -| main.rs:373:9:373:9 | x | -| main.rs:375:14:375:14 | y | -| main.rs:376:25:376:25 | y | -| main.rs:384:5:384:6 | a8 | -| main.rs:386:9:386:10 | b3 | -| main.rs:387:9:387:10 | c1 | -| main.rs:395:20:395:55 | a9 | -| main.rs:402:13:402:15 | a10 | -| main.rs:403:13:403:14 | b4 | -| main.rs:404:13:404:14 | c2 | -| main.rs:425:13:425:15 | a10 | -| main.rs:426:13:426:14 | b4 | -| main.rs:438:9:438:23 | example_closure | -| main.rs:439:10:439:10 | x | -| main.rs:441:9:441:10 | n1 | -| main.rs:446:9:446:26 | immutable_variable | -| main.rs:447:6:447:6 | x | -| main.rs:449:9:449:10 | n2 | -| main.rs:456:9:456:9 | f | -| main.rs:457:10:457:10 | x | -| main.rs:461:10:461:10 | x | -| main.rs:470:14:470:14 | x | -| main.rs:479:13:479:13 | f | -| main.rs:480:14:480:14 | x | -| main.rs:487:9:487:9 | v | -| main.rs:489:9:489:12 | text | -| main.rs:496:13:496:13 | a | -| main.rs:504:13:504:13 | i | -| main.rs:505:9:505:13 | ref_i | -| main.rs:511:17:511:17 | x | -| main.rs:518:22:518:22 | x | -| main.rs:518:38:518:38 | y | -| main.rs:527:13:527:13 | x | -| main.rs:528:9:528:9 | y | -| main.rs:535:13:535:13 | z | -| main.rs:536:9:536:9 | w | -| main.rs:549:13:549:13 | x | -| main.rs:550:9:550:9 | y | -| main.rs:557:9:557:9 | x | -| main.rs:560:9:560:11 | cap | -| main.rs:568:13:568:13 | x | -| main.rs:571:9:571:16 | closure1 | -| main.rs:577:13:577:13 | y | -| main.rs:580:13:580:20 | closure2 | -| main.rs:586:13:586:13 | z | -| main.rs:589:13:589:20 | closure3 | -| main.rs:597:13:597:13 | i | -| main.rs:598:9:598:13 | block | -| main.rs:606:8:606:8 | b | -| main.rs:607:13:607:13 | x | -| main.rs:624:13:624:14 | b1 | -| main.rs:624:23:624:24 | b2 | -| main.rs:625:9:625:9 | x | -| main.rs:648:20:648:23 | self | -| main.rs:652:11:652:14 | self | -| main.rs:656:23:656:26 | self | -| main.rs:657:17:657:17 | f | -| main.rs:657:22:657:22 | n | -| main.rs:667:13:667:13 | a | -| main.rs:676:13:676:13 | a | -| main.rs:685:9:685:9 | x | -| main.rs:689:9:689:9 | z | -| main.rs:698:17:698:20 | self | -| main.rs:704:13:704:13 | a | -| main.rs:726:9:726:22 | var_from_macro | -| main.rs:727:9:727:21 | var_in_macro | -| main.rs:729:9:729:20 | var_in_macro | -| main.rs:734:15:734:28 | var_in_macro | -| main.rs:739:9:739:9 | x | -| main.rs:745:13:745:13 | x | -| main.rs:746:13:746:15 | cap | -| main.rs:746:20:746:20 | b | -| main.rs:759:13:759:13 | x | -| main.rs:760:13:760:13 | y | -| main.rs:762:18:762:18 | y | -| main.rs:769:13:769:16 | N0ne | -| main.rs:776:13:776:22 | test_alias | -| main.rs:778:13:778:16 | test | -| main.rs:787:13:787:13 | x | -| main.rs:789:18:789:18 | x | +| main.rs:343:13:343:13 | x | +| main.rs:351:9:351:9 | x | +| main.rs:352:20:352:20 | x | +| main.rs:355:14:355:14 | x | +| main.rs:369:9:369:9 | x | +| main.rs:371:14:371:14 | x | +| main.rs:372:20:372:20 | x | +| main.rs:383:9:383:9 | x | +| main.rs:384:16:384:16 | x | +| main.rs:389:20:389:20 | x | +| main.rs:399:9:399:9 | x | +| main.rs:401:18:401:18 | x | +| main.rs:408:9:408:9 | x | +| main.rs:410:14:410:14 | y | +| main.rs:412:22:412:22 | y | +| main.rs:420:5:420:6 | a8 | +| main.rs:422:9:422:10 | b3 | +| main.rs:423:9:423:10 | c1 | +| main.rs:431:20:431:55 | a9 | +| main.rs:438:13:438:15 | a10 | +| main.rs:439:13:439:14 | b4 | +| main.rs:440:13:440:14 | c2 | +| main.rs:461:13:461:15 | a10 | +| main.rs:462:13:462:14 | b4 | +| main.rs:474:9:474:23 | example_closure | +| main.rs:475:10:475:10 | x | +| main.rs:477:9:477:10 | n1 | +| main.rs:482:9:482:26 | immutable_variable | +| main.rs:483:6:483:6 | x | +| main.rs:485:9:485:10 | n2 | +| main.rs:492:9:492:9 | f | +| main.rs:493:10:493:10 | x | +| main.rs:497:10:497:10 | x | +| main.rs:506:14:506:14 | x | +| main.rs:515:13:515:13 | f | +| main.rs:516:14:516:14 | x | +| main.rs:523:9:523:9 | v | +| main.rs:525:9:525:12 | text | +| main.rs:532:13:532:13 | a | +| main.rs:540:13:540:13 | i | +| main.rs:541:9:541:13 | ref_i | +| main.rs:547:17:547:17 | x | +| main.rs:554:22:554:22 | x | +| main.rs:554:38:554:38 | y | +| main.rs:563:13:563:13 | x | +| main.rs:564:9:564:9 | y | +| main.rs:571:13:571:13 | z | +| main.rs:572:9:572:9 | w | +| main.rs:585:13:585:13 | x | +| main.rs:586:9:586:9 | y | +| main.rs:593:9:593:9 | x | +| main.rs:596:9:596:11 | cap | +| main.rs:604:13:604:13 | x | +| main.rs:607:9:607:16 | closure1 | +| main.rs:613:13:613:13 | y | +| main.rs:616:13:616:20 | closure2 | +| main.rs:622:13:622:13 | z | +| main.rs:625:13:625:20 | closure3 | +| main.rs:633:13:633:13 | i | +| main.rs:634:9:634:13 | block | +| main.rs:642:8:642:8 | b | +| main.rs:643:13:643:13 | x | +| main.rs:660:13:660:14 | b1 | +| main.rs:660:23:660:24 | b2 | +| main.rs:661:9:661:9 | x | +| main.rs:684:20:684:23 | self | +| main.rs:688:11:688:14 | self | +| main.rs:692:23:692:26 | self | +| main.rs:693:17:693:17 | f | +| main.rs:693:22:693:22 | n | +| main.rs:703:13:703:13 | a | +| main.rs:712:13:712:13 | a | +| main.rs:721:9:721:9 | x | +| main.rs:725:9:725:9 | z | +| main.rs:734:17:734:20 | self | +| main.rs:740:13:740:13 | a | +| main.rs:762:9:762:22 | var_from_macro | +| main.rs:763:9:763:21 | var_in_macro | +| main.rs:765:9:765:20 | var_in_macro | +| main.rs:770:15:770:28 | var_in_macro | +| main.rs:775:9:775:9 | x | +| main.rs:781:13:781:13 | x | +| main.rs:782:13:782:15 | cap | +| main.rs:782:20:782:20 | b | +| main.rs:795:13:795:13 | x | +| main.rs:796:13:796:13 | y | +| main.rs:798:18:798:18 | y | +| main.rs:805:13:805:16 | N0ne | +| main.rs:812:13:812:22 | test_alias | +| main.rs:814:13:814:16 | test | +| main.rs:823:13:823:13 | x | +| main.rs:825:18:825:18 | x | +| main.rs:838:9:838:9 | x | +| main.rs:840:13:840:13 | x | variableAccess | main.rs:7:20:7:20 | s | main.rs:5:14:5:14 | s | | main.rs:12:20:12:20 | i | main.rs:10:14:10:14 | i | @@ -183,218 +195,233 @@ variableAccess | main.rs:105:13:105:13 | x | main.rs:100:9:100:9 | x | | main.rs:106:19:106:19 | x | main.rs:104:13:104:13 | x | | main.rs:109:15:109:15 | x | main.rs:101:14:101:14 | x | -| main.rs:116:11:116:12 | s1 | main.rs:113:9:113:10 | s1 | -| main.rs:117:19:117:20 | s2 | main.rs:115:24:115:25 | s2 | -| main.rs:125:11:125:12 | x6 | main.rs:122:9:122:10 | x6 | -| main.rs:130:23:130:24 | y1 | main.rs:127:14:127:15 | y1 | -| main.rs:135:15:135:16 | y1 | main.rs:123:9:123:10 | y1 | -| main.rs:141:11:141:17 | numbers | main.rs:139:9:139:15 | numbers | -| main.rs:150:23:150:27 | first | main.rs:144:13:144:17 | first | -| main.rs:151:23:151:27 | third | main.rs:146:13:146:17 | third | -| main.rs:152:23:152:27 | fifth | main.rs:148:13:148:17 | fifth | -| main.rs:156:11:156:17 | numbers | main.rs:139:9:139:15 | numbers | -| main.rs:163:23:163:27 | first | main.rs:159:13:159:17 | first | -| main.rs:164:23:164:26 | last | main.rs:161:13:161:16 | last | -| main.rs:172:11:172:12 | p2 | main.rs:170:9:170:10 | p2 | -| main.rs:175:24:175:25 | x7 | main.rs:174:16:174:17 | x7 | -| main.rs:186:11:186:13 | msg | main.rs:184:9:184:11 | msg | -| main.rs:190:24:190:34 | id_variable | main.rs:189:17:189:27 | id_variable | -| main.rs:197:23:197:24 | id | main.rs:194:26:194:27 | id | -| main.rs:209:11:209:16 | either | main.rs:208:9:208:14 | either | -| main.rs:211:26:211:27 | a3 | main.rs:210:9:210:44 | a3 | -| main.rs:223:11:223:12 | tv | main.rs:222:9:222:10 | tv | -| main.rs:225:26:225:27 | a4 | main.rs:224:9:224:81 | a4 | -| main.rs:227:11:227:12 | tv | main.rs:222:9:222:10 | tv | -| main.rs:229:26:229:27 | a5 | main.rs:228:9:228:83 | a5 | -| main.rs:231:11:231:12 | tv | main.rs:222:9:222:10 | tv | -| main.rs:233:26:233:27 | a6 | main.rs:232:9:232:83 | a6 | -| main.rs:239:11:239:16 | either | main.rs:238:9:238:14 | either | -| main.rs:241:16:241:17 | a7 | main.rs:240:9:240:44 | a7 | -| main.rs:242:26:242:27 | a7 | main.rs:240:9:240:44 | a7 | -| main.rs:250:11:250:16 | either | main.rs:248:9:248:14 | either | -| main.rs:254:23:254:25 | a11 | main.rs:252:14:252:51 | a11 | -| main.rs:256:15:256:15 | e | main.rs:251:13:251:13 | e | -| main.rs:257:28:257:30 | a12 | main.rs:255:33:255:35 | a12 | -| main.rs:273:11:273:12 | fv | main.rs:272:9:272:10 | fv | -| main.rs:275:26:275:28 | a13 | main.rs:274:9:274:109 | a13 | -| main.rs:283:7:283:7 | x | main.rs:281:9:281:9 | x | -| main.rs:285:5:285:5 | x | main.rs:282:17:282:17 | x | -| main.rs:287:19:287:19 | x | main.rs:282:17:282:17 | x | -| main.rs:290:13:290:13 | x | main.rs:281:9:281:9 | x | -| main.rs:291:19:291:19 | x | main.rs:289:13:289:13 | x | -| main.rs:299:7:299:7 | x | main.rs:297:9:297:9 | x | -| main.rs:302:12:302:12 | x | main.rs:298:17:298:17 | x | -| main.rs:304:5:304:5 | x | main.rs:301:14:301:14 | x | -| main.rs:306:19:306:19 | x | main.rs:301:14:301:14 | x | -| main.rs:309:13:309:13 | x | main.rs:297:9:297:9 | x | -| main.rs:310:19:310:19 | x | main.rs:308:13:308:13 | x | +| main.rs:116:11:116:11 | s | main.rs:113:9:113:9 | s | +| main.rs:117:19:117:19 | s | main.rs:115:24:115:24 | s | +| main.rs:125:25:125:25 | x | main.rs:123:17:123:17 | x | +| main.rs:127:19:127:19 | x | main.rs:124:19:124:19 | x | +| main.rs:135:9:135:9 | x | main.rs:133:9:133:9 | x | +| main.rs:137:9:137:9 | x | main.rs:134:12:134:12 | x | +| main.rs:139:9:139:9 | x | main.rs:136:12:136:12 | x | +| main.rs:141:9:141:9 | x | main.rs:138:12:138:12 | x | +| main.rs:143:9:143:9 | x | main.rs:140:12:140:12 | x | +| main.rs:145:9:145:9 | x | main.rs:142:12:142:12 | x | +| main.rs:147:9:147:9 | x | main.rs:144:12:144:12 | x | +| main.rs:149:19:149:19 | x | main.rs:146:12:146:12 | x | +| main.rs:152:19:152:19 | x | main.rs:133:9:133:9 | x | +| main.rs:160:11:160:12 | x6 | main.rs:157:9:157:10 | x6 | +| main.rs:165:23:165:24 | y1 | main.rs:162:14:162:15 | y1 | +| main.rs:170:15:170:16 | y1 | main.rs:158:9:158:10 | y1 | +| main.rs:176:11:176:17 | numbers | main.rs:174:9:174:15 | numbers | +| main.rs:185:23:185:27 | first | main.rs:179:13:179:17 | first | +| main.rs:186:23:186:27 | third | main.rs:181:13:181:17 | third | +| main.rs:187:23:187:27 | fifth | main.rs:183:13:183:17 | fifth | +| main.rs:191:11:191:17 | numbers | main.rs:174:9:174:15 | numbers | +| main.rs:198:23:198:27 | first | main.rs:194:13:194:17 | first | +| main.rs:199:23:199:26 | last | main.rs:196:13:196:16 | last | +| main.rs:207:11:207:12 | p2 | main.rs:205:9:205:10 | p2 | +| main.rs:210:24:210:25 | x7 | main.rs:209:16:209:17 | x7 | +| main.rs:221:11:221:13 | msg | main.rs:219:9:219:11 | msg | +| main.rs:225:24:225:34 | id_variable | main.rs:224:17:224:27 | id_variable | +| main.rs:232:23:232:24 | id | main.rs:229:26:229:27 | id | +| main.rs:244:11:244:16 | either | main.rs:243:9:243:14 | either | +| main.rs:246:26:246:27 | a3 | main.rs:245:9:245:44 | a3 | +| main.rs:258:11:258:12 | tv | main.rs:257:9:257:10 | tv | +| main.rs:260:26:260:27 | a4 | main.rs:259:9:259:81 | a4 | +| main.rs:262:11:262:12 | tv | main.rs:257:9:257:10 | tv | +| main.rs:264:26:264:27 | a5 | main.rs:263:9:263:83 | a5 | +| main.rs:266:11:266:12 | tv | main.rs:257:9:257:10 | tv | +| main.rs:268:26:268:27 | a6 | main.rs:267:9:267:83 | a6 | +| main.rs:274:11:274:16 | either | main.rs:273:9:273:14 | either | +| main.rs:276:16:276:17 | a7 | main.rs:275:9:275:44 | a7 | +| main.rs:277:26:277:27 | a7 | main.rs:275:9:275:44 | a7 | +| main.rs:285:11:285:16 | either | main.rs:283:9:283:14 | either | +| main.rs:289:23:289:25 | a11 | main.rs:287:14:287:51 | a11 | +| main.rs:291:15:291:15 | e | main.rs:286:13:286:13 | e | +| main.rs:292:28:292:30 | a12 | main.rs:290:33:290:35 | a12 | +| main.rs:308:11:308:12 | fv | main.rs:307:9:307:10 | fv | +| main.rs:310:26:310:28 | a13 | main.rs:309:9:309:109 | a13 | | main.rs:318:7:318:7 | x | main.rs:316:9:316:9 | x | -| main.rs:321:12:321:12 | x | main.rs:317:20:317:20 | x | -| main.rs:323:5:323:5 | x | main.rs:320:14:320:14 | x | -| main.rs:325:19:325:19 | x | main.rs:320:14:320:14 | x | -| main.rs:329:15:329:15 | x | main.rs:316:9:316:9 | x | -| main.rs:335:11:335:11 | x | main.rs:334:9:334:9 | x | -| main.rs:338:18:338:18 | x | main.rs:336:14:336:14 | x | -| main.rs:339:19:339:19 | x | main.rs:337:20:337:20 | x | -| main.rs:343:15:343:15 | x | main.rs:334:9:334:9 | x | -| main.rs:350:7:350:7 | x | main.rs:348:9:348:9 | x | -| main.rs:352:19:352:19 | x | main.rs:349:16:349:16 | x | -| main.rs:355:7:355:7 | x | main.rs:348:9:348:9 | x | -| main.rs:357:19:357:19 | x | main.rs:354:20:354:20 | x | -| main.rs:359:19:359:19 | x | main.rs:348:9:348:9 | x | -| main.rs:365:11:365:11 | x | main.rs:364:9:364:9 | x | -| main.rs:367:20:367:20 | x | main.rs:366:18:366:18 | x | -| main.rs:374:11:374:11 | x | main.rs:373:9:373:9 | x | -| main.rs:377:22:377:22 | y | main.rs:375:14:375:14 | y | -| main.rs:378:26:378:26 | y | main.rs:376:25:376:25 | y | -| main.rs:390:15:390:16 | a8 | main.rs:384:5:384:6 | a8 | -| main.rs:391:15:391:16 | b3 | main.rs:386:9:386:10 | b3 | -| main.rs:392:15:392:16 | c1 | main.rs:387:9:387:10 | c1 | -| main.rs:397:15:397:16 | a9 | main.rs:395:20:395:55 | a9 | -| main.rs:406:15:406:17 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:407:15:407:16 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:408:15:408:16 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:411:9:411:10 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:412:9:412:10 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:413:9:413:11 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:415:9:415:11 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:416:9:416:10 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:417:9:417:10 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:419:15:419:17 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:420:15:420:16 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:421:15:421:16 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:428:23:428:25 | a10 | main.rs:425:13:425:15 | a10 | -| main.rs:429:23:429:24 | b4 | main.rs:426:13:426:14 | b4 | -| main.rs:433:15:433:17 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:434:15:434:16 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:440:9:440:9 | x | main.rs:439:10:439:10 | x | -| main.rs:442:9:442:23 | example_closure | main.rs:438:9:438:23 | example_closure | -| main.rs:443:15:443:16 | n1 | main.rs:441:9:441:10 | n1 | -| main.rs:448:9:448:9 | x | main.rs:447:6:447:6 | x | -| main.rs:450:9:450:26 | immutable_variable | main.rs:446:9:446:26 | immutable_variable | -| main.rs:451:15:451:16 | n2 | main.rs:449:9:449:10 | n2 | -| main.rs:458:9:458:9 | x | main.rs:457:10:457:10 | x | -| main.rs:459:15:459:15 | f | main.rs:456:9:456:9 | f | -| main.rs:463:9:463:9 | x | main.rs:461:10:461:10 | x | -| main.rs:466:15:466:15 | f | main.rs:456:9:456:9 | f | -| main.rs:472:17:472:17 | x | main.rs:470:14:470:14 | x | -| main.rs:481:13:481:13 | x | main.rs:480:14:480:14 | x | -| main.rs:482:19:482:19 | f | main.rs:479:13:479:13 | f | -| main.rs:490:12:490:12 | v | main.rs:487:9:487:9 | v | -| main.rs:491:19:491:22 | text | main.rs:489:9:489:12 | text | -| main.rs:497:5:497:5 | a | main.rs:496:13:496:13 | a | -| main.rs:498:15:498:15 | a | main.rs:496:13:496:13 | a | -| main.rs:499:11:499:11 | a | main.rs:496:13:496:13 | a | -| main.rs:500:15:500:15 | a | main.rs:496:13:496:13 | a | -| main.rs:506:14:506:14 | i | main.rs:504:13:504:13 | i | -| main.rs:507:6:507:10 | ref_i | main.rs:505:9:505:13 | ref_i | -| main.rs:508:15:508:15 | i | main.rs:504:13:504:13 | i | -| main.rs:512:6:512:6 | x | main.rs:511:17:511:17 | x | -| main.rs:513:10:513:10 | x | main.rs:511:17:511:17 | x | -| main.rs:514:10:514:10 | x | main.rs:511:17:511:17 | x | -| main.rs:515:12:515:12 | x | main.rs:511:17:511:17 | x | -| main.rs:519:6:519:6 | x | main.rs:518:22:518:22 | x | -| main.rs:520:10:520:10 | x | main.rs:518:22:518:22 | x | -| main.rs:521:10:521:10 | x | main.rs:518:22:518:22 | x | -| main.rs:522:6:522:6 | y | main.rs:518:38:518:38 | y | -| main.rs:523:9:523:9 | x | main.rs:518:22:518:22 | x | -| main.rs:529:27:529:27 | x | main.rs:527:13:527:13 | x | -| main.rs:530:6:530:6 | y | main.rs:528:9:528:9 | y | -| main.rs:533:15:533:15 | x | main.rs:527:13:527:13 | x | -| main.rs:537:19:537:19 | x | main.rs:527:13:527:13 | x | -| main.rs:539:14:539:14 | z | main.rs:535:13:535:13 | z | -| main.rs:540:9:540:9 | w | main.rs:536:9:536:9 | w | -| main.rs:542:7:542:7 | w | main.rs:536:9:536:9 | w | -| main.rs:545:15:545:15 | z | main.rs:535:13:535:13 | z | -| main.rs:551:14:551:14 | x | main.rs:549:13:549:13 | x | -| main.rs:552:6:552:6 | y | main.rs:550:9:550:9 | y | -| main.rs:553:15:553:15 | x | main.rs:549:13:549:13 | x | -| main.rs:561:19:561:19 | x | main.rs:557:9:557:9 | x | -| main.rs:563:5:563:7 | cap | main.rs:560:9:560:11 | cap | -| main.rs:564:15:564:15 | x | main.rs:557:9:557:9 | x | -| main.rs:572:19:572:19 | x | main.rs:568:13:568:13 | x | -| main.rs:574:5:574:12 | closure1 | main.rs:571:9:571:16 | closure1 | -| main.rs:575:15:575:15 | x | main.rs:568:13:568:13 | x | -| main.rs:581:9:581:9 | y | main.rs:577:13:577:13 | y | -| main.rs:583:5:583:12 | closure2 | main.rs:580:13:580:20 | closure2 | -| main.rs:584:15:584:15 | y | main.rs:577:13:577:13 | y | -| main.rs:590:9:590:9 | z | main.rs:586:13:586:13 | z | -| main.rs:592:5:592:12 | closure3 | main.rs:589:13:589:20 | closure3 | -| main.rs:593:15:593:15 | z | main.rs:586:13:586:13 | z | -| main.rs:599:9:599:9 | i | main.rs:597:13:597:13 | i | -| main.rs:602:5:602:9 | block | main.rs:598:9:598:13 | block | -| main.rs:603:15:603:15 | i | main.rs:597:13:597:13 | i | -| main.rs:608:15:608:15 | x | main.rs:607:13:607:13 | x | -| main.rs:609:15:609:15 | x | main.rs:607:13:607:13 | x | -| main.rs:611:16:611:16 | b | main.rs:606:8:606:8 | b | -| main.rs:613:9:613:9 | x | main.rs:607:13:607:13 | x | -| main.rs:614:19:614:19 | x | main.rs:607:13:607:13 | x | -| main.rs:615:19:615:19 | x | main.rs:607:13:607:13 | x | -| main.rs:617:9:617:9 | x | main.rs:607:13:607:13 | x | -| main.rs:618:19:618:19 | x | main.rs:607:13:607:13 | x | -| main.rs:619:19:619:19 | x | main.rs:607:13:607:13 | x | -| main.rs:621:15:621:15 | x | main.rs:607:13:607:13 | x | -| main.rs:627:16:627:17 | b1 | main.rs:624:13:624:14 | b1 | -| main.rs:629:19:629:19 | x | main.rs:625:9:625:9 | x | -| main.rs:631:19:631:19 | x | main.rs:625:9:625:9 | x | -| main.rs:635:16:635:17 | b2 | main.rs:624:23:624:24 | b2 | -| main.rs:637:19:637:19 | x | main.rs:625:9:625:9 | x | -| main.rs:639:19:639:19 | x | main.rs:625:9:625:9 | x | -| main.rs:649:16:649:19 | self | main.rs:648:20:648:23 | self | -| main.rs:653:9:653:12 | self | main.rs:652:11:652:14 | self | -| main.rs:659:13:659:16 | self | main.rs:656:23:656:26 | self | -| main.rs:659:25:659:25 | n | main.rs:657:22:657:22 | n | -| main.rs:661:9:661:9 | f | main.rs:657:17:657:17 | f | -| main.rs:662:9:662:9 | f | main.rs:657:17:657:17 | f | -| main.rs:668:15:668:15 | a | main.rs:667:13:667:13 | a | -| main.rs:669:5:669:5 | a | main.rs:667:13:667:13 | a | -| main.rs:670:15:670:15 | a | main.rs:667:13:667:13 | a | -| main.rs:671:5:671:5 | a | main.rs:667:13:667:13 | a | -| main.rs:672:15:672:15 | a | main.rs:667:13:667:13 | a | -| main.rs:677:15:677:15 | a | main.rs:676:13:676:13 | a | -| main.rs:678:5:678:5 | a | main.rs:676:13:676:13 | a | -| main.rs:679:15:679:15 | a | main.rs:676:13:676:13 | a | -| main.rs:680:5:680:5 | a | main.rs:676:13:676:13 | a | -| main.rs:681:15:681:15 | a | main.rs:676:13:676:13 | a | -| main.rs:686:20:686:20 | x | main.rs:685:9:685:9 | x | -| main.rs:687:15:687:15 | x | main.rs:685:9:685:9 | x | -| main.rs:690:20:690:20 | z | main.rs:689:9:689:9 | z | -| main.rs:699:10:699:13 | self | main.rs:698:17:698:20 | self | -| main.rs:705:5:705:5 | a | main.rs:704:13:704:13 | a | -| main.rs:708:15:708:15 | a | main.rs:704:13:704:13 | a | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:9:727:21 | var_in_macro | -| main.rs:728:15:728:28 | var_from_macro | main.rs:726:9:726:22 | var_from_macro | -| main.rs:734:30:734:41 | var_in_macro | main.rs:734:15:734:28 | var_in_macro | -| main.rs:735:15:735:26 | var_in_macro | main.rs:729:9:729:20 | var_in_macro | -| main.rs:740:5:740:5 | x | main.rs:739:9:739:9 | x | -| main.rs:741:15:741:15 | x | main.rs:739:9:739:9 | x | -| main.rs:748:20:748:20 | b | main.rs:746:20:746:20 | b | -| main.rs:749:13:749:13 | x | main.rs:745:13:745:13 | x | -| main.rs:752:5:752:7 | cap | main.rs:746:13:746:15 | cap | -| main.rs:753:15:753:15 | x | main.rs:745:13:745:13 | x | -| main.rs:761:19:761:19 | x | main.rs:759:13:759:13 | x | -| main.rs:768:15:768:15 | y | main.rs:760:13:760:13 | y | -| main.rs:770:17:770:20 | N0ne | main.rs:769:13:769:16 | N0ne | -| main.rs:779:13:779:22 | test_alias | main.rs:776:13:776:22 | test_alias | -| main.rs:780:9:780:12 | test | main.rs:778:13:778:16 | test | -| main.rs:788:15:788:15 | x | main.rs:787:13:787:13 | x | -| main.rs:790:20:790:20 | x | main.rs:789:18:789:18 | x | -| main.rs:793:15:793:15 | x | main.rs:787:13:787:13 | x | +| main.rs:320:5:320:5 | x | main.rs:317:17:317:17 | x | +| main.rs:322:19:322:19 | x | main.rs:317:17:317:17 | x | +| main.rs:325:13:325:13 | x | main.rs:316:9:316:9 | x | +| main.rs:326:19:326:19 | x | main.rs:324:13:324:13 | x | +| main.rs:334:7:334:7 | x | main.rs:332:9:332:9 | x | +| main.rs:337:12:337:12 | x | main.rs:333:17:333:17 | x | +| main.rs:339:5:339:5 | x | main.rs:336:14:336:14 | x | +| main.rs:341:19:341:19 | x | main.rs:336:14:336:14 | x | +| main.rs:344:13:344:13 | x | main.rs:332:9:332:9 | x | +| main.rs:345:19:345:19 | x | main.rs:343:13:343:13 | x | +| main.rs:353:7:353:7 | x | main.rs:351:9:351:9 | x | +| main.rs:356:12:356:12 | x | main.rs:352:20:352:20 | x | +| main.rs:358:5:358:5 | x | main.rs:355:14:355:14 | x | +| main.rs:360:19:360:19 | x | main.rs:355:14:355:14 | x | +| main.rs:364:15:364:15 | x | main.rs:351:9:351:9 | x | +| main.rs:370:11:370:11 | x | main.rs:369:9:369:9 | x | +| main.rs:373:18:373:18 | x | main.rs:371:14:371:14 | x | +| main.rs:374:19:374:19 | x | main.rs:372:20:372:20 | x | +| main.rs:378:15:378:15 | x | main.rs:369:9:369:9 | x | +| main.rs:385:7:385:7 | x | main.rs:383:9:383:9 | x | +| main.rs:387:19:387:19 | x | main.rs:384:16:384:16 | x | +| main.rs:390:7:390:7 | x | main.rs:383:9:383:9 | x | +| main.rs:392:19:392:19 | x | main.rs:389:20:389:20 | x | +| main.rs:394:19:394:19 | x | main.rs:383:9:383:9 | x | +| main.rs:400:11:400:11 | x | main.rs:399:9:399:9 | x | +| main.rs:402:20:402:20 | x | main.rs:401:18:401:18 | x | +| main.rs:409:11:409:11 | x | main.rs:408:9:408:9 | x | +| main.rs:411:16:411:16 | y | main.rs:410:14:410:14 | y | +| main.rs:413:22:413:22 | y | main.rs:410:14:410:14 | y | +| main.rs:414:26:414:26 | y | main.rs:412:22:412:22 | y | +| main.rs:426:15:426:16 | a8 | main.rs:420:5:420:6 | a8 | +| main.rs:427:15:427:16 | b3 | main.rs:422:9:422:10 | b3 | +| main.rs:428:15:428:16 | c1 | main.rs:423:9:423:10 | c1 | +| main.rs:433:15:433:16 | a9 | main.rs:431:20:431:55 | a9 | +| main.rs:442:15:442:17 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:443:15:443:16 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:444:15:444:16 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:447:9:447:10 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:448:9:448:10 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:449:9:449:11 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:451:9:451:11 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:452:9:452:10 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:453:9:453:10 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:455:15:455:17 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:456:15:456:16 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:457:15:457:16 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:464:23:464:25 | a10 | main.rs:461:13:461:15 | a10 | +| main.rs:465:23:465:24 | b4 | main.rs:462:13:462:14 | b4 | +| main.rs:469:15:469:17 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:470:15:470:16 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:476:9:476:9 | x | main.rs:475:10:475:10 | x | +| main.rs:478:9:478:23 | example_closure | main.rs:474:9:474:23 | example_closure | +| main.rs:479:15:479:16 | n1 | main.rs:477:9:477:10 | n1 | +| main.rs:484:9:484:9 | x | main.rs:483:6:483:6 | x | +| main.rs:486:9:486:26 | immutable_variable | main.rs:482:9:482:26 | immutable_variable | +| main.rs:487:15:487:16 | n2 | main.rs:485:9:485:10 | n2 | +| main.rs:494:9:494:9 | x | main.rs:493:10:493:10 | x | +| main.rs:495:15:495:15 | f | main.rs:492:9:492:9 | f | +| main.rs:499:9:499:9 | x | main.rs:497:10:497:10 | x | +| main.rs:502:15:502:15 | f | main.rs:492:9:492:9 | f | +| main.rs:508:17:508:17 | x | main.rs:506:14:506:14 | x | +| main.rs:517:13:517:13 | x | main.rs:516:14:516:14 | x | +| main.rs:518:19:518:19 | f | main.rs:515:13:515:13 | f | +| main.rs:526:12:526:12 | v | main.rs:523:9:523:9 | v | +| main.rs:527:19:527:22 | text | main.rs:525:9:525:12 | text | +| main.rs:533:5:533:5 | a | main.rs:532:13:532:13 | a | +| main.rs:534:15:534:15 | a | main.rs:532:13:532:13 | a | +| main.rs:535:11:535:11 | a | main.rs:532:13:532:13 | a | +| main.rs:536:15:536:15 | a | main.rs:532:13:532:13 | a | +| main.rs:542:14:542:14 | i | main.rs:540:13:540:13 | i | +| main.rs:543:6:543:10 | ref_i | main.rs:541:9:541:13 | ref_i | +| main.rs:544:15:544:15 | i | main.rs:540:13:540:13 | i | +| main.rs:548:6:548:6 | x | main.rs:547:17:547:17 | x | +| main.rs:549:10:549:10 | x | main.rs:547:17:547:17 | x | +| main.rs:550:10:550:10 | x | main.rs:547:17:547:17 | x | +| main.rs:551:12:551:12 | x | main.rs:547:17:547:17 | x | +| main.rs:555:6:555:6 | x | main.rs:554:22:554:22 | x | +| main.rs:556:10:556:10 | x | main.rs:554:22:554:22 | x | +| main.rs:557:10:557:10 | x | main.rs:554:22:554:22 | x | +| main.rs:558:6:558:6 | y | main.rs:554:38:554:38 | y | +| main.rs:559:9:559:9 | x | main.rs:554:22:554:22 | x | +| main.rs:565:27:565:27 | x | main.rs:563:13:563:13 | x | +| main.rs:566:6:566:6 | y | main.rs:564:9:564:9 | y | +| main.rs:569:15:569:15 | x | main.rs:563:13:563:13 | x | +| main.rs:573:19:573:19 | x | main.rs:563:13:563:13 | x | +| main.rs:575:14:575:14 | z | main.rs:571:13:571:13 | z | +| main.rs:576:9:576:9 | w | main.rs:572:9:572:9 | w | +| main.rs:578:7:578:7 | w | main.rs:572:9:572:9 | w | +| main.rs:581:15:581:15 | z | main.rs:571:13:571:13 | z | +| main.rs:587:14:587:14 | x | main.rs:585:13:585:13 | x | +| main.rs:588:6:588:6 | y | main.rs:586:9:586:9 | y | +| main.rs:589:15:589:15 | x | main.rs:585:13:585:13 | x | +| main.rs:597:19:597:19 | x | main.rs:593:9:593:9 | x | +| main.rs:599:5:599:7 | cap | main.rs:596:9:596:11 | cap | +| main.rs:600:15:600:15 | x | main.rs:593:9:593:9 | x | +| main.rs:608:19:608:19 | x | main.rs:604:13:604:13 | x | +| main.rs:610:5:610:12 | closure1 | main.rs:607:9:607:16 | closure1 | +| main.rs:611:15:611:15 | x | main.rs:604:13:604:13 | x | +| main.rs:617:9:617:9 | y | main.rs:613:13:613:13 | y | +| main.rs:619:5:619:12 | closure2 | main.rs:616:13:616:20 | closure2 | +| main.rs:620:15:620:15 | y | main.rs:613:13:613:13 | y | +| main.rs:626:9:626:9 | z | main.rs:622:13:622:13 | z | +| main.rs:628:5:628:12 | closure3 | main.rs:625:13:625:20 | closure3 | +| main.rs:629:15:629:15 | z | main.rs:622:13:622:13 | z | +| main.rs:635:9:635:9 | i | main.rs:633:13:633:13 | i | +| main.rs:638:5:638:9 | block | main.rs:634:9:634:13 | block | +| main.rs:639:15:639:15 | i | main.rs:633:13:633:13 | i | +| main.rs:644:15:644:15 | x | main.rs:643:13:643:13 | x | +| main.rs:645:15:645:15 | x | main.rs:643:13:643:13 | x | +| main.rs:647:16:647:16 | b | main.rs:642:8:642:8 | b | +| main.rs:649:9:649:9 | x | main.rs:643:13:643:13 | x | +| main.rs:650:19:650:19 | x | main.rs:643:13:643:13 | x | +| main.rs:651:19:651:19 | x | main.rs:643:13:643:13 | x | +| main.rs:653:9:653:9 | x | main.rs:643:13:643:13 | x | +| main.rs:654:19:654:19 | x | main.rs:643:13:643:13 | x | +| main.rs:655:19:655:19 | x | main.rs:643:13:643:13 | x | +| main.rs:657:15:657:15 | x | main.rs:643:13:643:13 | x | +| main.rs:663:16:663:17 | b1 | main.rs:660:13:660:14 | b1 | +| main.rs:665:19:665:19 | x | main.rs:661:9:661:9 | x | +| main.rs:667:19:667:19 | x | main.rs:661:9:661:9 | x | +| main.rs:671:16:671:17 | b2 | main.rs:660:23:660:24 | b2 | +| main.rs:673:19:673:19 | x | main.rs:661:9:661:9 | x | +| main.rs:675:19:675:19 | x | main.rs:661:9:661:9 | x | +| main.rs:685:16:685:19 | self | main.rs:684:20:684:23 | self | +| main.rs:689:9:689:12 | self | main.rs:688:11:688:14 | self | +| main.rs:695:13:695:16 | self | main.rs:692:23:692:26 | self | +| main.rs:695:25:695:25 | n | main.rs:693:22:693:22 | n | +| main.rs:697:9:697:9 | f | main.rs:693:17:693:17 | f | +| main.rs:698:9:698:9 | f | main.rs:693:17:693:17 | f | +| main.rs:704:15:704:15 | a | main.rs:703:13:703:13 | a | +| main.rs:705:5:705:5 | a | main.rs:703:13:703:13 | a | +| main.rs:706:15:706:15 | a | main.rs:703:13:703:13 | a | +| main.rs:707:5:707:5 | a | main.rs:703:13:703:13 | a | +| main.rs:708:15:708:15 | a | main.rs:703:13:703:13 | a | +| main.rs:713:15:713:15 | a | main.rs:712:13:712:13 | a | +| main.rs:714:5:714:5 | a | main.rs:712:13:712:13 | a | +| main.rs:715:15:715:15 | a | main.rs:712:13:712:13 | a | +| main.rs:716:5:716:5 | a | main.rs:712:13:712:13 | a | +| main.rs:717:15:717:15 | a | main.rs:712:13:712:13 | a | +| main.rs:722:20:722:20 | x | main.rs:721:9:721:9 | x | +| main.rs:723:15:723:15 | x | main.rs:721:9:721:9 | x | +| main.rs:726:20:726:20 | z | main.rs:725:9:725:9 | z | +| main.rs:735:10:735:13 | self | main.rs:734:17:734:20 | self | +| main.rs:741:5:741:5 | a | main.rs:740:13:740:13 | a | +| main.rs:744:15:744:15 | a | main.rs:740:13:740:13 | a | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:9:763:21 | var_in_macro | +| main.rs:764:15:764:28 | var_from_macro | main.rs:762:9:762:22 | var_from_macro | +| main.rs:770:30:770:41 | var_in_macro | main.rs:770:15:770:28 | var_in_macro | +| main.rs:771:15:771:26 | var_in_macro | main.rs:765:9:765:20 | var_in_macro | +| main.rs:776:5:776:5 | x | main.rs:775:9:775:9 | x | +| main.rs:777:15:777:15 | x | main.rs:775:9:775:9 | x | +| main.rs:784:20:784:20 | b | main.rs:782:20:782:20 | b | +| main.rs:785:13:785:13 | x | main.rs:781:13:781:13 | x | +| main.rs:788:5:788:7 | cap | main.rs:782:13:782:15 | cap | +| main.rs:789:15:789:15 | x | main.rs:781:13:781:13 | x | +| main.rs:797:19:797:19 | x | main.rs:795:13:795:13 | x | +| main.rs:804:15:804:15 | y | main.rs:796:13:796:13 | y | +| main.rs:806:17:806:20 | N0ne | main.rs:805:13:805:16 | N0ne | +| main.rs:815:13:815:22 | test_alias | main.rs:812:13:812:22 | test_alias | +| main.rs:816:9:816:12 | test | main.rs:814:13:814:16 | test | +| main.rs:824:15:824:15 | x | main.rs:823:13:823:13 | x | +| main.rs:826:20:826:20 | x | main.rs:825:18:825:18 | x | +| main.rs:829:15:829:15 | x | main.rs:823:13:823:13 | x | +| main.rs:841:9:841:9 | x | main.rs:840:13:840:13 | x | +| main.rs:843:19:843:19 | x | main.rs:840:13:840:13 | x | +| main.rs:845:19:845:19 | x | main.rs:838:9:838:9 | x | variableWriteAccess | main.rs:27:5:27:6 | x2 | main.rs:25:13:25:14 | x2 | | main.rs:29:5:29:6 | x2 | main.rs:25:13:25:14 | x2 | | main.rs:36:5:36:5 | x | main.rs:34:13:34:13 | x | -| main.rs:411:9:411:10 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:412:9:412:10 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:413:9:413:11 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:581:9:581:9 | y | main.rs:577:13:577:13 | y | -| main.rs:599:9:599:9 | i | main.rs:597:13:597:13 | i | -| main.rs:613:9:613:9 | x | main.rs:607:13:607:13 | x | -| main.rs:617:9:617:9 | x | main.rs:607:13:607:13 | x | -| main.rs:671:5:671:5 | a | main.rs:667:13:667:13 | a | -| main.rs:680:5:680:5 | a | main.rs:676:13:676:13 | a | -| main.rs:740:5:740:5 | x | main.rs:739:9:739:9 | x | -| main.rs:749:13:749:13 | x | main.rs:745:13:745:13 | x | +| main.rs:447:9:447:10 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:448:9:448:10 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:449:9:449:11 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:617:9:617:9 | y | main.rs:613:13:613:13 | y | +| main.rs:635:9:635:9 | i | main.rs:633:13:633:13 | i | +| main.rs:649:9:649:9 | x | main.rs:643:13:643:13 | x | +| main.rs:653:9:653:9 | x | main.rs:643:13:643:13 | x | +| main.rs:707:5:707:5 | a | main.rs:703:13:703:13 | a | +| main.rs:716:5:716:5 | a | main.rs:712:13:712:13 | a | +| main.rs:776:5:776:5 | x | main.rs:775:9:775:9 | x | +| main.rs:785:13:785:13 | x | main.rs:781:13:781:13 | x | variableReadAccess | main.rs:7:20:7:20 | s | main.rs:5:14:5:14 | s | | main.rs:12:20:12:20 | i | main.rs:10:14:10:14 | i | @@ -423,183 +450,198 @@ variableReadAccess | main.rs:105:13:105:13 | x | main.rs:100:9:100:9 | x | | main.rs:106:19:106:19 | x | main.rs:104:13:104:13 | x | | main.rs:109:15:109:15 | x | main.rs:101:14:101:14 | x | -| main.rs:116:11:116:12 | s1 | main.rs:113:9:113:10 | s1 | -| main.rs:117:19:117:20 | s2 | main.rs:115:24:115:25 | s2 | -| main.rs:125:11:125:12 | x6 | main.rs:122:9:122:10 | x6 | -| main.rs:130:23:130:24 | y1 | main.rs:127:14:127:15 | y1 | -| main.rs:135:15:135:16 | y1 | main.rs:123:9:123:10 | y1 | -| main.rs:141:11:141:17 | numbers | main.rs:139:9:139:15 | numbers | -| main.rs:150:23:150:27 | first | main.rs:144:13:144:17 | first | -| main.rs:151:23:151:27 | third | main.rs:146:13:146:17 | third | -| main.rs:152:23:152:27 | fifth | main.rs:148:13:148:17 | fifth | -| main.rs:156:11:156:17 | numbers | main.rs:139:9:139:15 | numbers | -| main.rs:163:23:163:27 | first | main.rs:159:13:159:17 | first | -| main.rs:164:23:164:26 | last | main.rs:161:13:161:16 | last | -| main.rs:172:11:172:12 | p2 | main.rs:170:9:170:10 | p2 | -| main.rs:175:24:175:25 | x7 | main.rs:174:16:174:17 | x7 | -| main.rs:186:11:186:13 | msg | main.rs:184:9:184:11 | msg | -| main.rs:190:24:190:34 | id_variable | main.rs:189:17:189:27 | id_variable | -| main.rs:197:23:197:24 | id | main.rs:194:26:194:27 | id | -| main.rs:209:11:209:16 | either | main.rs:208:9:208:14 | either | -| main.rs:211:26:211:27 | a3 | main.rs:210:9:210:44 | a3 | -| main.rs:223:11:223:12 | tv | main.rs:222:9:222:10 | tv | -| main.rs:225:26:225:27 | a4 | main.rs:224:9:224:81 | a4 | -| main.rs:227:11:227:12 | tv | main.rs:222:9:222:10 | tv | -| main.rs:229:26:229:27 | a5 | main.rs:228:9:228:83 | a5 | -| main.rs:231:11:231:12 | tv | main.rs:222:9:222:10 | tv | -| main.rs:233:26:233:27 | a6 | main.rs:232:9:232:83 | a6 | -| main.rs:239:11:239:16 | either | main.rs:238:9:238:14 | either | -| main.rs:241:16:241:17 | a7 | main.rs:240:9:240:44 | a7 | -| main.rs:242:26:242:27 | a7 | main.rs:240:9:240:44 | a7 | -| main.rs:250:11:250:16 | either | main.rs:248:9:248:14 | either | -| main.rs:254:23:254:25 | a11 | main.rs:252:14:252:51 | a11 | -| main.rs:256:15:256:15 | e | main.rs:251:13:251:13 | e | -| main.rs:257:28:257:30 | a12 | main.rs:255:33:255:35 | a12 | -| main.rs:273:11:273:12 | fv | main.rs:272:9:272:10 | fv | -| main.rs:275:26:275:28 | a13 | main.rs:274:9:274:109 | a13 | -| main.rs:283:7:283:7 | x | main.rs:281:9:281:9 | x | -| main.rs:285:5:285:5 | x | main.rs:282:17:282:17 | x | -| main.rs:287:19:287:19 | x | main.rs:282:17:282:17 | x | -| main.rs:290:13:290:13 | x | main.rs:281:9:281:9 | x | -| main.rs:291:19:291:19 | x | main.rs:289:13:289:13 | x | -| main.rs:299:7:299:7 | x | main.rs:297:9:297:9 | x | -| main.rs:302:12:302:12 | x | main.rs:298:17:298:17 | x | -| main.rs:304:5:304:5 | x | main.rs:301:14:301:14 | x | -| main.rs:306:19:306:19 | x | main.rs:301:14:301:14 | x | -| main.rs:309:13:309:13 | x | main.rs:297:9:297:9 | x | -| main.rs:310:19:310:19 | x | main.rs:308:13:308:13 | x | +| main.rs:116:11:116:11 | s | main.rs:113:9:113:9 | s | +| main.rs:117:19:117:19 | s | main.rs:115:24:115:24 | s | +| main.rs:125:25:125:25 | x | main.rs:123:17:123:17 | x | +| main.rs:127:19:127:19 | x | main.rs:124:19:124:19 | x | +| main.rs:135:9:135:9 | x | main.rs:133:9:133:9 | x | +| main.rs:137:9:137:9 | x | main.rs:134:12:134:12 | x | +| main.rs:139:9:139:9 | x | main.rs:136:12:136:12 | x | +| main.rs:141:9:141:9 | x | main.rs:138:12:138:12 | x | +| main.rs:143:9:143:9 | x | main.rs:140:12:140:12 | x | +| main.rs:145:9:145:9 | x | main.rs:142:12:142:12 | x | +| main.rs:147:9:147:9 | x | main.rs:144:12:144:12 | x | +| main.rs:149:19:149:19 | x | main.rs:146:12:146:12 | x | +| main.rs:152:19:152:19 | x | main.rs:133:9:133:9 | x | +| main.rs:160:11:160:12 | x6 | main.rs:157:9:157:10 | x6 | +| main.rs:165:23:165:24 | y1 | main.rs:162:14:162:15 | y1 | +| main.rs:170:15:170:16 | y1 | main.rs:158:9:158:10 | y1 | +| main.rs:176:11:176:17 | numbers | main.rs:174:9:174:15 | numbers | +| main.rs:185:23:185:27 | first | main.rs:179:13:179:17 | first | +| main.rs:186:23:186:27 | third | main.rs:181:13:181:17 | third | +| main.rs:187:23:187:27 | fifth | main.rs:183:13:183:17 | fifth | +| main.rs:191:11:191:17 | numbers | main.rs:174:9:174:15 | numbers | +| main.rs:198:23:198:27 | first | main.rs:194:13:194:17 | first | +| main.rs:199:23:199:26 | last | main.rs:196:13:196:16 | last | +| main.rs:207:11:207:12 | p2 | main.rs:205:9:205:10 | p2 | +| main.rs:210:24:210:25 | x7 | main.rs:209:16:209:17 | x7 | +| main.rs:221:11:221:13 | msg | main.rs:219:9:219:11 | msg | +| main.rs:225:24:225:34 | id_variable | main.rs:224:17:224:27 | id_variable | +| main.rs:232:23:232:24 | id | main.rs:229:26:229:27 | id | +| main.rs:244:11:244:16 | either | main.rs:243:9:243:14 | either | +| main.rs:246:26:246:27 | a3 | main.rs:245:9:245:44 | a3 | +| main.rs:258:11:258:12 | tv | main.rs:257:9:257:10 | tv | +| main.rs:260:26:260:27 | a4 | main.rs:259:9:259:81 | a4 | +| main.rs:262:11:262:12 | tv | main.rs:257:9:257:10 | tv | +| main.rs:264:26:264:27 | a5 | main.rs:263:9:263:83 | a5 | +| main.rs:266:11:266:12 | tv | main.rs:257:9:257:10 | tv | +| main.rs:268:26:268:27 | a6 | main.rs:267:9:267:83 | a6 | +| main.rs:274:11:274:16 | either | main.rs:273:9:273:14 | either | +| main.rs:276:16:276:17 | a7 | main.rs:275:9:275:44 | a7 | +| main.rs:277:26:277:27 | a7 | main.rs:275:9:275:44 | a7 | +| main.rs:285:11:285:16 | either | main.rs:283:9:283:14 | either | +| main.rs:289:23:289:25 | a11 | main.rs:287:14:287:51 | a11 | +| main.rs:291:15:291:15 | e | main.rs:286:13:286:13 | e | +| main.rs:292:28:292:30 | a12 | main.rs:290:33:290:35 | a12 | +| main.rs:308:11:308:12 | fv | main.rs:307:9:307:10 | fv | +| main.rs:310:26:310:28 | a13 | main.rs:309:9:309:109 | a13 | | main.rs:318:7:318:7 | x | main.rs:316:9:316:9 | x | -| main.rs:321:12:321:12 | x | main.rs:317:20:317:20 | x | -| main.rs:323:5:323:5 | x | main.rs:320:14:320:14 | x | -| main.rs:325:19:325:19 | x | main.rs:320:14:320:14 | x | -| main.rs:329:15:329:15 | x | main.rs:316:9:316:9 | x | -| main.rs:335:11:335:11 | x | main.rs:334:9:334:9 | x | -| main.rs:338:18:338:18 | x | main.rs:336:14:336:14 | x | -| main.rs:339:19:339:19 | x | main.rs:337:20:337:20 | x | -| main.rs:343:15:343:15 | x | main.rs:334:9:334:9 | x | -| main.rs:350:7:350:7 | x | main.rs:348:9:348:9 | x | -| main.rs:352:19:352:19 | x | main.rs:349:16:349:16 | x | -| main.rs:355:7:355:7 | x | main.rs:348:9:348:9 | x | -| main.rs:357:19:357:19 | x | main.rs:354:20:354:20 | x | -| main.rs:359:19:359:19 | x | main.rs:348:9:348:9 | x | -| main.rs:365:11:365:11 | x | main.rs:364:9:364:9 | x | -| main.rs:367:20:367:20 | x | main.rs:366:18:366:18 | x | -| main.rs:374:11:374:11 | x | main.rs:373:9:373:9 | x | -| main.rs:377:22:377:22 | y | main.rs:375:14:375:14 | y | -| main.rs:378:26:378:26 | y | main.rs:376:25:376:25 | y | -| main.rs:390:15:390:16 | a8 | main.rs:384:5:384:6 | a8 | -| main.rs:391:15:391:16 | b3 | main.rs:386:9:386:10 | b3 | -| main.rs:392:15:392:16 | c1 | main.rs:387:9:387:10 | c1 | -| main.rs:397:15:397:16 | a9 | main.rs:395:20:395:55 | a9 | -| main.rs:406:15:406:17 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:407:15:407:16 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:408:15:408:16 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:415:9:415:11 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:416:9:416:10 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:417:9:417:10 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:419:15:419:17 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:420:15:420:16 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:421:15:421:16 | c2 | main.rs:404:13:404:14 | c2 | -| main.rs:428:23:428:25 | a10 | main.rs:425:13:425:15 | a10 | -| main.rs:429:23:429:24 | b4 | main.rs:426:13:426:14 | b4 | -| main.rs:433:15:433:17 | a10 | main.rs:402:13:402:15 | a10 | -| main.rs:434:15:434:16 | b4 | main.rs:403:13:403:14 | b4 | -| main.rs:440:9:440:9 | x | main.rs:439:10:439:10 | x | -| main.rs:442:9:442:23 | example_closure | main.rs:438:9:438:23 | example_closure | -| main.rs:443:15:443:16 | n1 | main.rs:441:9:441:10 | n1 | -| main.rs:448:9:448:9 | x | main.rs:447:6:447:6 | x | -| main.rs:450:9:450:26 | immutable_variable | main.rs:446:9:446:26 | immutable_variable | -| main.rs:451:15:451:16 | n2 | main.rs:449:9:449:10 | n2 | -| main.rs:458:9:458:9 | x | main.rs:457:10:457:10 | x | -| main.rs:459:15:459:15 | f | main.rs:456:9:456:9 | f | -| main.rs:463:9:463:9 | x | main.rs:461:10:461:10 | x | -| main.rs:466:15:466:15 | f | main.rs:456:9:456:9 | f | -| main.rs:472:17:472:17 | x | main.rs:470:14:470:14 | x | -| main.rs:481:13:481:13 | x | main.rs:480:14:480:14 | x | -| main.rs:482:19:482:19 | f | main.rs:479:13:479:13 | f | -| main.rs:490:12:490:12 | v | main.rs:487:9:487:9 | v | -| main.rs:491:19:491:22 | text | main.rs:489:9:489:12 | text | -| main.rs:498:15:498:15 | a | main.rs:496:13:496:13 | a | -| main.rs:500:15:500:15 | a | main.rs:496:13:496:13 | a | -| main.rs:507:6:507:10 | ref_i | main.rs:505:9:505:13 | ref_i | -| main.rs:508:15:508:15 | i | main.rs:504:13:504:13 | i | -| main.rs:512:6:512:6 | x | main.rs:511:17:511:17 | x | -| main.rs:513:10:513:10 | x | main.rs:511:17:511:17 | x | -| main.rs:514:10:514:10 | x | main.rs:511:17:511:17 | x | -| main.rs:515:12:515:12 | x | main.rs:511:17:511:17 | x | -| main.rs:519:6:519:6 | x | main.rs:518:22:518:22 | x | -| main.rs:520:10:520:10 | x | main.rs:518:22:518:22 | x | -| main.rs:521:10:521:10 | x | main.rs:518:22:518:22 | x | -| main.rs:522:6:522:6 | y | main.rs:518:38:518:38 | y | -| main.rs:523:9:523:9 | x | main.rs:518:22:518:22 | x | -| main.rs:530:6:530:6 | y | main.rs:528:9:528:9 | y | -| main.rs:533:15:533:15 | x | main.rs:527:13:527:13 | x | -| main.rs:540:9:540:9 | w | main.rs:536:9:536:9 | w | -| main.rs:542:7:542:7 | w | main.rs:536:9:536:9 | w | -| main.rs:545:15:545:15 | z | main.rs:535:13:535:13 | z | -| main.rs:552:6:552:6 | y | main.rs:550:9:550:9 | y | -| main.rs:553:15:553:15 | x | main.rs:549:13:549:13 | x | -| main.rs:561:19:561:19 | x | main.rs:557:9:557:9 | x | -| main.rs:563:5:563:7 | cap | main.rs:560:9:560:11 | cap | -| main.rs:564:15:564:15 | x | main.rs:557:9:557:9 | x | -| main.rs:572:19:572:19 | x | main.rs:568:13:568:13 | x | -| main.rs:574:5:574:12 | closure1 | main.rs:571:9:571:16 | closure1 | -| main.rs:575:15:575:15 | x | main.rs:568:13:568:13 | x | -| main.rs:583:5:583:12 | closure2 | main.rs:580:13:580:20 | closure2 | -| main.rs:584:15:584:15 | y | main.rs:577:13:577:13 | y | -| main.rs:590:9:590:9 | z | main.rs:586:13:586:13 | z | -| main.rs:592:5:592:12 | closure3 | main.rs:589:13:589:20 | closure3 | -| main.rs:593:15:593:15 | z | main.rs:586:13:586:13 | z | -| main.rs:602:5:602:9 | block | main.rs:598:9:598:13 | block | -| main.rs:603:15:603:15 | i | main.rs:597:13:597:13 | i | -| main.rs:608:15:608:15 | x | main.rs:607:13:607:13 | x | -| main.rs:609:15:609:15 | x | main.rs:607:13:607:13 | x | -| main.rs:611:16:611:16 | b | main.rs:606:8:606:8 | b | -| main.rs:614:19:614:19 | x | main.rs:607:13:607:13 | x | -| main.rs:615:19:615:19 | x | main.rs:607:13:607:13 | x | -| main.rs:618:19:618:19 | x | main.rs:607:13:607:13 | x | -| main.rs:619:19:619:19 | x | main.rs:607:13:607:13 | x | -| main.rs:621:15:621:15 | x | main.rs:607:13:607:13 | x | -| main.rs:627:16:627:17 | b1 | main.rs:624:13:624:14 | b1 | -| main.rs:629:19:629:19 | x | main.rs:625:9:625:9 | x | -| main.rs:631:19:631:19 | x | main.rs:625:9:625:9 | x | -| main.rs:635:16:635:17 | b2 | main.rs:624:23:624:24 | b2 | -| main.rs:637:19:637:19 | x | main.rs:625:9:625:9 | x | -| main.rs:639:19:639:19 | x | main.rs:625:9:625:9 | x | -| main.rs:649:16:649:19 | self | main.rs:648:20:648:23 | self | -| main.rs:653:9:653:12 | self | main.rs:652:11:652:14 | self | -| main.rs:659:13:659:16 | self | main.rs:656:23:656:26 | self | -| main.rs:659:25:659:25 | n | main.rs:657:22:657:22 | n | -| main.rs:661:9:661:9 | f | main.rs:657:17:657:17 | f | -| main.rs:662:9:662:9 | f | main.rs:657:17:657:17 | f | -| main.rs:668:15:668:15 | a | main.rs:667:13:667:13 | a | -| main.rs:669:5:669:5 | a | main.rs:667:13:667:13 | a | -| main.rs:670:15:670:15 | a | main.rs:667:13:667:13 | a | -| main.rs:672:15:672:15 | a | main.rs:667:13:667:13 | a | -| main.rs:677:15:677:15 | a | main.rs:676:13:676:13 | a | -| main.rs:678:5:678:5 | a | main.rs:676:13:676:13 | a | -| main.rs:679:15:679:15 | a | main.rs:676:13:676:13 | a | -| main.rs:681:15:681:15 | a | main.rs:676:13:676:13 | a | -| main.rs:687:15:687:15 | x | main.rs:685:9:685:9 | x | -| main.rs:699:10:699:13 | self | main.rs:698:17:698:20 | self | -| main.rs:705:5:705:5 | a | main.rs:704:13:704:13 | a | -| main.rs:708:15:708:15 | a | main.rs:704:13:704:13 | a | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:9:727:21 | var_in_macro | -| main.rs:728:15:728:28 | var_from_macro | main.rs:726:9:726:22 | var_from_macro | -| main.rs:734:30:734:41 | var_in_macro | main.rs:734:15:734:28 | var_in_macro | -| main.rs:735:15:735:26 | var_in_macro | main.rs:729:9:729:20 | var_in_macro | -| main.rs:741:15:741:15 | x | main.rs:739:9:739:9 | x | -| main.rs:748:20:748:20 | b | main.rs:746:20:746:20 | b | -| main.rs:752:5:752:7 | cap | main.rs:746:13:746:15 | cap | -| main.rs:753:15:753:15 | x | main.rs:745:13:745:13 | x | -| main.rs:761:19:761:19 | x | main.rs:759:13:759:13 | x | -| main.rs:768:15:768:15 | y | main.rs:760:13:760:13 | y | -| main.rs:770:17:770:20 | N0ne | main.rs:769:13:769:16 | N0ne | -| main.rs:779:13:779:22 | test_alias | main.rs:776:13:776:22 | test_alias | -| main.rs:780:9:780:12 | test | main.rs:778:13:778:16 | test | -| main.rs:788:15:788:15 | x | main.rs:787:13:787:13 | x | -| main.rs:790:20:790:20 | x | main.rs:789:18:789:18 | x | -| main.rs:793:15:793:15 | x | main.rs:787:13:787:13 | x | +| main.rs:320:5:320:5 | x | main.rs:317:17:317:17 | x | +| main.rs:322:19:322:19 | x | main.rs:317:17:317:17 | x | +| main.rs:325:13:325:13 | x | main.rs:316:9:316:9 | x | +| main.rs:326:19:326:19 | x | main.rs:324:13:324:13 | x | +| main.rs:334:7:334:7 | x | main.rs:332:9:332:9 | x | +| main.rs:337:12:337:12 | x | main.rs:333:17:333:17 | x | +| main.rs:339:5:339:5 | x | main.rs:336:14:336:14 | x | +| main.rs:341:19:341:19 | x | main.rs:336:14:336:14 | x | +| main.rs:344:13:344:13 | x | main.rs:332:9:332:9 | x | +| main.rs:345:19:345:19 | x | main.rs:343:13:343:13 | x | +| main.rs:353:7:353:7 | x | main.rs:351:9:351:9 | x | +| main.rs:356:12:356:12 | x | main.rs:352:20:352:20 | x | +| main.rs:358:5:358:5 | x | main.rs:355:14:355:14 | x | +| main.rs:360:19:360:19 | x | main.rs:355:14:355:14 | x | +| main.rs:364:15:364:15 | x | main.rs:351:9:351:9 | x | +| main.rs:370:11:370:11 | x | main.rs:369:9:369:9 | x | +| main.rs:373:18:373:18 | x | main.rs:371:14:371:14 | x | +| main.rs:374:19:374:19 | x | main.rs:372:20:372:20 | x | +| main.rs:378:15:378:15 | x | main.rs:369:9:369:9 | x | +| main.rs:385:7:385:7 | x | main.rs:383:9:383:9 | x | +| main.rs:387:19:387:19 | x | main.rs:384:16:384:16 | x | +| main.rs:390:7:390:7 | x | main.rs:383:9:383:9 | x | +| main.rs:392:19:392:19 | x | main.rs:389:20:389:20 | x | +| main.rs:394:19:394:19 | x | main.rs:383:9:383:9 | x | +| main.rs:400:11:400:11 | x | main.rs:399:9:399:9 | x | +| main.rs:402:20:402:20 | x | main.rs:401:18:401:18 | x | +| main.rs:409:11:409:11 | x | main.rs:408:9:408:9 | x | +| main.rs:411:16:411:16 | y | main.rs:410:14:410:14 | y | +| main.rs:413:22:413:22 | y | main.rs:410:14:410:14 | y | +| main.rs:414:26:414:26 | y | main.rs:412:22:412:22 | y | +| main.rs:426:15:426:16 | a8 | main.rs:420:5:420:6 | a8 | +| main.rs:427:15:427:16 | b3 | main.rs:422:9:422:10 | b3 | +| main.rs:428:15:428:16 | c1 | main.rs:423:9:423:10 | c1 | +| main.rs:433:15:433:16 | a9 | main.rs:431:20:431:55 | a9 | +| main.rs:442:15:442:17 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:443:15:443:16 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:444:15:444:16 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:451:9:451:11 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:452:9:452:10 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:453:9:453:10 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:455:15:455:17 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:456:15:456:16 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:457:15:457:16 | c2 | main.rs:440:13:440:14 | c2 | +| main.rs:464:23:464:25 | a10 | main.rs:461:13:461:15 | a10 | +| main.rs:465:23:465:24 | b4 | main.rs:462:13:462:14 | b4 | +| main.rs:469:15:469:17 | a10 | main.rs:438:13:438:15 | a10 | +| main.rs:470:15:470:16 | b4 | main.rs:439:13:439:14 | b4 | +| main.rs:476:9:476:9 | x | main.rs:475:10:475:10 | x | +| main.rs:478:9:478:23 | example_closure | main.rs:474:9:474:23 | example_closure | +| main.rs:479:15:479:16 | n1 | main.rs:477:9:477:10 | n1 | +| main.rs:484:9:484:9 | x | main.rs:483:6:483:6 | x | +| main.rs:486:9:486:26 | immutable_variable | main.rs:482:9:482:26 | immutable_variable | +| main.rs:487:15:487:16 | n2 | main.rs:485:9:485:10 | n2 | +| main.rs:494:9:494:9 | x | main.rs:493:10:493:10 | x | +| main.rs:495:15:495:15 | f | main.rs:492:9:492:9 | f | +| main.rs:499:9:499:9 | x | main.rs:497:10:497:10 | x | +| main.rs:502:15:502:15 | f | main.rs:492:9:492:9 | f | +| main.rs:508:17:508:17 | x | main.rs:506:14:506:14 | x | +| main.rs:517:13:517:13 | x | main.rs:516:14:516:14 | x | +| main.rs:518:19:518:19 | f | main.rs:515:13:515:13 | f | +| main.rs:526:12:526:12 | v | main.rs:523:9:523:9 | v | +| main.rs:527:19:527:22 | text | main.rs:525:9:525:12 | text | +| main.rs:534:15:534:15 | a | main.rs:532:13:532:13 | a | +| main.rs:536:15:536:15 | a | main.rs:532:13:532:13 | a | +| main.rs:543:6:543:10 | ref_i | main.rs:541:9:541:13 | ref_i | +| main.rs:544:15:544:15 | i | main.rs:540:13:540:13 | i | +| main.rs:548:6:548:6 | x | main.rs:547:17:547:17 | x | +| main.rs:549:10:549:10 | x | main.rs:547:17:547:17 | x | +| main.rs:550:10:550:10 | x | main.rs:547:17:547:17 | x | +| main.rs:551:12:551:12 | x | main.rs:547:17:547:17 | x | +| main.rs:555:6:555:6 | x | main.rs:554:22:554:22 | x | +| main.rs:556:10:556:10 | x | main.rs:554:22:554:22 | x | +| main.rs:557:10:557:10 | x | main.rs:554:22:554:22 | x | +| main.rs:558:6:558:6 | y | main.rs:554:38:554:38 | y | +| main.rs:559:9:559:9 | x | main.rs:554:22:554:22 | x | +| main.rs:566:6:566:6 | y | main.rs:564:9:564:9 | y | +| main.rs:569:15:569:15 | x | main.rs:563:13:563:13 | x | +| main.rs:576:9:576:9 | w | main.rs:572:9:572:9 | w | +| main.rs:578:7:578:7 | w | main.rs:572:9:572:9 | w | +| main.rs:581:15:581:15 | z | main.rs:571:13:571:13 | z | +| main.rs:588:6:588:6 | y | main.rs:586:9:586:9 | y | +| main.rs:589:15:589:15 | x | main.rs:585:13:585:13 | x | +| main.rs:597:19:597:19 | x | main.rs:593:9:593:9 | x | +| main.rs:599:5:599:7 | cap | main.rs:596:9:596:11 | cap | +| main.rs:600:15:600:15 | x | main.rs:593:9:593:9 | x | +| main.rs:608:19:608:19 | x | main.rs:604:13:604:13 | x | +| main.rs:610:5:610:12 | closure1 | main.rs:607:9:607:16 | closure1 | +| main.rs:611:15:611:15 | x | main.rs:604:13:604:13 | x | +| main.rs:619:5:619:12 | closure2 | main.rs:616:13:616:20 | closure2 | +| main.rs:620:15:620:15 | y | main.rs:613:13:613:13 | y | +| main.rs:626:9:626:9 | z | main.rs:622:13:622:13 | z | +| main.rs:628:5:628:12 | closure3 | main.rs:625:13:625:20 | closure3 | +| main.rs:629:15:629:15 | z | main.rs:622:13:622:13 | z | +| main.rs:638:5:638:9 | block | main.rs:634:9:634:13 | block | +| main.rs:639:15:639:15 | i | main.rs:633:13:633:13 | i | +| main.rs:644:15:644:15 | x | main.rs:643:13:643:13 | x | +| main.rs:645:15:645:15 | x | main.rs:643:13:643:13 | x | +| main.rs:647:16:647:16 | b | main.rs:642:8:642:8 | b | +| main.rs:650:19:650:19 | x | main.rs:643:13:643:13 | x | +| main.rs:651:19:651:19 | x | main.rs:643:13:643:13 | x | +| main.rs:654:19:654:19 | x | main.rs:643:13:643:13 | x | +| main.rs:655:19:655:19 | x | main.rs:643:13:643:13 | x | +| main.rs:657:15:657:15 | x | main.rs:643:13:643:13 | x | +| main.rs:663:16:663:17 | b1 | main.rs:660:13:660:14 | b1 | +| main.rs:665:19:665:19 | x | main.rs:661:9:661:9 | x | +| main.rs:667:19:667:19 | x | main.rs:661:9:661:9 | x | +| main.rs:671:16:671:17 | b2 | main.rs:660:23:660:24 | b2 | +| main.rs:673:19:673:19 | x | main.rs:661:9:661:9 | x | +| main.rs:675:19:675:19 | x | main.rs:661:9:661:9 | x | +| main.rs:685:16:685:19 | self | main.rs:684:20:684:23 | self | +| main.rs:689:9:689:12 | self | main.rs:688:11:688:14 | self | +| main.rs:695:13:695:16 | self | main.rs:692:23:692:26 | self | +| main.rs:695:25:695:25 | n | main.rs:693:22:693:22 | n | +| main.rs:697:9:697:9 | f | main.rs:693:17:693:17 | f | +| main.rs:698:9:698:9 | f | main.rs:693:17:693:17 | f | +| main.rs:704:15:704:15 | a | main.rs:703:13:703:13 | a | +| main.rs:705:5:705:5 | a | main.rs:703:13:703:13 | a | +| main.rs:706:15:706:15 | a | main.rs:703:13:703:13 | a | +| main.rs:708:15:708:15 | a | main.rs:703:13:703:13 | a | +| main.rs:713:15:713:15 | a | main.rs:712:13:712:13 | a | +| main.rs:714:5:714:5 | a | main.rs:712:13:712:13 | a | +| main.rs:715:15:715:15 | a | main.rs:712:13:712:13 | a | +| main.rs:717:15:717:15 | a | main.rs:712:13:712:13 | a | +| main.rs:723:15:723:15 | x | main.rs:721:9:721:9 | x | +| main.rs:735:10:735:13 | self | main.rs:734:17:734:20 | self | +| main.rs:741:5:741:5 | a | main.rs:740:13:740:13 | a | +| main.rs:744:15:744:15 | a | main.rs:740:13:740:13 | a | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:9:763:21 | var_in_macro | +| main.rs:764:15:764:28 | var_from_macro | main.rs:762:9:762:22 | var_from_macro | +| main.rs:770:30:770:41 | var_in_macro | main.rs:770:15:770:28 | var_in_macro | +| main.rs:771:15:771:26 | var_in_macro | main.rs:765:9:765:20 | var_in_macro | +| main.rs:777:15:777:15 | x | main.rs:775:9:775:9 | x | +| main.rs:784:20:784:20 | b | main.rs:782:20:782:20 | b | +| main.rs:788:5:788:7 | cap | main.rs:782:13:782:15 | cap | +| main.rs:789:15:789:15 | x | main.rs:781:13:781:13 | x | +| main.rs:797:19:797:19 | x | main.rs:795:13:795:13 | x | +| main.rs:804:15:804:15 | y | main.rs:796:13:796:13 | y | +| main.rs:806:17:806:20 | N0ne | main.rs:805:13:805:16 | N0ne | +| main.rs:815:13:815:22 | test_alias | main.rs:812:13:812:22 | test_alias | +| main.rs:816:9:816:12 | test | main.rs:814:13:814:16 | test | +| main.rs:824:15:824:15 | x | main.rs:823:13:823:13 | x | +| main.rs:826:20:826:20 | x | main.rs:825:18:825:18 | x | +| main.rs:829:15:829:15 | x | main.rs:823:13:823:13 | x | +| main.rs:841:9:841:9 | x | main.rs:840:13:840:13 | x | +| main.rs:843:19:843:19 | x | main.rs:840:13:840:13 | x | +| main.rs:845:19:845:19 | x | main.rs:838:9:838:9 | x | variableInitializer | main.rs:20:9:20:10 | x1 | main.rs:20:14:20:16 | "a" | | main.rs:25:13:25:14 | x2 | main.rs:25:18:25:18 | 4 | @@ -612,88 +654,98 @@ variableInitializer | main.rs:91:9:91:10 | s1 | main.rs:91:14:91:41 | Some(...) | | main.rs:100:9:100:9 | x | main.rs:100:13:100:22 | Some(...) | | main.rs:104:13:104:13 | x | main.rs:105:13:105:13 | x | -| main.rs:113:9:113:10 | s1 | main.rs:113:14:113:41 | Some(...) | -| main.rs:122:9:122:10 | x6 | main.rs:122:14:122:20 | Some(...) | -| main.rs:123:9:123:10 | y1 | main.rs:123:14:123:15 | 10 | -| main.rs:139:9:139:15 | numbers | main.rs:139:19:139:35 | TupleExpr | -| main.rs:170:9:170:10 | p2 | main.rs:170:14:170:37 | Point {...} | -| main.rs:184:9:184:11 | msg | main.rs:184:15:184:38 | ...::Hello {...} | -| main.rs:208:9:208:14 | either | main.rs:208:18:208:33 | ...::Left(...) | -| main.rs:222:9:222:10 | tv | main.rs:222:14:222:36 | ...::Second(...) | -| main.rs:238:9:238:14 | either | main.rs:238:18:238:33 | ...::Left(...) | -| main.rs:248:9:248:14 | either | main.rs:248:18:248:33 | ...::Left(...) | -| main.rs:272:9:272:10 | fv | main.rs:272:14:272:35 | ...::Second(...) | -| main.rs:281:9:281:9 | x | main.rs:281:12:281:19 | Some(...) | -| main.rs:289:13:289:13 | x | main.rs:290:13:290:13 | x | -| main.rs:297:9:297:9 | x | main.rs:297:13:297:20 | Some(...) | -| main.rs:308:13:308:13 | x | main.rs:309:13:309:13 | x | -| main.rs:316:9:316:9 | x | main.rs:316:13:316:20 | Some(...) | -| main.rs:334:9:334:9 | x | main.rs:334:13:334:20 | Some(...) | -| main.rs:337:20:337:20 | x | main.rs:338:18:338:18 | x | -| main.rs:348:9:348:9 | x | main.rs:348:13:348:18 | Ok(...) | -| main.rs:364:9:364:9 | x | main.rs:364:13:364:19 | Some(...) | -| main.rs:373:9:373:9 | x | main.rs:373:13:373:20 | Some(...) | -| main.rs:438:9:438:23 | example_closure | main.rs:439:9:440:9 | \|...\| x | -| main.rs:441:9:441:10 | n1 | main.rs:442:9:442:26 | example_closure(...) | -| main.rs:446:9:446:26 | immutable_variable | main.rs:447:5:448:9 | \|...\| x | -| main.rs:449:9:449:10 | n2 | main.rs:450:9:450:29 | immutable_variable(...) | -| main.rs:456:9:456:9 | f | main.rs:457:9:458:9 | \|...\| x | -| main.rs:479:13:479:13 | f | main.rs:480:13:481:13 | \|...\| x | -| main.rs:487:9:487:9 | v | main.rs:487:13:487:41 | &... | -| main.rs:496:13:496:13 | a | main.rs:496:17:496:17 | 0 | -| main.rs:504:13:504:13 | i | main.rs:504:17:504:17 | 1 | -| main.rs:505:9:505:13 | ref_i | main.rs:506:9:506:14 | &mut i | -| main.rs:527:13:527:13 | x | main.rs:527:17:527:17 | 2 | -| main.rs:528:9:528:9 | y | main.rs:529:9:529:28 | mutate_param(...) | -| main.rs:535:13:535:13 | z | main.rs:535:17:535:17 | 4 | -| main.rs:536:9:536:9 | w | main.rs:537:9:537:19 | &mut ... | -| main.rs:549:13:549:13 | x | main.rs:549:17:549:17 | 1 | -| main.rs:550:9:550:9 | y | main.rs:551:9:551:14 | &mut x | -| main.rs:557:9:557:9 | x | main.rs:557:13:557:15 | 100 | -| main.rs:560:9:560:11 | cap | main.rs:560:15:562:5 | \|...\| ... | -| main.rs:568:13:568:13 | x | main.rs:568:17:568:17 | 1 | -| main.rs:571:9:571:16 | closure1 | main.rs:571:20:573:5 | \|...\| ... | -| main.rs:577:13:577:13 | y | main.rs:577:17:577:17 | 2 | -| main.rs:580:13:580:20 | closure2 | main.rs:580:24:582:5 | \|...\| ... | -| main.rs:586:13:586:13 | z | main.rs:586:17:586:17 | 2 | -| main.rs:589:13:589:20 | closure3 | main.rs:589:24:591:5 | \|...\| ... | -| main.rs:597:13:597:13 | i | main.rs:597:22:597:22 | 0 | -| main.rs:598:9:598:13 | block | main.rs:598:17:600:5 | { ... } | -| main.rs:607:13:607:13 | x | main.rs:607:17:607:17 | 1 | -| main.rs:625:9:625:9 | x | main.rs:625:13:625:13 | 1 | -| main.rs:657:17:657:17 | f | main.rs:657:21:660:9 | \|...\| ... | -| main.rs:667:13:667:13 | a | main.rs:667:17:667:35 | MyStruct {...} | -| main.rs:676:13:676:13 | a | main.rs:676:17:676:25 | [...] | -| main.rs:685:9:685:9 | x | main.rs:685:13:685:14 | 16 | -| main.rs:689:9:689:9 | z | main.rs:689:13:689:14 | 17 | -| main.rs:704:13:704:13 | a | main.rs:704:17:704:35 | MyStruct {...} | -| main.rs:726:9:726:22 | var_from_macro | main.rs:727:9:727:25 | MacroExpr | -| main.rs:727:9:727:21 | var_in_macro | main.rs:727:23:727:24 | 37 | -| main.rs:729:9:729:20 | var_in_macro | main.rs:729:24:729:25 | 33 | -| main.rs:734:15:734:28 | var_in_macro | main.rs:734:15:734:28 | 0 | -| main.rs:745:13:745:13 | x | main.rs:745:17:745:19 | 100 | -| main.rs:746:13:746:15 | cap | main.rs:746:19:751:5 | \|...\| ... | -| main.rs:759:13:759:13 | x | main.rs:759:17:759:24 | Some(...) | -| main.rs:760:13:760:13 | y | main.rs:761:13:767:9 | match x { ... } | -| main.rs:776:13:776:22 | test_alias | main.rs:777:13:777:16 | test | -| main.rs:778:13:778:16 | test | main.rs:779:13:779:24 | test_alias(...) | -| main.rs:787:13:787:13 | x | main.rs:787:17:787:23 | Some(...) | +| main.rs:113:9:113:9 | s | main.rs:113:13:113:40 | Some(...) | +| main.rs:133:9:133:9 | x | main.rs:133:13:133:13 | 1 | +| main.rs:134:12:134:12 | x | main.rs:135:9:135:13 | ... + ... | +| main.rs:136:12:136:12 | x | main.rs:137:9:137:13 | ... + ... | +| main.rs:138:12:138:12 | x | main.rs:139:9:139:13 | ... + ... | +| main.rs:140:12:140:12 | x | main.rs:141:9:141:13 | ... + ... | +| main.rs:142:12:142:12 | x | main.rs:143:9:143:13 | ... + ... | +| main.rs:144:12:144:12 | x | main.rs:145:9:145:13 | ... + ... | +| main.rs:146:12:146:12 | x | main.rs:147:9:147:13 | ... + ... | +| main.rs:157:9:157:10 | x6 | main.rs:157:14:157:20 | Some(...) | +| main.rs:158:9:158:10 | y1 | main.rs:158:14:158:15 | 10 | +| main.rs:174:9:174:15 | numbers | main.rs:174:19:174:35 | TupleExpr | +| main.rs:205:9:205:10 | p2 | main.rs:205:14:205:37 | Point {...} | +| main.rs:219:9:219:11 | msg | main.rs:219:15:219:38 | ...::Hello {...} | +| main.rs:243:9:243:14 | either | main.rs:243:18:243:33 | ...::Left(...) | +| main.rs:257:9:257:10 | tv | main.rs:257:14:257:36 | ...::Second(...) | +| main.rs:273:9:273:14 | either | main.rs:273:18:273:33 | ...::Left(...) | +| main.rs:283:9:283:14 | either | main.rs:283:18:283:33 | ...::Left(...) | +| main.rs:307:9:307:10 | fv | main.rs:307:14:307:35 | ...::Second(...) | +| main.rs:316:9:316:9 | x | main.rs:316:12:316:19 | Some(...) | +| main.rs:324:13:324:13 | x | main.rs:325:13:325:13 | x | +| main.rs:332:9:332:9 | x | main.rs:332:13:332:20 | Some(...) | +| main.rs:343:13:343:13 | x | main.rs:344:13:344:13 | x | +| main.rs:351:9:351:9 | x | main.rs:351:13:351:20 | Some(...) | +| main.rs:369:9:369:9 | x | main.rs:369:13:369:20 | Some(...) | +| main.rs:372:20:372:20 | x | main.rs:373:18:373:18 | x | +| main.rs:383:9:383:9 | x | main.rs:383:13:383:18 | Ok(...) | +| main.rs:399:9:399:9 | x | main.rs:399:13:399:19 | Some(...) | +| main.rs:408:9:408:9 | x | main.rs:408:13:408:20 | Some(...) | +| main.rs:474:9:474:23 | example_closure | main.rs:475:9:476:9 | \|...\| x | +| main.rs:477:9:477:10 | n1 | main.rs:478:9:478:26 | example_closure(...) | +| main.rs:482:9:482:26 | immutable_variable | main.rs:483:5:484:9 | \|...\| x | +| main.rs:485:9:485:10 | n2 | main.rs:486:9:486:29 | immutable_variable(...) | +| main.rs:492:9:492:9 | f | main.rs:493:9:494:9 | \|...\| x | +| main.rs:515:13:515:13 | f | main.rs:516:13:517:13 | \|...\| x | +| main.rs:523:9:523:9 | v | main.rs:523:13:523:41 | &... | +| main.rs:532:13:532:13 | a | main.rs:532:17:532:17 | 0 | +| main.rs:540:13:540:13 | i | main.rs:540:17:540:17 | 1 | +| main.rs:541:9:541:13 | ref_i | main.rs:542:9:542:14 | &mut i | +| main.rs:563:13:563:13 | x | main.rs:563:17:563:17 | 2 | +| main.rs:564:9:564:9 | y | main.rs:565:9:565:28 | mutate_param(...) | +| main.rs:571:13:571:13 | z | main.rs:571:17:571:17 | 4 | +| main.rs:572:9:572:9 | w | main.rs:573:9:573:19 | &mut ... | +| main.rs:585:13:585:13 | x | main.rs:585:17:585:17 | 1 | +| main.rs:586:9:586:9 | y | main.rs:587:9:587:14 | &mut x | +| main.rs:593:9:593:9 | x | main.rs:593:13:593:15 | 100 | +| main.rs:596:9:596:11 | cap | main.rs:596:15:598:5 | \|...\| ... | +| main.rs:604:13:604:13 | x | main.rs:604:17:604:17 | 1 | +| main.rs:607:9:607:16 | closure1 | main.rs:607:20:609:5 | \|...\| ... | +| main.rs:613:13:613:13 | y | main.rs:613:17:613:17 | 2 | +| main.rs:616:13:616:20 | closure2 | main.rs:616:24:618:5 | \|...\| ... | +| main.rs:622:13:622:13 | z | main.rs:622:17:622:17 | 2 | +| main.rs:625:13:625:20 | closure3 | main.rs:625:24:627:5 | \|...\| ... | +| main.rs:633:13:633:13 | i | main.rs:633:22:633:22 | 0 | +| main.rs:634:9:634:13 | block | main.rs:634:17:636:5 | { ... } | +| main.rs:643:13:643:13 | x | main.rs:643:17:643:17 | 1 | +| main.rs:661:9:661:9 | x | main.rs:661:13:661:13 | 1 | +| main.rs:693:17:693:17 | f | main.rs:693:21:696:9 | \|...\| ... | +| main.rs:703:13:703:13 | a | main.rs:703:17:703:35 | MyStruct {...} | +| main.rs:712:13:712:13 | a | main.rs:712:17:712:25 | [...] | +| main.rs:721:9:721:9 | x | main.rs:721:13:721:14 | 16 | +| main.rs:725:9:725:9 | z | main.rs:725:13:725:14 | 17 | +| main.rs:740:13:740:13 | a | main.rs:740:17:740:35 | MyStruct {...} | +| main.rs:762:9:762:22 | var_from_macro | main.rs:763:9:763:25 | MacroExpr | +| main.rs:763:9:763:21 | var_in_macro | main.rs:763:23:763:24 | 37 | +| main.rs:765:9:765:20 | var_in_macro | main.rs:765:24:765:25 | 33 | +| main.rs:770:15:770:28 | var_in_macro | main.rs:770:15:770:28 | 0 | +| main.rs:781:13:781:13 | x | main.rs:781:17:781:19 | 100 | +| main.rs:782:13:782:15 | cap | main.rs:782:19:787:5 | \|...\| ... | +| main.rs:795:13:795:13 | x | main.rs:795:17:795:24 | Some(...) | +| main.rs:796:13:796:13 | y | main.rs:797:13:803:9 | match x { ... } | +| main.rs:812:13:812:22 | test_alias | main.rs:813:13:813:16 | test | +| main.rs:814:13:814:16 | test | main.rs:815:13:815:24 | test_alias(...) | +| main.rs:823:13:823:13 | x | main.rs:823:17:823:23 | Some(...) | +| main.rs:838:9:838:9 | x | main.rs:838:13:838:13 | 1 | +| main.rs:840:13:840:13 | x | main.rs:840:17:840:17 | 1 | capturedVariable -| main.rs:557:9:557:9 | x | -| main.rs:568:13:568:13 | x | -| main.rs:577:13:577:13 | y | -| main.rs:586:13:586:13 | z | -| main.rs:597:13:597:13 | i | -| main.rs:656:23:656:26 | self | -| main.rs:745:13:745:13 | x | +| main.rs:593:9:593:9 | x | +| main.rs:604:13:604:13 | x | +| main.rs:613:13:613:13 | y | +| main.rs:622:13:622:13 | z | +| main.rs:633:13:633:13 | i | +| main.rs:692:23:692:26 | self | +| main.rs:781:13:781:13 | x | capturedAccess -| main.rs:561:19:561:19 | x | -| main.rs:572:19:572:19 | x | -| main.rs:581:9:581:9 | y | -| main.rs:590:9:590:9 | z | -| main.rs:599:9:599:9 | i | -| main.rs:659:13:659:16 | self | -| main.rs:749:13:749:13 | x | +| main.rs:597:19:597:19 | x | +| main.rs:608:19:608:19 | x | +| main.rs:617:9:617:9 | y | +| main.rs:626:9:626:9 | z | +| main.rs:635:9:635:9 | i | +| main.rs:695:13:695:16 | self | +| main.rs:785:13:785:13 | x | nestedFunctionAccess -| main.rs:469:19:469:19 | f | main.rs:470:9:473:9 | fn f | -| main.rs:476:23:476:23 | f | main.rs:470:9:473:9 | fn f | +| main.rs:505:19:505:19 | f | main.rs:506:9:509:9 | fn f | +| main.rs:512:23:512:23 | f | main.rs:506:9:509:9 | fn f | From c08cf8166543d5a4ae3e594908e8d65ec8b54c24 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 27 May 2026 09:09:19 +0200 Subject: [PATCH 131/226] Rust: Adopt shared local name resolution library --- .../rust/elements/internal/ParamBaseImpl.qll | 7 +- .../rust/elements/internal/VariableImpl.qll | 798 +++++------------- rust/ql/lib/qlpack.yml | 1 + .../test/library-tests/variables/Ssa.expected | 4 +- rust/ql/test/library-tests/variables/main.rs | 2 +- .../variables/variables.expected | 4 +- 6 files changed, 223 insertions(+), 593 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll index 3b0f82eb6c3..5badd696f1a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `ParamBase`. * @@ -6,6 +5,7 @@ */ private import codeql.rust.elements.internal.generated.ParamBase +private import codeql.rust.elements.Callable /** * INTERNAL: This module contains the customizable definition of `ParamBase` and should not @@ -15,5 +15,8 @@ module Impl { /** * A normal parameter, `Param`, or a self parameter `SelfParam`. */ - class ParamBase extends Generated::ParamBase { } + class ParamBase extends Generated::ParamBase { + /** Gets the callable this parameter belongs to. */ + Callable getCallable() { this = result.getParamList().getAParamBase() } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 37a2e4dacc0..f1df0a144b8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -1,71 +1,13 @@ private import rust +private import codeql.namebinding.LocalNameBinding private import codeql.rust.controlflow.ControlFlowGraph private import codeql.rust.internal.PathResolution as PathResolution private import codeql.rust.elements.internal.generated.ParentChild as ParentChild private import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl private import codeql.rust.elements.internal.PathImpl::Impl as PathImpl private import codeql.rust.elements.internal.FormatTemplateVariableAccessImpl::Impl as FormatTemplateVariableAccessImpl -private import codeql.util.DenseRank module Impl { - /** - * A variable scope. Either a block `{ ... }`, the guard/rhs - * of a match arm, or the body of a closure. - */ - abstract class VariableScope extends AstNode { } - - class BlockExprScope extends VariableScope, BlockExpr { } - - class MatchArmExprScope extends VariableScope { - MatchArmExprScope() { this = any(MatchArm arm).getExpr() } - } - - class MatchArmGuardScope extends VariableScope { - MatchArmGuardScope() { this = any(MatchArm arm).getGuard() } - } - - class ClosureBodyScope extends VariableScope { - ClosureBodyScope() { this = any(ClosureExpr ce).getBody() } - } - - /** - * A scope for conditions, which may introduce variables using `let` expressions. - * - * Such variables are only available in the body guarded by the condition. - */ - class ConditionScope extends VariableScope { - private AstNode parent; - private AstNode body; - - ConditionScope() { - parent = - any(IfExpr ie | - this = ie.getCondition() and - body = ie.getThen() - ) - or - parent = - any(WhileExpr we | - this = we.getCondition() and - body = we.getLoopBody() - ) - or - parent = - any(MatchArm ma | - this = ma.getGuard() and - body = ma.getExpr() - ) - } - - /** Gets the parent of this condition. */ - AstNode getParent() { result = parent } - - /** - * Gets the body in which variables introduced in this scope are available. - */ - AstNode getBody() { result = body } - } - private Pat getAPatAncestor(Pat p) { (p instanceof IdentPat or p instanceof OrPat) and exists(Pat p0 | result = p0.getParentPat() | @@ -100,7 +42,7 @@ module Impl { */ cached predicate variableDecl(AstNode definingNode, Name name, string text) { - Cached::ref() and + CachedStage::ref() and exists(SelfParam sp | name = sp.getName() and definingNode = name and @@ -127,34 +69,204 @@ module Impl { ) } + /** + * `let` chains like + * + * ```rust + * if let x1 = ... && let x2 = ... && ... && let xn = ... { ... } + * ``` + * + * are parsed left-associatively, so the AST for the condition looks like + * + * ```rust + * ((let x1 = ... && let x2 = ...) && ...) & let xn = ... + * ``` + * + * This, however, does not work with scoping and shadowing, so we instead treat + * `let` chains as if there is just a single root `&&` node with `n` children, + * skipping all intermediate `&&` nodes. + */ + private module LetChains { + predicate isLetChainAncestor(LogicalAndExpr lae) { + lae.getAnOperand() instanceof LetExpr + or + isLetChainAncestor(lae.getLhs()) + } + + private predicate isLetChainRoot(LogicalAndExpr root) { + isLetChainAncestor(root) and + not root = any(LogicalAndExpr lae).getLhs() + } + + private predicate leftMostChildOfLetChainRoot(LogicalAndExpr left, LogicalAndExpr root) { + isLetChainRoot(root) and + left = root.getLhs*() and + not left.getLhs() instanceof LogicalAndExpr + } + + private AstNode getLetChainChild(LogicalAndExpr sub, LogicalAndExpr root, int i) { + leftMostChildOfLetChainRoot(sub, root) and + i = 1 and + result = sub.getRhs() + or + exists(LogicalAndExpr mid | + exists(getLetChainChild(mid, root, i - 1)) and + sub.getLhs() = mid and + result = sub.getRhs() + ) + } + + AstNode getLetChainChild(LogicalAndExpr lae, int i) { + exists(LogicalAndExpr left | + leftMostChildOfLetChainRoot(left, lae) and + i = 0 and + result = left.getLhs() + ) + or + result = getLetChainChild(_, lae, i) + } + } + + private import LetChains + + private module Input implements LocalNameBindingInputSig { + private import rust as Rust + + predicate cacheRevRef() { + (variableDecl(_, _, _) implies any()) + or + (exists(VariableReadAccess a) implies any()) + or + (exists(VariableWriteAccess a) implies any()) + or + (exists(any(Variable v).getParameter()) implies any()) + } + + class AstNode = Rust::AstNode; + + AstNode getChild(AstNode parent, int index) { + result = ParentChild::getImmediateChild(parent, index) and + not isLetChainAncestor(parent) + or + result = getLetChainChild(parent, index) + or + exists(Format f | + f = result.(FormatTemplateVariableAccess).getArgument().getParent() and + parent = f.getParent() and + index = f.getIndex() + ) + } + + abstract class Conditional extends AstNode { + abstract AstNode getCondition(); + + abstract AstNode getThen(); + + abstract AstNode getElse(); + } + + private class IfExprConditional extends Conditional instanceof IfExpr { + override AstNode getCondition() { result = IfExpr.super.getCondition() } + + override AstNode getThen() { result = IfExpr.super.getThen() } + + override AstNode getElse() { result = IfExpr.super.getElse() } + } + + private class WhileExprConditional extends Conditional instanceof WhileExpr { + override AstNode getCondition() { result = WhileExpr.super.getCondition() } + + override AstNode getThen() { result = WhileExpr.super.getLoopBody() } + + override AstNode getElse() { none() } + } + + private class MatchGuardConditional extends Conditional instanceof MatchGuard { + override AstNode getCondition() { result = MatchGuard.super.getCondition() } + + override AstNode getThen() { + exists(MatchArm arm | this = arm.getGuard() and result = arm.getExpr()) + } + + override AstNode getElse() { none() } + } + + abstract class SiblingShadowingDecl extends AstNode { + abstract AstNode getLhs(); + + abstract AstNode getRhs(); + + abstract AstNode getElse(); + } + + private class LetStmtSiblingShadowingDecl extends SiblingShadowingDecl instanceof LetStmt { + override AstNode getLhs() { result = LetStmt.super.getPat() } + + override AstNode getRhs() { result = LetStmt.super.getInitializer() } + + override AstNode getElse() { result = LetStmt.super.getLetElse() } + } + + private class LetExprSiblingShadowingDecl extends SiblingShadowingDecl instanceof LetExpr { + override AstNode getLhs() { result = LetExpr.super.getPat() } + + override AstNode getRhs() { result = LetExpr.super.getScrutinee() } + + override AstNode getElse() { none() } + } + + predicate declInScope(AstNode definingNode, string name, AstNode scope) { + // local variable + exists(Name n | variableDecl(definingNode, n, name) | + scope = any(SelfParam self | n = self.getName()).getCallable() + or + exists(Pat pat, Pat pat0 | + pat = getAPatAncestor*(pat0) and + (pat0 = definingNode or pat0.(IdentPat).getName() = n) + | + scope = any(MatchArm arm | pat = arm.getPat()) + or + scope = any(Input::SiblingShadowingDecl let | pat = let.getLhs()) + or + scope = any(ForExpr fe | pat = fe.getPat()).getLoopBody() + or + scope = any(Param p | pat = p.getPat()).getCallable() + ) + ) + or + // local function; behave as if they are defined at the beginning of the scope + definingNode = scope.(BlockExpr).getStmtList().getAStatement() and + name = definingNode.(Function).getName().getText() + } + + predicate accessCand(AstNode n, string name) { + name = n.(PathExpr).getPath().(PathImpl::IdentPath).getName() + or + name = n.(FormatTemplateVariableAccess).getName() + } + } + + private import LocalNameBinding + /** A variable. */ - class Variable extends MkVariable { - private AstNode definingNode; - private string text; - - Variable() { this = MkVariable(definingNode, text) } - - /** Gets the name of this variable as a string. */ - string getText() { result = text } - - /** Gets the location of this variable. */ - Location getLocation() { result = definingNode.getLocation() } - - /** Gets a textual representation of this variable. */ - string toString() { result = this.getText() } + class Variable extends Local { + Variable() { variableDecl(this.getDefiningNode(), _, _) } /** Gets an access to this variable. */ VariableAccess getAnAccess() { result.getVariable() = this } + /** Gets the name of this variable. */ + string getText() { result = super.getName() } + /** * Get the name of this variable. * * Normally, the name is unique, except when introduced in an or pattern. */ - Name getName() { variableDecl(definingNode, result, text) } + Name getName() { variableDecl(this.getDefiningNode(), result, super.getName()) } /** Gets the block that encloses this variable, if any. */ - BlockExpr getEnclosingBlock() { result = definingNode.getEnclosingBlock() } + BlockExpr getEnclosingBlock() { result = this.getDefiningNode().getEnclosingBlock() } /** Gets the `self` parameter that declares this variable, if any. */ SelfParam getSelfParam() { result.getName() = this.getName() } @@ -173,12 +285,20 @@ module Impl { IdentPat getPat() { result.getName() = this.getName() } /** Gets the enclosing CFG scope for this variable declaration. */ - CfgScope getEnclosingCfgScope() { result = definingNode.getEnclosingCfgScope() } + CfgScope getEnclosingCfgScope() { result = this.getDefiningNode().getEnclosingCfgScope() } - /** Gets the `let` statement that introduces this variable, if any. */ + /** + * Gets the `let` statement that introduces this variable, if any. + * + * This is restricted to simple `let` statements of the form `let x = ...;`. + */ LetStmt getLetStmt() { this.getPat() = result.getPat() } - /** Gets the `let` expression that introduces this variable, if any. */ + /** + * Gets the `let` expression that introduces this variable, if any. + * + * This is restricted to simple `let` expressions of the form `let x = ...`. + */ LetExpr getLetExpr() { this.getPat() = result.getPat() } /** Gets the initial value of this variable, if any. */ @@ -193,10 +313,10 @@ module Impl { /** Gets the parameter that introduces this variable, if any. */ cached ParamBase getParameter() { - Cached::ref() and + CachedStage::ref() and result = this.getSelfParam() or - result.(Param).getPat() = getAVariablePatAncestor(this) + result.(Param).getPat() = getAPatAncestor*(this.getPat()) } /** Hold is this variable is mutable. */ @@ -206,474 +326,17 @@ module Impl { predicate isImmutable() { not this.isMutable() } } - /** - * A path expression that may access a local variable. These are paths that - * only consist of a simple name (i.e., without generic arguments, - * qualifiers, etc.). - */ - private class VariableAccessCand extends PathExprBase { - string name_; - - VariableAccessCand() { - name_ = this.(PathExpr).getPath().(PathImpl::IdentPath).getName() - or - this.(FormatTemplateVariableAccess).getName() = name_ - } - - string toString() { result = name_ } - - string getName() { result = name_ } - } - - pragma[nomagic] - private Element getImmediateChildAdj(Element e, int preOrd, int index) { - result = ParentChild::getImmediateChild(e, index) and - preOrd = 0 and - not exists(ConditionScope cs | - e = cs.getParent() and - result = cs.getBody() - ) - or - result = e.(ConditionScope).getBody() and - preOrd = 1 and - index = 0 - } - - /** - * An adjusted version of `ParentChild::getImmediateChild`, which makes the following - * two adjustments: - * - * 1. For conditions like `if cond body`, instead of letting `body` be the second child - * of `if`, we make it the last child of `cond`. This ensures that variables - * introduced in the `cond` scope are available in `body`. - * - * 2. A similar adjustment is made for `while` loops: the body of the loop is made a - * child of the loop condition instead of the loop itself. - */ - pragma[nomagic] - private Element getImmediateChildAdj(Element e, int index) { - result = - rank[index + 1](Element res, int preOrd, int i | - res = getImmediateChildAdj(e, preOrd, i) - | - res order by preOrd, i - ) - } - - private Element getImmediateParentAdj(Element e) { e = getImmediateChildAdj(result, _) } - - private AstNode getAnAncestorInVariableScope(AstNode n) { - ( - n instanceof Pat or - n instanceof VariableAccessCand or - n instanceof LetStmt or - n = any(LetExpr le).getScrutinee() or - n instanceof VariableScope - ) and - exists(AstNode n0 | - result = getImmediateParentAdj(n0) or - result = n0.(FormatTemplateVariableAccess).getArgument().getParent().getParent() - | - n0 = n - or - n0 = getAnAncestorInVariableScope(n) and - not n0 instanceof VariableScope - ) - } - - /** Gets the immediately enclosing variable scope of `n`. */ - private VariableScope getEnclosingScope(AstNode n) { result = getAnAncestorInVariableScope(n) } - - /** - * Get all the pattern ancestors of this variable up to an including the - * root of the pattern. - */ - private Pat getAVariablePatAncestor(Variable v) { - result = v.getPat() - or - exists(Pat mid | - mid = getAVariablePatAncestor(v) and - result = mid.getParentPat() - ) - } - - /** - * Holds if a parameter declares the variable `v` inside variable scope `scope`. - */ - private predicate parameterDeclInScope(Variable v, VariableScope scope) { - exists(Callable f | - v.getParameter() = f.getParamList().getAParamBase() and - scope = f.getBody() - ) - } - - /** A subset of `Element`s for which we want to compute pre-order numbers. */ - private class RelevantElement extends Element { - RelevantElement() { - this instanceof VariableScope or - this instanceof VariableAccessCand or - this instanceof LetStmt or - this = any(LetExpr le).getScrutinee() or - getImmediateChildAdj(this, _) instanceof RelevantElement - } - - pragma[nomagic] - private RelevantElement getChild(int index) { result = getImmediateChildAdj(this, index) } - - pragma[nomagic] - private RelevantElement getImmediateChildAdjMin(int index) { - // A child may have multiple positions for different accessors, - // so always use the first - result = this.getChild(index) and - index = min(int i | result = this.getChild(i) | i) - } - - pragma[nomagic] - RelevantElement getImmediateChildAdj(int index) { - result = - rank[index + 1](Element res, int i | res = this.getImmediateChildAdjMin(i) | res order by i) - } - - pragma[nomagic] - RelevantElement getImmediateLastChild() { - exists(int last | - result = this.getImmediateChildAdj(last) and - not exists(this.getImmediateChildAdj(last + 1)) - ) - } - } - - /** - * Gets the pre-order numbering of `n`, where the immediately enclosing - * variable scope of `n` is `scope`. - */ - pragma[nomagic] - private int getPreOrderNumbering(VariableScope scope, RelevantElement n) { - n = scope and - result = 0 - or - exists(RelevantElement parent | - not parent instanceof VariableScope - or - parent = scope - | - // first child of a previously numbered node - result = getPreOrderNumbering(scope, parent) + 1 and - n = parent.getImmediateChildAdj(0) - or - // non-first child of a previously numbered node - exists(RelevantElement child, int i | - result = getLastPreOrderNumbering(scope, child) + 1 and - child = parent.getImmediateChildAdj(i) and - n = parent.getImmediateChildAdj(i + 1) - ) - ) - } - - /** - * Gets the pre-order numbering of the _last_ node nested under `n`, where the - * immediately enclosing variable scope of `n` (and the last node) is `scope`. - */ - pragma[nomagic] - private int getLastPreOrderNumbering(VariableScope scope, RelevantElement n) { - exists(RelevantElement leaf | - result = getPreOrderNumbering(scope, leaf) and - leaf != scope and - ( - not exists(leaf.getImmediateChildAdj(_)) - or - leaf instanceof VariableScope - ) - | - n = leaf - or - n.getImmediateLastChild() = leaf and - not n instanceof VariableScope - ) - or - exists(RelevantElement mid | - mid = n.getImmediateLastChild() and - result = getLastPreOrderNumbering(scope, mid) and - not mid instanceof VariableScope and - not n instanceof VariableScope - ) - } - - /** - * Holds if `v` is named `name` and is declared inside variable scope - * `scope`. The pre-order numbering of the binding site of `v`, amongst - * all nodes nested under `scope`, is `ord`. - */ - private predicate variableDeclInScope(Variable v, VariableScope scope, string name, int ord) { - name = v.getText() and - ( - parameterDeclInScope(v, scope) and - ord = getPreOrderNumbering(scope, scope) - or - exists(Pat pat | pat = getAVariablePatAncestor(v) | - exists(MatchArm arm | - pat = arm.getPat() and - ord = getPreOrderNumbering(scope, scope) - | - scope = arm.getGuard() - or - not arm.hasGuard() and scope = arm.getExpr() - ) - or - exists(LetStmt let | - let.getPat() = pat and - scope = getEnclosingScope(let) and - // for `let` statements, variables are bound _after_ the statement, i.e. - // not in the RHS - ord = getLastPreOrderNumbering(scope, let) + 1 - ) - or - exists(LetExpr let, Expr scrutinee | - let.getPat() = pat and - scrutinee = let.getScrutinee() and - scope = getEnclosingScope(scrutinee) and - // for `let` expressions, variables are bound _after_ the expression, i.e. - // not in the RHS - ord = getLastPreOrderNumbering(scope, scrutinee) + 1 - ) - or - exists(ForExpr fe | - fe.getPat() = pat and - scope = fe.getLoopBody() and - ord = getPreOrderNumbering(scope, scope) - ) - ) - ) - } - - /** - * Holds if `cand` may access a variable named `name` at pre-order number `ord` - * in the variable scope `scope`. - * - * `nestLevel` is the number of nested scopes that need to be traversed - * to reach `scope` from `cand`. - */ - private predicate variableAccessCandInScope( - VariableAccessCand cand, VariableScope scope, string name, int nestLevel, int ord - ) { - name = cand.getName() and - ( - scope = cand - or - not cand instanceof VariableScope and - scope = getEnclosingScope(cand) - ) and - ord = getPreOrderNumbering(scope, cand) and - nestLevel = 0 - or - exists(VariableScope inner | - variableAccessCandInScope(cand, inner, name, nestLevel - 1, _) and - scope = getEnclosingScope(inner) and - // Use the pre-order number of the inner scope as the number of the access. This allows - // us to collapse multiple accesses in inner scopes to a single entity - ord = getPreOrderNumbering(scope, inner) - ) - } - - private newtype TDefOrAccessCand = - TDefOrAccessCandNestedFunction(Function f, BlockExprScope scope) { - f = scope.getStmtList().getAStatement() - } or - TDefOrAccessCandVariable(Variable v) or - TDefOrAccessCandVariableAccessCand(VariableAccessCand va) - - /** - * A nested function declaration, variable declaration, or variable (or function) - * access candidate. - * - * In order to determine whether a candidate is an actual variable/function access, - * we rank declarations and candidates by their position in the AST. - * - * The ranking must take names into account, but also variable scopes; below a comment - * `rank(scope, name, i)` means that the declaration/access on the given line has rank - * `i` amongst all declarations/accesses inside variable scope `scope`, for name `name`: - * - * ```rust - * fn f() { // scope0 - * let x = 0; // rank(scope0, "x", 0) - * use(x); // rank(scope0, "x", 1) - * let x = // rank(scope0, "x", 3) - * x + 1; // rank(scope0, "x", 2) - * let y = // rank(scope0, "y", 0) - * x; // rank(scope0, "x", 4) - * - * { // scope1 - * use(x); // rank(scope1, "x", 0), rank(scope0, "x", 4) - * use(y); // rank(scope1, "y", 0), rank(scope0, "y", 1) - * let x = 2; // rank(scope1, "x", 1) - * use(x); // rank(scope1, "x", 2), rank(scope0, "x", 4) - * } - * } - * ``` - * - * Function/variable declarations are only ranked in the scope that they bind into, - * while accesses candidates propagate outwards through scopes, as they may access - * declarations from outer scopes. - * - * For an access candidate with ranks `{ rank(scope_i, name, rnk_i) | i in I }` and - * declarations `d in D` with ranks `rnk(scope_d, name, rnk_d)`, the target is - * calculated as - * ``` - * max_{i in I} ( - * max_{d in D | scope_d = scope_i and rnk_d < rnk_i} ( - * d - * ) - * ) - * ``` - * - * i.e., its the nearest declaration before the access in the same (or outer) scope - * as the access. - */ - abstract private class DefOrAccessCand extends TDefOrAccessCand { - abstract string toString(); - - abstract Location getLocation(); - - pragma[nomagic] - abstract predicate rankBy(string name, VariableScope scope, int ord, int kind); - } - - abstract private class NestedFunctionOrVariable extends DefOrAccessCand { } - - private class DefOrAccessCandNestedFunction extends NestedFunctionOrVariable, - TDefOrAccessCandNestedFunction - { - private Function f; - private BlockExprScope scope_; - - DefOrAccessCandNestedFunction() { this = TDefOrAccessCandNestedFunction(f, scope_) } - - override string toString() { result = f.toString() } - - override Location getLocation() { result = f.getLocation() } - - override predicate rankBy(string name, VariableScope scope, int ord, int kind) { - // nested functions behave as if they are defined at the beginning of the scope - name = f.getName().getText() and - scope = scope_ and - ord = 0 and - kind = 0 - } - } - - private class DefOrAccessCandVariable extends NestedFunctionOrVariable, TDefOrAccessCandVariable { - private Variable v; - - DefOrAccessCandVariable() { this = TDefOrAccessCandVariable(v) } - - override string toString() { result = v.toString() } - - override Location getLocation() { result = v.getLocation() } - - override predicate rankBy(string name, VariableScope scope, int ord, int kind) { - variableDeclInScope(v, scope, name, ord) and - kind = 1 - } - } - - private class DefOrAccessCandVariableAccessCand extends DefOrAccessCand, - TDefOrAccessCandVariableAccessCand - { - private VariableAccessCand va; - - DefOrAccessCandVariableAccessCand() { this = TDefOrAccessCandVariableAccessCand(va) } - - override string toString() { result = va.toString() } - - override Location getLocation() { result = va.getLocation() } - - override predicate rankBy(string name, VariableScope scope, int ord, int kind) { - variableAccessCandInScope(va, scope, name, _, ord) and - kind = 2 - } - } - - private module DenseRankInput implements DenseRankInputSig2 { - class C1 = VariableScope; - - class C2 = string; - - class Ranked = DefOrAccessCand; - - int getRank(VariableScope scope, string name, DefOrAccessCand v) { - v = - rank[result](DefOrAccessCand v0, int ord, int kind | - v0.rankBy(name, scope, ord, kind) - | - v0 order by ord, kind - ) - } - } - - /** - * Gets the rank of `v` amongst all other declarations or access candidates - * to a variable named `name` in the variable scope `scope`. - */ - private int rankVariableOrAccess(VariableScope scope, string name, DefOrAccessCand v) { - v = DenseRank2::denseRank(scope, name, result + 1) - } - - /** - * Holds if `v` can reach rank `rnk` in the variable scope `scope`. This is needed to - * take shadowing into account, for example in - * - * ```rust - * let x = 0; // rank 0 - * use(x); // rank 1 - * let x = ""; // rank 2 - * use(x); // rank 3 - * ``` - * - * the declaration at rank 0 can only reach the access at rank 1, while the declaration - * at rank 2 can only reach the access at rank 3. - */ - private predicate variableReachesRank( - VariableScope scope, string name, NestedFunctionOrVariable v, int rnk - ) { - rnk = rankVariableOrAccess(scope, name, v) - or - variableReachesRank(scope, name, v, rnk - 1) and - rnk = rankVariableOrAccess(scope, name, TDefOrAccessCandVariableAccessCand(_)) - } - - private predicate variableReachesCand( - VariableScope scope, string name, NestedFunctionOrVariable v, VariableAccessCand cand, - int nestLevel - ) { - exists(int rnk | - variableReachesRank(scope, name, v, rnk) and - rnk = rankVariableOrAccess(scope, name, TDefOrAccessCandVariableAccessCand(cand)) and - variableAccessCandInScope(cand, scope, name, nestLevel, _) - ) - } - - pragma[nomagic] - predicate access(string name, NestedFunctionOrVariable v, VariableAccessCand cand) { - v = - min(NestedFunctionOrVariable v0, int nestLevel | - variableReachesCand(_, name, v0, cand, nestLevel) - | - v0 order by nestLevel - ) - } - /** A variable access. */ - class VariableAccess extends PathExprBase { - private string name; - private Variable v; - - VariableAccess() { variableAccess(name, v, this) } + class VariableAccess extends LocalAccess { + VariableAccess() { this.getLocal() instanceof Variable } /** Gets the variable being accessed. */ - Variable getVariable() { result = v } + Variable getVariable() { result = super.getLocal() } /** Holds if this access is a capture. */ - predicate isCapture() { this.getEnclosingCfgScope() != v.getEnclosingCfgScope() } + predicate isCapture() { + this.getEnclosingCfgScope() != this.getVariable().getEnclosingCfgScope() + } } /** Holds if `e` occurs in the LHS of an assignment operation. */ @@ -682,7 +345,7 @@ module Impl { or exists(Expr mid | assignmentOperationDescendant(ao, mid) and - getImmediateParentAdj(e) = mid and + mid = e.getParentNode() and not mid instanceof DerefExpr and not mid instanceof FieldExpr and not mid instanceof IndexExpr @@ -695,7 +358,7 @@ module Impl { cached VariableWriteAccess() { - Cached::ref() and + CachedStage::ref() and assignmentOperationDescendant(ae, this) } @@ -707,7 +370,7 @@ module Impl { class VariableReadAccess extends VariableAccess { cached VariableReadAccess() { - Cached::ref() and + CachedStage::ref() and not this instanceof VariableWriteAccess and not this = any(RefExpr re).getExpr() and not this = any(CompoundAssignmentExpr cae).getLhs() @@ -715,47 +378,10 @@ module Impl { } /** A nested function access. */ - class NestedFunctionAccess extends PathExprBase { + class NestedFunctionAccess extends LocalAccess { private Function f; - NestedFunctionAccess() { nestedFunctionAccess(_, f, this) } - /** Gets the function being accessed. */ - Function getFunction() { result = f } + Function getFunction() { result = super.getLocal().getDefiningNode() } } - - cached - private module Cached { - cached - predicate ref() { 1 = 1 } - - cached - predicate backref() { - 1 = 1 - or - variableDecl(_, _, _) - or - exists(VariableReadAccess a) - or - exists(VariableWriteAccess a) - or - exists(any(Variable v).getParameter()) - } - - cached - newtype TVariable = - MkVariable(AstNode definingNode, string name) { variableDecl(definingNode, _, name) } - - cached - predicate variableAccess(string name, Variable v, VariableAccessCand cand) { - access(name, TDefOrAccessCandVariable(v), cand) - } - - cached - predicate nestedFunctionAccess(string name, Function f, VariableAccessCand cand) { - access(name, TDefOrAccessCandNestedFunction(f, _), cand) - } - } - - private import Cached } diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 062c2f4e635..311ee93a127 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -16,6 +16,7 @@ dependencies: codeql/tutorial: ${workspace} codeql/typeinference: ${workspace} codeql/util: ${workspace} + codeql/namebinding: ${workspace} dataExtensions: - /**/*.model.yml warnOnImplicitThis: true diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index d428d49cf1d..a5583df8be4 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -442,9 +442,9 @@ read | main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | main.rs:824:15:824:15 | x | | main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | main.rs:829:15:829:15 | x | | main.rs:825:18:825:18 | x | main.rs:825:18:825:18 | x | main.rs:826:20:826:20 | x | +| main.rs:838:9:838:9 | x | main.rs:838:9:838:9 | x | main.rs:843:19:843:19 | x | | main.rs:838:9:838:9 | x | main.rs:838:9:838:9 | x | main.rs:845:19:845:19 | x | | main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | main.rs:841:9:841:9 | x | -| main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | main.rs:843:19:843:19 | x | firstRead | main.rs:5:14:5:14 | s | main.rs:5:14:5:14 | s | main.rs:7:20:7:20 | s | | main.rs:10:14:10:14 | i | main.rs:10:14:10:14 | i | main.rs:12:20:12:20 | i | @@ -628,6 +628,7 @@ firstRead | main.rs:814:13:814:16 | test | main.rs:814:13:814:16 | test | main.rs:816:9:816:12 | test | | main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | main.rs:824:15:824:15 | x | | main.rs:825:18:825:18 | x | main.rs:825:18:825:18 | x | main.rs:826:20:826:20 | x | +| main.rs:838:9:838:9 | x | main.rs:838:9:838:9 | x | main.rs:843:19:843:19 | x | | main.rs:838:9:838:9 | x | main.rs:838:9:838:9 | x | main.rs:845:19:845:19 | x | | main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | main.rs:841:9:841:9 | x | adjacentReads @@ -678,7 +679,6 @@ adjacentReads | main.rs:712:13:712:13 | a | main.rs:712:13:712:13 | a | main.rs:714:5:714:5 | a | main.rs:715:15:715:15 | a | | main.rs:721:9:721:9 | x | main.rs:721:9:721:9 | x | main.rs:722:20:722:20 | x | main.rs:723:15:723:15 | x | | main.rs:823:13:823:13 | x | main.rs:823:13:823:13 | x | main.rs:824:15:824:15 | x | main.rs:829:15:829:15 | x | -| main.rs:840:13:840:13 | x | main.rs:840:13:840:13 | x | main.rs:841:9:841:9 | x | main.rs:843:19:843:19 | x | phi | main.rs:245:9:245:44 | SSA phi(a3) | main.rs:245:9:245:44 | a3 | main.rs:245:22:245:23 | a3 | | main.rs:245:9:245:44 | SSA phi(a3) | main.rs:245:9:245:44 | a3 | main.rs:245:42:245:43 | a3 | diff --git a/rust/ql/test/library-tests/variables/main.rs b/rust/ql/test/library-tests/variables/main.rs index c20f1fe42c3..1435d79aaca 100644 --- a/rust/ql/test/library-tests/variables/main.rs +++ b/rust/ql/test/library-tests/variables/main.rs @@ -840,7 +840,7 @@ fn let_in_block_in_cond() { let x = 1; // x2 x > 0 // $ read_access=x2 } { - print_i64(x); // $ SPURIOUS: read_access=x2 $ MISSING: read_access=x1 + print_i64(x); // $ read_access=x1 } else { print_i64(x); // $ read_access=x1 } diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index b28d16a5c34..de94e826393 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -405,7 +405,7 @@ variableAccess | main.rs:826:20:826:20 | x | main.rs:825:18:825:18 | x | | main.rs:829:15:829:15 | x | main.rs:823:13:823:13 | x | | main.rs:841:9:841:9 | x | main.rs:840:13:840:13 | x | -| main.rs:843:19:843:19 | x | main.rs:840:13:840:13 | x | +| main.rs:843:19:843:19 | x | main.rs:838:9:838:9 | x | | main.rs:845:19:845:19 | x | main.rs:838:9:838:9 | x | variableWriteAccess | main.rs:27:5:27:6 | x2 | main.rs:25:13:25:14 | x2 | @@ -640,7 +640,7 @@ variableReadAccess | main.rs:826:20:826:20 | x | main.rs:825:18:825:18 | x | | main.rs:829:15:829:15 | x | main.rs:823:13:823:13 | x | | main.rs:841:9:841:9 | x | main.rs:840:13:840:13 | x | -| main.rs:843:19:843:19 | x | main.rs:840:13:840:13 | x | +| main.rs:843:19:843:19 | x | main.rs:838:9:838:9 | x | | main.rs:845:19:845:19 | x | main.rs:838:9:838:9 | x | variableInitializer | main.rs:20:9:20:10 | x1 | main.rs:20:14:20:16 | "a" | From aeb82858d74e15787169a2c301adb74cbfcee660 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 21 May 2026 14:08:10 +0200 Subject: [PATCH 132/226] Rust: Run codegen --- rust/ql/.generated.list | 1 - rust/ql/.gitattributes | 1 - rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 003ede90023..87cd5eb4808 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -332,7 +332,6 @@ lib/codeql/rust/elements/internal/NeverTypeReprConstructor.qll 2e0a9c75e389e9ef4 lib/codeql/rust/elements/internal/OffsetOfExprConstructor.qll 616e146562adb3ac0fba4d6f55dd6ce60518ed377c0856f1f09ba49593e7bfab 80518ce90fc6d08011d6f5fc2a543958067739e1b0a6a5f2ed90fc9b1db078f0 lib/codeql/rust/elements/internal/OffsetOfExprImpl.qll e52d4596068cc54719438121f7d5afcaab04e0c70168ac5e4df1a3a0969817a6 6ab37e659d79e02fb2685d6802ae124157bf14b6f790b31688f437c87f40f52c lib/codeql/rust/elements/internal/OrPatConstructor.qll 4ef583e07298487c0c4c6d7c76ffcc04b1e5fe58aba0c1da3e2c8446a9e0c92b 980a6bd176ae5e5b11c134569910c5468ba91f480982d846e222d031a6a05f1a -lib/codeql/rust/elements/internal/ParamBaseImpl.qll fe11999c728c443c46c992e9bed7a2b3e23afa16ae99592e70054bc57ae371b8 df86fdb23266bdfb9ed8a8f02558a760b67f173943b9d075b081229eb5844f66 lib/codeql/rust/elements/internal/ParamConstructor.qll b98a2d8969f289fdcc8c0fb11cbd19a3b0c71be038c4a74f5988295a2bae52f0 77d81b31064167945b79b19d9697b57ca24462c3a7cc19e462c4693ce87db532 lib/codeql/rust/elements/internal/ParamListConstructor.qll 3123142ab3cab46fb53d7f3eff6ba2d3ff7a45b78839a53dc1979a9c6a54920e 165f3d777ea257cfcf142cc4ba9a0ebcd1902eb99842b8a6657c87087f3df6fe lib/codeql/rust/elements/internal/ParenExprConstructor.qll 104b67dc3fd53ab52e2a42ffde37f3a3a50647aa7bf35df9ba9528e9670da210 d1f5937756e87a477710c61698d141cdad0ccce8b07ecb51bab00330a1ca9835 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index d8004cb5b35..6ea7d011a5d 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -334,7 +334,6 @@ /lib/codeql/rust/elements/internal/OffsetOfExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/OffsetOfExprImpl.qll linguist-generated /lib/codeql/rust/elements/internal/OrPatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/ParamBaseImpl.qll linguist-generated /lib/codeql/rust/elements/internal/ParamConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ParamListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/ParenExprConstructor.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll index 5badd696f1a..ed7f0dd5d5e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ParamBaseImpl.qll @@ -12,6 +12,7 @@ private import codeql.rust.elements.Callable * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A normal parameter, `Param`, or a self parameter `SelfParam`. */ From 7718fe40a08621a0730333e52587027c15a47a1e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 27 May 2026 08:51:36 +0200 Subject: [PATCH 133/226] Ruby: Add more variable tests --- .../variables/parameter.expected | 1 + .../ql/test/library-tests/variables/scopes.rb | 24 ++++++ .../test/library-tests/variables/ssa.expected | 81 ++++++++++++------ .../variables/varaccess.expected | 85 +++++++++++++------ .../library-tests/variables/variable.expected | 9 +- .../variables/varscopes.expected | 6 +- 6 files changed, 153 insertions(+), 53 deletions(-) diff --git a/ruby/ql/test/library-tests/variables/parameter.expected b/ruby/ql/test/library-tests/variables/parameter.expected index 6e6c8426f86..c04df71117d 100644 --- a/ruby/ql/test/library-tests/variables/parameter.expected +++ b/ruby/ql/test/library-tests/variables/parameter.expected @@ -28,6 +28,7 @@ parameterVariable | parameters.rb:59:22:59:26 | (..., ...) | parameters.rb:59:25:59:25 | c | | scopes.rb:2:14:2:14 | x | scopes.rb:2:14:2:14 | x | | scopes.rb:9:14:9:14 | x | scopes.rb:9:14:9:14 | x | +| scopes.rb:69:15:69:15 | x | scopes.rb:69:15:69:15 | x | | ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | | ssa.rb:18:8:18:8 | x | ssa.rb:18:8:18:8 | x | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | diff --git a/ruby/ql/test/library-tests/variables/scopes.rb b/ruby/ql/test/library-tests/variables/scopes.rb index db55da3b77f..c37146cd681 100644 --- a/ruby/ql/test/library-tests/variables/scopes.rb +++ b/ruby/ql/test/library-tests/variables/scopes.rb @@ -47,3 +47,27 @@ module M #{var2} EOF end + +module ExceptionVariable + class MyException < Exception + end + + x = 1 + puts x + + begin + raise MyException + rescue MyException => x # reuses `x` from above + puts x + end + puts x # prints `MyException`, not `1` +end + +module ParameterShadowing + x = 1 + xs = [1, 2, 3] + xs.each do |x| + puts x + end + puts x # prints `1`, not `3` +end \ No newline at end of file diff --git a/ruby/ql/test/library-tests/variables/ssa.expected b/ruby/ql/test/library-tests/variables/ssa.expected index 8e69feef15b..ab68d17ac2a 100644 --- a/ruby/ql/test/library-tests/variables/ssa.expected +++ b/ruby/ql/test/library-tests/variables/ssa.expected @@ -86,12 +86,12 @@ definition | parameters.rb:59:20:59:20 | a | parameters.rb:59:20:59:20 | a | | parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b | | parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | -| scopes.rb:1:1:49:4 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | -| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:49:4 | self | +| scopes.rb:1:1:73:3 | self (scopes.rb) | scopes.rb:1:1:73:3 | self | +| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:73:3 | self | | scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | | scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | | scopes.rb:9:9:18:3 | a | scopes.rb:7:1:7:1 | a | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | | scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | | scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | | scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | @@ -99,13 +99,18 @@ definition | scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | | scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | | scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | -| scopes.rb:26:1:26:12 | self (A) | scopes.rb:26:1:26:12 | self | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | -| scopes.rb:28:1:30:3 | self (B) | scopes.rb:28:1:30:3 | self | -| scopes.rb:34:1:36:3 | self (C) | scopes.rb:34:1:36:3 | self | | scopes.rb:41:1:49:3 | self (M) | scopes.rb:41:1:49:3 | self | | scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | | scopes.rb:46:5:46:8 | var2 | scopes.rb:46:5:46:8 | var2 | +| scopes.rb:51:1:64:3 | self (ExceptionVariable) | scopes.rb:51:1:64:3 | self | +| scopes.rb:55:3:55:3 | x | scopes.rb:55:3:55:3 | x | +| scopes.rb:60:25:60:25 | x | scopes.rb:55:3:55:3 | x | +| scopes.rb:66:1:73:3 | self (ParameterShadowing) | scopes.rb:66:1:73:3 | self | +| scopes.rb:67:3:67:3 | x | scopes.rb:67:3:67:3 | x | +| scopes.rb:68:3:68:4 | xs | scopes.rb:68:3:68:4 | xs | +| scopes.rb:69:11:71:5 | self | scopes.rb:66:1:73:3 | self | +| scopes.rb:69:15:69:15 | x | scopes.rb:69:15:69:15 | x | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | | ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | | ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | @@ -262,20 +267,20 @@ read | parameters.rb:59:20:59:20 | a | parameters.rb:59:20:59:20 | a | parameters.rb:60:11:60:11 | a | | parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b | parameters.rb:60:16:60:16 | b | | parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c | -| scopes.rb:1:1:49:4 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self | -| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self | -| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:3:9:3:9 | self | -| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:5:4:5:9 | self | +| scopes.rb:1:1:73:3 | self (scopes.rb) | scopes.rb:1:1:73:3 | self | scopes.rb:8:1:8:6 | self | +| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:3:4:3:9 | self | +| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:3:9:3:9 | self | +| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:5:4:5:9 | self | | scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a | | scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a | | scopes.rb:9:9:18:3 | a | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a | | scopes.rb:9:9:18:3 | a | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:4 | a | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:12:4:12:9 | self | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:14:4:14:9 | self | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:15:4:15:9 | self | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:16:4:16:9 | self | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:17:4:17:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:10:4:10:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:12:4:12:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:14:4:14:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:15:4:15:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:16:4:16:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:17:4:17:9 | self | | scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | | scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | | scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | @@ -294,6 +299,18 @@ read | scopes.rb:41:1:49:3 | self (M) | scopes.rb:41:1:49:3 | self | scopes.rb:45:5:45:7 | self | | scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | | scopes.rb:46:5:46:8 | var2 | scopes.rb:46:5:46:8 | var2 | scopes.rb:47:5:47:8 | var2 | +| scopes.rb:51:1:64:3 | self (ExceptionVariable) | scopes.rb:51:1:64:3 | self | scopes.rb:56:3:56:8 | self | +| scopes.rb:51:1:64:3 | self (ExceptionVariable) | scopes.rb:51:1:64:3 | self | scopes.rb:59:5:59:21 | self | +| scopes.rb:51:1:64:3 | self (ExceptionVariable) | scopes.rb:51:1:64:3 | self | scopes.rb:61:5:61:10 | self | +| scopes.rb:51:1:64:3 | self (ExceptionVariable) | scopes.rb:51:1:64:3 | self | scopes.rb:63:3:63:8 | self | +| scopes.rb:55:3:55:3 | x | scopes.rb:55:3:55:3 | x | scopes.rb:56:8:56:8 | x | +| scopes.rb:60:25:60:25 | x | scopes.rb:55:3:55:3 | x | scopes.rb:61:10:61:10 | x | +| scopes.rb:60:25:60:25 | x | scopes.rb:55:3:55:3 | x | scopes.rb:63:8:63:8 | x | +| scopes.rb:66:1:73:3 | self (ParameterShadowing) | scopes.rb:66:1:73:3 | self | scopes.rb:72:3:72:8 | self | +| scopes.rb:67:3:67:3 | x | scopes.rb:67:3:67:3 | x | scopes.rb:72:8:72:8 | x | +| scopes.rb:68:3:68:4 | xs | scopes.rb:68:3:68:4 | xs | scopes.rb:69:3:69:4 | xs | +| scopes.rb:69:11:71:5 | self | scopes.rb:66:1:73:3 | self | scopes.rb:70:5:70:10 | self | +| scopes.rb:69:15:69:15 | x | scopes.rb:69:15:69:15 | x | scopes.rb:70:10:70:10 | x | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:3:3:3:8 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:4:3:4:12 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:7:5:7:10 | self | @@ -443,12 +460,12 @@ firstRead | parameters.rb:59:20:59:20 | a | parameters.rb:59:20:59:20 | a | parameters.rb:60:11:60:11 | a | | parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b | parameters.rb:60:16:60:16 | b | | parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c | -| scopes.rb:1:1:49:4 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self | -| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self | +| scopes.rb:1:1:73:3 | self (scopes.rb) | scopes.rb:1:1:73:3 | self | scopes.rb:8:1:8:6 | self | +| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:3:4:3:9 | self | | scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a | | scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a | | scopes.rb:9:9:18:3 | a | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:10:4:10:9 | self | | scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | | scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | | scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | @@ -460,6 +477,14 @@ firstRead | scopes.rb:41:1:49:3 | self (M) | scopes.rb:41:1:49:3 | self | scopes.rb:45:5:45:7 | self | | scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | | scopes.rb:46:5:46:8 | var2 | scopes.rb:46:5:46:8 | var2 | scopes.rb:47:5:47:8 | var2 | +| scopes.rb:51:1:64:3 | self (ExceptionVariable) | scopes.rb:51:1:64:3 | self | scopes.rb:56:3:56:8 | self | +| scopes.rb:55:3:55:3 | x | scopes.rb:55:3:55:3 | x | scopes.rb:56:8:56:8 | x | +| scopes.rb:60:25:60:25 | x | scopes.rb:55:3:55:3 | x | scopes.rb:61:10:61:10 | x | +| scopes.rb:66:1:73:3 | self (ParameterShadowing) | scopes.rb:66:1:73:3 | self | scopes.rb:72:3:72:8 | self | +| scopes.rb:67:3:67:3 | x | scopes.rb:67:3:67:3 | x | scopes.rb:72:8:72:8 | x | +| scopes.rb:68:3:68:4 | xs | scopes.rb:68:3:68:4 | xs | scopes.rb:69:3:69:4 | xs | +| scopes.rb:69:11:71:5 | self | scopes.rb:66:1:73:3 | self | scopes.rb:70:5:70:10 | self | +| scopes.rb:69:15:69:15 | x | scopes.rb:69:15:69:15 | x | scopes.rb:70:10:70:10 | x | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:3:3:3:8 | self | | ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | ssa.rb:5:6:5:6 | b | | ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | ssa.rb:3:8:3:8 | i | @@ -532,14 +557,14 @@ adjacentReads | parameters.rb:25:1:28:3 | self (opt_param) | parameters.rb:25:1:28:3 | self | parameters.rb:26:3:26:11 | self | parameters.rb:27:3:27:11 | self | | parameters.rb:25:15:25:18 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:40:25:43 | name | parameters.rb:26:8:26:11 | name | | parameters.rb:54:9:57:3 | self | parameters.rb:1:1:62:1 | self | parameters.rb:55:4:55:9 | self | parameters.rb:56:4:56:9 | self | -| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self | scopes.rb:3:9:3:9 | self | -| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:3:9:3:9 | self | scopes.rb:5:4:5:9 | self | +| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:3:4:3:9 | self | scopes.rb:3:9:3:9 | self | +| scopes.rb:2:9:6:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:3:9:3:9 | self | scopes.rb:5:4:5:9 | self | | scopes.rb:9:9:18:3 | a | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a | scopes.rb:11:4:11:4 | a | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self | scopes.rb:12:4:12:9 | self | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:12:4:12:9 | self | scopes.rb:14:4:14:9 | self | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:14:4:14:9 | self | scopes.rb:15:4:15:9 | self | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:15:4:15:9 | self | scopes.rb:16:4:16:9 | self | -| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:49:4 | self | scopes.rb:16:4:16:9 | self | scopes.rb:17:4:17:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:10:4:10:9 | self | scopes.rb:12:4:12:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:12:4:12:9 | self | scopes.rb:14:4:14:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:14:4:14:9 | self | scopes.rb:15:4:15:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:15:4:15:9 | self | scopes.rb:16:4:16:9 | self | +| scopes.rb:9:9:18:3 | self | scopes.rb:1:1:73:3 | self | scopes.rb:16:4:16:9 | self | scopes.rb:17:4:17:9 | self | | scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:11:13:11 | __synth__2__1 | scopes.rb:13:14:13:14 | __synth__2__1 | | scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | scopes.rb:13:4:13:4 | __synth__3 | scopes.rb:13:7:13:7 | __synth__3 | | scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | scopes.rb:13:7:13:7 | __synth__3 | scopes.rb:13:10:13:15 | __synth__3 | @@ -547,6 +572,10 @@ adjacentReads | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:31:10:31:10 | x | scopes.rb:34:7:34:7 | x | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:34:7:34:7 | x | scopes.rb:34:14:34:14 | x | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:34:14:34:14 | x | scopes.rb:37:5:37:5 | x | +| scopes.rb:51:1:64:3 | self (ExceptionVariable) | scopes.rb:51:1:64:3 | self | scopes.rb:56:3:56:8 | self | scopes.rb:59:5:59:21 | self | +| scopes.rb:51:1:64:3 | self (ExceptionVariable) | scopes.rb:51:1:64:3 | self | scopes.rb:59:5:59:21 | self | scopes.rb:61:5:61:10 | self | +| scopes.rb:51:1:64:3 | self (ExceptionVariable) | scopes.rb:51:1:64:3 | self | scopes.rb:61:5:61:10 | self | scopes.rb:63:3:63:8 | self | +| scopes.rb:60:25:60:25 | x | scopes.rb:55:3:55:3 | x | scopes.rb:61:10:61:10 | x | scopes.rb:63:8:63:8 | x | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:3:3:3:8 | self | ssa.rb:4:3:4:12 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:4:3:4:12 | self | ssa.rb:7:5:7:10 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:4:3:4:12 | self | ssa.rb:11:5:11:10 | self | diff --git a/ruby/ql/test/library-tests/variables/varaccess.expected b/ruby/ql/test/library-tests/variables/varaccess.expected index e79f6ca3023..56113f13e35 100644 --- a/ruby/ql/test/library-tests/variables/varaccess.expected +++ b/ruby/ql/test/library-tests/variables/varaccess.expected @@ -155,43 +155,43 @@ variableAccess | parameters.rb:60:16:60:16 | b | parameters.rb:59:23:59:23 | b | parameters.rb:59:1:61:3 | tuples_nested | | parameters.rb:60:21:60:21 | c | parameters.rb:59:25:59:25 | c | parameters.rb:59:1:61:3 | tuples_nested | | scopes.rb:2:14:2:14 | x | scopes.rb:2:14:2:14 | x | scopes.rb:2:9:6:3 | do ... end | -| scopes.rb:3:4:3:9 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:3:9:3:9 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:3:4:3:9 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:3:9:3:9 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | scopes.rb:2:9:6:3 | do ... end | -| scopes.rb:5:4:5:9 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:5:4:5:9 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:5:9:5:9 | a | scopes.rb:4:4:4:4 | a | scopes.rb:2:9:6:3 | do ... end | -| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:8:1:8:6 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:8:6:8:6 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:8:1:8:6 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:8:6:8:6 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:9:14:9:14 | x | scopes.rb:9:14:9:14 | x | scopes.rb:9:9:18:3 | do ... end | -| scopes.rb:10:4:10:9 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:10:9:10:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:12:4:12:9 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:12:9:12:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:10:4:10:9 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:10:9:10:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:12:4:12:9 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:12:9:12:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:9:9:18:3 | do ... end | | scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | scopes.rb:9:9:18:3 | do ... end | | scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | scopes.rb:9:9:18:3 | do ... end | -| scopes.rb:14:4:14:9 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:14:9:14:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:15:4:15:9 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:14:4:14:9 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:14:9:14:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:15:4:15:9 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:15:9:15:9 | b | scopes.rb:13:7:13:7 | b | scopes.rb:9:9:18:3 | do ... end | -| scopes.rb:16:4:16:9 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:16:4:16:9 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:16:9:16:9 | c | scopes.rb:13:11:13:11 | c | scopes.rb:9:9:18:3 | do ... end | -| scopes.rb:17:4:17:9 | self | scopes.rb:1:1:49:4 | self | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:17:4:17:9 | self | scopes.rb:1:1:73:3 | self | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:17:9:17:9 | d | scopes.rb:13:14:13:14 | d | scopes.rb:9:9:18:3 | do ... end | -| scopes.rb:24:1:24:6 | script | scopes.rb:24:1:24:6 | script | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:28:8:28:8 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:24:1:24:6 | script | scopes.rb:24:1:24:6 | script | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:28:8:28:8 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:29:3:29:3 | x | scopes.rb:29:3:29:3 | x | scopes.rb:28:1:30:3 | B | -| scopes.rb:31:10:31:10 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:31:10:31:10 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:32:3:32:3 | x | scopes.rb:32:3:32:3 | x | scopes.rb:31:1:33:3 | class << ... | -| scopes.rb:34:7:34:7 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:49:4 | scopes.rb | -| scopes.rb:34:14:34:14 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:34:7:34:7 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:73:3 | scopes.rb | +| scopes.rb:34:14:34:14 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:35:3:35:3 | x | scopes.rb:35:3:35:3 | x | scopes.rb:34:1:36:3 | C | -| scopes.rb:37:5:37:5 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:37:5:37:5 | x | scopes.rb:27:1:27:1 | x | scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:38:3:38:3 | x | scopes.rb:38:3:38:3 | x | scopes.rb:37:1:39:3 | foo | | scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | scopes.rb:41:1:49:3 | M | | scopes.rb:43:2:43:4 | foo | scopes.rb:43:2:43:4 | foo | scopes.rb:41:1:49:3 | M | @@ -199,6 +199,23 @@ variableAccess | scopes.rb:45:5:45:7 | self | scopes.rb:41:1:49:3 | self | scopes.rb:41:1:49:3 | M | | scopes.rb:46:5:46:8 | var2 | scopes.rb:46:5:46:8 | var2 | scopes.rb:41:1:49:3 | M | | scopes.rb:47:5:47:8 | var2 | scopes.rb:46:5:46:8 | var2 | scopes.rb:41:1:49:3 | M | +| scopes.rb:55:3:55:3 | x | scopes.rb:55:3:55:3 | x | scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:56:3:56:8 | self | scopes.rb:51:1:64:3 | self | scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:56:8:56:8 | x | scopes.rb:55:3:55:3 | x | scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:59:5:59:21 | self | scopes.rb:51:1:64:3 | self | scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:60:25:60:25 | x | scopes.rb:55:3:55:3 | x | scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:61:5:61:10 | self | scopes.rb:51:1:64:3 | self | scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:61:10:61:10 | x | scopes.rb:55:3:55:3 | x | scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:63:3:63:8 | self | scopes.rb:51:1:64:3 | self | scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:63:8:63:8 | x | scopes.rb:55:3:55:3 | x | scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:67:3:67:3 | x | scopes.rb:67:3:67:3 | x | scopes.rb:66:1:73:3 | ParameterShadowing | +| scopes.rb:68:3:68:4 | xs | scopes.rb:68:3:68:4 | xs | scopes.rb:66:1:73:3 | ParameterShadowing | +| scopes.rb:69:3:69:4 | xs | scopes.rb:68:3:68:4 | xs | scopes.rb:66:1:73:3 | ParameterShadowing | +| scopes.rb:69:15:69:15 | x | scopes.rb:69:15:69:15 | x | scopes.rb:69:11:71:5 | do ... end | +| scopes.rb:70:5:70:10 | self | scopes.rb:66:1:73:3 | self | scopes.rb:66:1:73:3 | ParameterShadowing | +| scopes.rb:70:10:70:10 | x | scopes.rb:69:15:69:15 | x | scopes.rb:69:11:71:5 | do ... end | +| scopes.rb:72:3:72:8 | self | scopes.rb:66:1:73:3 | self | scopes.rb:66:1:73:3 | ParameterShadowing | +| scopes.rb:72:8:72:8 | x | scopes.rb:67:3:67:3 | x | scopes.rb:66:1:73:3 | ParameterShadowing | | ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | ssa.rb:1:1:16:3 | m | | ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | ssa.rb:1:1:16:3 | m | | ssa.rb:3:3:3:8 | self | ssa.rb:1:1:16:3 | self | ssa.rb:1:1:16:3 | m | @@ -350,6 +367,9 @@ explicitWrite | scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:9 | ... = ... | | scopes.rb:43:2:43:4 | foo | scopes.rb:43:2:43:13 | ... = ... | | scopes.rb:46:5:46:8 | var2 | scopes.rb:46:5:46:13 | ... = ... | +| scopes.rb:55:3:55:3 | x | scopes.rb:55:3:55:7 | ... = ... | +| scopes.rb:67:3:67:3 | x | scopes.rb:67:3:67:7 | ... = ... | +| scopes.rb:68:3:68:4 | xs | scopes.rb:68:3:68:16 | ... = ... | | ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:7 | ... = ... | | ssa.rb:6:5:6:5 | i | ssa.rb:6:5:6:9 | ... = ... | | ssa.rb:10:5:10:5 | i | ssa.rb:10:5:10:9 | ... = ... | @@ -400,6 +420,8 @@ implicitWrite | parameters.rb:59:25:59:25 | c | | scopes.rb:2:14:2:14 | x | | scopes.rb:9:14:9:14 | x | +| scopes.rb:60:25:60:25 | x | +| scopes.rb:69:15:69:15 | x | | ssa.rb:1:7:1:7 | b | | ssa.rb:18:8:18:8 | x | | ssa.rb:25:8:25:15 | elements | @@ -550,6 +572,18 @@ readAccess | scopes.rb:44:5:44:7 | var | | scopes.rb:45:5:45:7 | self | | scopes.rb:47:5:47:8 | var2 | +| scopes.rb:56:3:56:8 | self | +| scopes.rb:56:8:56:8 | x | +| scopes.rb:59:5:59:21 | self | +| scopes.rb:61:5:61:10 | self | +| scopes.rb:61:10:61:10 | x | +| scopes.rb:63:3:63:8 | self | +| scopes.rb:63:8:63:8 | x | +| scopes.rb:69:3:69:4 | xs | +| scopes.rb:70:5:70:10 | self | +| scopes.rb:70:10:70:10 | x | +| scopes.rb:72:3:72:8 | self | +| scopes.rb:72:8:72:8 | x | | ssa.rb:3:3:3:8 | self | | ssa.rb:3:8:3:8 | i | | ssa.rb:4:3:4:12 | self | @@ -647,6 +681,7 @@ captureAccess | scopes.rb:15:4:15:9 | self | | scopes.rb:16:4:16:9 | self | | scopes.rb:17:4:17:9 | self | +| scopes.rb:70:5:70:10 | self | | ssa.rb:26:7:26:10 | elem | | ssa.rb:27:5:27:13 | self | | ssa.rb:27:10:27:13 | elem | diff --git a/ruby/ql/test/library-tests/variables/variable.expected b/ruby/ql/test/library-tests/variables/variable.expected index 55288f74088..b0e23fb2045 100644 --- a/ruby/ql/test/library-tests/variables/variable.expected +++ b/ruby/ql/test/library-tests/variables/variable.expected @@ -94,7 +94,7 @@ | parameters.rb:59:23:59:23 | b | | parameters.rb:59:25:59:25 | c | | scopes.rb:1:1:1:15 | self | -| scopes.rb:1:1:49:4 | self | +| scopes.rb:1:1:73:3 | self | | scopes.rb:2:14:2:14 | x | | scopes.rb:4:4:4:4 | a | | scopes.rb:7:1:7:1 | a | @@ -124,6 +124,13 @@ | scopes.rb:42:2:42:4 | var | | scopes.rb:43:2:43:4 | foo | | scopes.rb:46:5:46:8 | var2 | +| scopes.rb:51:1:64:3 | self | +| scopes.rb:52:3:53:5 | self | +| scopes.rb:55:3:55:3 | x | +| scopes.rb:66:1:73:3 | self | +| scopes.rb:67:3:67:3 | x | +| scopes.rb:68:3:68:4 | xs | +| scopes.rb:69:15:69:15 | x | | ssa.rb:1:1:16:3 | self | | ssa.rb:1:1:103:3 | self | | ssa.rb:1:7:1:7 | b | diff --git a/ruby/ql/test/library-tests/variables/varscopes.expected b/ruby/ql/test/library-tests/variables/varscopes.expected index 6b64ca6f97d..958be320a5d 100644 --- a/ruby/ql/test/library-tests/variables/varscopes.expected +++ b/ruby/ql/test/library-tests/variables/varscopes.expected @@ -47,7 +47,7 @@ | parameters.rb:54:9:57:3 | do ... end | | parameters.rb:59:1:61:3 | tuples_nested | | scopes.rb:1:1:1:15 | a | -| scopes.rb:1:1:49:4 | scopes.rb | +| scopes.rb:1:1:73:3 | scopes.rb | | scopes.rb:2:9:6:3 | do ... end | | scopes.rb:9:9:18:3 | do ... end | | scopes.rb:26:1:26:12 | A | @@ -56,6 +56,10 @@ | scopes.rb:34:1:36:3 | C | | scopes.rb:37:1:39:3 | foo | | scopes.rb:41:1:49:3 | M | +| scopes.rb:51:1:64:3 | ExceptionVariable | +| scopes.rb:52:3:53:5 | MyException | +| scopes.rb:66:1:73:3 | ParameterShadowing | +| scopes.rb:69:11:71:5 | do ... end | | ssa.rb:1:1:16:3 | m | | ssa.rb:1:1:103:3 | ssa.rb | | ssa.rb:18:1:23:3 | m1 | From a159dc1c66b1cb745ad5f1531a9ba05792b6e869 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 May 2026 10:00:26 +0100 Subject: [PATCH 134/226] Change variable name in test --- .../CWE-918/ApacheHttpClientExecuteSSRF.java | 6 +-- .../security/CWE-918/RequestForgery.expected | 50 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java b/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java index 05d38b2b5dd..0074e228e86 100644 --- a/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java +++ b/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java @@ -18,11 +18,11 @@ public class ApacheHttpClientExecuteSSRF extends HttpServlet { throws ServletException, IOException { try { - String sink = request.getParameter("host"); // $ Source + String source = request.getParameter("host"); // $ Source - HttpHost host = new HttpHost(sink); + HttpHost host = new HttpHost(source); HttpRequest req = new BasicHttpRequest("GET", "/"); - HttpUriRequest uriReq = (HttpUriRequest) (Object) sink; + HttpUriRequest uriReq = (HttpUriRequest) (Object) source; HttpContext context = null; HttpClient client = null; ResponseHandler handler = null; diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected index eed7d3ee527..fb0e61c90d8 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected @@ -1,12 +1,12 @@ #select -| ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:30:43:30:45 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:30:43:30:45 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:32:29:32:31 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:32:29:32:31 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:34:26:34:28 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:34:26:34:28 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | @@ -385,18 +385,18 @@ | mad/Test.java:107:15:107:31 | (...)... | mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:107:15:107:31 | (...)... | Potential server-side request forgery due to a $@. | mad/Test.java:26:16:26:41 | getParameter(...) | user-provided value | | mad/Test.java:112:15:112:31 | (...)... | mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:112:15:112:31 | (...)... | Potential server-side request forgery due to a $@. | mad/Test.java:26:16:26:41 | getParameter(...) | user-provided value | edges -| ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:23:42:23:45 | sink : String | provenance | Src:MaD:285 | -| ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:25:54:25:66 | (...)... : String | provenance | Src:MaD:285 | -| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | provenance | Sink:MaD:228 | -| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | provenance | Sink:MaD:229 | -| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | provenance | Sink:MaD:230 | -| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | provenance | Sink:MaD:231 | -| ApacheHttpClientExecuteSSRF.java:23:42:23:45 | sink : String | ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | provenance | MaD:305 | -| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | provenance | Sink:MaD:232 | -| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | provenance | Sink:MaD:233 | -| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | provenance | Sink:MaD:234 | -| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | provenance | Sink:MaD:235 | -| ApacheHttpClientExecuteSSRF.java:25:54:25:66 | (...)... : String | ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | provenance | | +| ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:23:42:23:47 | source : String | provenance | Src:MaD:285 | +| ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:25:54:25:68 | (...)... : String | provenance | Src:MaD:285 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | provenance | Sink:MaD:228 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | provenance | Sink:MaD:229 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | provenance | Sink:MaD:230 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | provenance | Sink:MaD:231 | +| ApacheHttpClientExecuteSSRF.java:23:42:23:47 | source : String | ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | provenance | MaD:305 | +| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | provenance | Sink:MaD:232 | +| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | provenance | Sink:MaD:233 | +| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | provenance | Sink:MaD:234 | +| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | provenance | Sink:MaD:235 | +| ApacheHttpClientExecuteSSRF.java:25:54:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | provenance | | | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:28:31:28:34 | sink : String | provenance | Src:MaD:285 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:30:43:30:45 | uri | provenance | Sink:MaD:211 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:32:29:32:31 | uri | provenance | Sink:MaD:217 | @@ -1405,11 +1405,11 @@ models | 304 | Summary: org.apache.http.message; BasicRequestLine; false; BasicRequestLine; ; ; Argument[1]; Argument[this]; taint; manual | | 305 | Summary: org.apache.http; HttpHost; true; HttpHost; (String); ; Argument[0]; Argument[this]; taint; hq-manual | nodes -| ApacheHttpClientExecuteSSRF.java:21:27:21:54 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| ApacheHttpClientExecuteSSRF.java:23:29:23:46 | new HttpHost(...) : HttpHost | semmle.label | new HttpHost(...) : HttpHost | -| ApacheHttpClientExecuteSSRF.java:23:42:23:45 | sink : String | semmle.label | sink : String | -| ApacheHttpClientExecuteSSRF.java:25:37:25:66 | (...)... : String | semmle.label | (...)... : String | -| ApacheHttpClientExecuteSSRF.java:25:54:25:66 | (...)... : String | semmle.label | (...)... : String | +| ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | semmle.label | new HttpHost(...) : HttpHost | +| ApacheHttpClientExecuteSSRF.java:23:42:23:47 | source : String | semmle.label | source : String | +| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | semmle.label | (...)... : String | +| ApacheHttpClientExecuteSSRF.java:25:54:25:68 | (...)... : String | semmle.label | (...)... : String | | ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | semmle.label | host | | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | semmle.label | host | | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | semmle.label | host | From 37589dd8a0e1a70c99095d5a231a695b705a4626 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 May 2026 10:30:43 +0100 Subject: [PATCH 135/226] Improve how `org.apache.http.client.HttpClient` is created in test --- .../CWE-918/ApacheHttpClientExecuteSSRF.java | 3 +- .../security/CWE-918/RequestForgery.expected | 54 +++++++++---------- .../http/impl/client/CloseableHttpClient.java | 7 +++ .../apache/http/impl/client/HttpClients.java | 10 ++++ 4 files changed, 46 insertions(+), 28 deletions(-) create mode 100644 java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/impl/client/CloseableHttpClient.java create mode 100644 java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/impl/client/HttpClients.java diff --git a/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java b/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java index 0074e228e86..505783e23eb 100644 --- a/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java +++ b/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java @@ -5,6 +5,7 @@ import org.apache.http.HttpRequest; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.HttpContext; import javax.servlet.ServletException; @@ -24,7 +25,7 @@ public class ApacheHttpClientExecuteSSRF extends HttpServlet { HttpRequest req = new BasicHttpRequest("GET", "/"); HttpUriRequest uriReq = (HttpUriRequest) (Object) source; HttpContext context = null; - HttpClient client = null; + HttpClient client = HttpClients.createDefault(); ResponseHandler handler = null; client.execute(host, req); // $ Alert diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected index fb0e61c90d8..45345b175b9 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected @@ -1,12 +1,12 @@ #select -| ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:30:43:30:45 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:30:43:30:45 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:32:29:32:31 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:32:29:32:31 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:34:26:34:28 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:34:26:34:28 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | @@ -385,18 +385,18 @@ | mad/Test.java:107:15:107:31 | (...)... | mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:107:15:107:31 | (...)... | Potential server-side request forgery due to a $@. | mad/Test.java:26:16:26:41 | getParameter(...) | user-provided value | | mad/Test.java:112:15:112:31 | (...)... | mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:112:15:112:31 | (...)... | Potential server-side request forgery due to a $@. | mad/Test.java:26:16:26:41 | getParameter(...) | user-provided value | edges -| ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:23:42:23:47 | source : String | provenance | Src:MaD:285 | -| ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:25:54:25:68 | (...)... : String | provenance | Src:MaD:285 | -| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | provenance | Sink:MaD:228 | -| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | provenance | Sink:MaD:229 | -| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | provenance | Sink:MaD:230 | -| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | provenance | Sink:MaD:231 | -| ApacheHttpClientExecuteSSRF.java:23:42:23:47 | source : String | ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | provenance | MaD:305 | -| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | provenance | Sink:MaD:232 | -| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | provenance | Sink:MaD:233 | -| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | provenance | Sink:MaD:234 | -| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | provenance | Sink:MaD:235 | -| ApacheHttpClientExecuteSSRF.java:25:54:25:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | provenance | | +| ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:24:42:24:47 | source : String | provenance | Src:MaD:285 | +| ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:26:54:26:68 | (...)... : String | provenance | Src:MaD:285 | +| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | provenance | Sink:MaD:228 | +| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | provenance | Sink:MaD:229 | +| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | provenance | Sink:MaD:230 | +| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | provenance | Sink:MaD:231 | +| ApacheHttpClientExecuteSSRF.java:24:42:24:47 | source : String | ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | provenance | MaD:305 | +| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | provenance | Sink:MaD:232 | +| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | provenance | Sink:MaD:233 | +| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | provenance | Sink:MaD:234 | +| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | provenance | Sink:MaD:235 | +| ApacheHttpClientExecuteSSRF.java:26:54:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | provenance | | | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:28:31:28:34 | sink : String | provenance | Src:MaD:285 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:30:43:30:45 | uri | provenance | Sink:MaD:211 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:32:29:32:31 | uri | provenance | Sink:MaD:217 | @@ -1405,19 +1405,19 @@ models | 304 | Summary: org.apache.http.message; BasicRequestLine; false; BasicRequestLine; ; ; Argument[1]; Argument[this]; taint; manual | | 305 | Summary: org.apache.http; HttpHost; true; HttpHost; (String); ; Argument[0]; Argument[this]; taint; hq-manual | nodes -| ApacheHttpClientExecuteSSRF.java:21:29:21:56 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| ApacheHttpClientExecuteSSRF.java:23:29:23:48 | new HttpHost(...) : HttpHost | semmle.label | new HttpHost(...) : HttpHost | -| ApacheHttpClientExecuteSSRF.java:23:42:23:47 | source : String | semmle.label | source : String | -| ApacheHttpClientExecuteSSRF.java:25:37:25:68 | (...)... : String | semmle.label | (...)... : String | -| ApacheHttpClientExecuteSSRF.java:25:54:25:68 | (...)... : String | semmle.label | (...)... : String | -| ApacheHttpClientExecuteSSRF.java:30:28:30:31 | host | semmle.label | host | +| ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | semmle.label | new HttpHost(...) : HttpHost | +| ApacheHttpClientExecuteSSRF.java:24:42:24:47 | source : String | semmle.label | source : String | +| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | semmle.label | (...)... : String | +| ApacheHttpClientExecuteSSRF.java:26:54:26:68 | (...)... : String | semmle.label | (...)... : String | | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | semmle.label | host | | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | semmle.label | host | | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | semmle.label | host | -| ApacheHttpClientExecuteSSRF.java:34:28:34:33 | uriReq | semmle.label | uriReq | +| ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | semmle.label | host | | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | semmle.label | uriReq | | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | semmle.label | uriReq | | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | semmle.label | uriReq | +| ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | semmle.label | uriReq | | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | semmle.label | new URI(...) : URI | | ApacheHttpSSRF.java:28:31:28:34 | sink : String | semmle.label | sink : String | diff --git a/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/impl/client/CloseableHttpClient.java b/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/impl/client/CloseableHttpClient.java new file mode 100644 index 00000000000..dff62322e5a --- /dev/null +++ b/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/impl/client/CloseableHttpClient.java @@ -0,0 +1,7 @@ +package org.apache.http.impl.client; + +import org.apache.http.client.HttpClient; + +public abstract class CloseableHttpClient implements HttpClient { + +} diff --git a/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/impl/client/HttpClients.java b/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/impl/client/HttpClients.java new file mode 100644 index 00000000000..e5d1a2537c5 --- /dev/null +++ b/java/ql/test/stubs/apache-http-client-4.4.13/org/apache/http/impl/client/HttpClients.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.http.client.HttpClient for testing purposes + +package org.apache.http.impl.client; + +import java.io.IOException; +import org.apache.http.impl.client.CloseableHttpClient; + +public final class HttpClients { + public static CloseableHttpClient createDefault() { return null; } +} From 8937e22735ec209046dae7003d71db6cccbb2fa2 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 May 2026 10:56:37 +0100 Subject: [PATCH 136/226] Add summary models for `org.apache.http.client.methods.RequestBuilder` Generated by GPT 5.3-codex, verified by me. --- .../org.apache.http.client.methods.model.yml | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/ext/org.apache.http.client.methods.model.yml b/java/ql/lib/ext/org.apache.http.client.methods.model.yml index 4eccb08eb8c..4560e402f43 100644 --- a/java/ql/lib/ext/org.apache.http.client.methods.model.yml +++ b/java/ql/lib/ext/org.apache.http.client.methods.model.yml @@ -11,7 +11,7 @@ extensions: - ["org.apache.http.client.methods", "HttpPost", False, "HttpPost", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.apache.http.client.methods", "HttpPut", False, "HttpPut", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.apache.http.client.methods", "HttpRequestBase", True, "setURI", "", "", "Argument[0]", "request-forgery", "manual"] - - ["org.apache.http.client.methods", "HttpRequestWrapper", True, "setURI", "(URI)", "", "Argument[0]", "request-forgery", "hq-manual"] + - ["org.apache.http.client.methods", "HttpRequestWrapper", True, "setURI", "(URI)", "", "Argument[0]", "request-forgery", "ai-manual"] - ["org.apache.http.client.methods", "HttpTrace", False, "HttpTrace", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.apache.http.client.methods", "RequestBuilder", False, "delete", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.apache.http.client.methods", "RequestBuilder", False, "get", "", "", "Argument[0]", "request-forgery", "manual"] @@ -22,3 +22,29 @@ extensions: - ["org.apache.http.client.methods", "RequestBuilder", False, "put", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.apache.http.client.methods", "RequestBuilder", False, "setUri", "", "", "Argument[0]", "request-forgery", "manual"] - ["org.apache.http.client.methods", "RequestBuilder", False, "trace", "", "", "Argument[0]", "request-forgery", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["org.apache.http.client.methods", "RequestBuilder", True, "build", "()", "", "Argument[this]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "delete", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "delete", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "get", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "get", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "getUri", "()", "", "Argument[this]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "head", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "head", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "options", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "options", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "patch", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "patch", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "post", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "post", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "put", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "put", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "setUri", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "setUri", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "setUri", "(URI)", "", "Argument[0]", "Argument[this]", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "setUri", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "trace", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] + - ["org.apache.http.client.methods", "RequestBuilder", True, "trace", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] From d95d99848c5260b941692216aed213042b8bfd95 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 May 2026 11:05:40 +0100 Subject: [PATCH 137/226] Build `RequestBuilder` more realistically --- .../CWE-918/ApacheHttpClientExecuteSSRF.java | 3 +- .../security/CWE-918/RequestForgery.expected | 69 ++++++++++--------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java b/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java index 505783e23eb..e9206335e5d 100644 --- a/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java +++ b/java/ql/test/query-tests/security/CWE-918/ApacheHttpClientExecuteSSRF.java @@ -5,6 +5,7 @@ import org.apache.http.HttpRequest; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.methods.RequestBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.HttpContext; @@ -23,7 +24,7 @@ public class ApacheHttpClientExecuteSSRF extends HttpServlet { HttpHost host = new HttpHost(source); HttpRequest req = new BasicHttpRequest("GET", "/"); - HttpUriRequest uriReq = (HttpUriRequest) (Object) source; + HttpUriRequest uriReq = RequestBuilder.get(source).build(); // $ Alert HttpContext context = null; HttpClient client = HttpClients.createDefault(); ResponseHandler handler = null; diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected index 45345b175b9..1a36fba94c7 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected @@ -1,12 +1,13 @@ #select -| ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | -| ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:27:56:27:61 | source | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:27:56:27:61 | source | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:35:28:35:31 | host | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:35:28:35:31 | host | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) | user-provided value | +| ApacheHttpClientExecuteSSRF.java:39:28:39:33 | uriReq | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:39:28:39:33 | uriReq | Potential server-side request forgery due to a $@. | ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:30:43:30:45 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:30:43:30:45 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:32:29:32:31 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:32:29:32:31 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | | ApacheHttpSSRF.java:34:26:34:28 | uri | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:34:26:34:28 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) | user-provided value | @@ -385,18 +386,20 @@ | mad/Test.java:107:15:107:31 | (...)... | mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:107:15:107:31 | (...)... | Potential server-side request forgery due to a $@. | mad/Test.java:26:16:26:41 | getParameter(...) | user-provided value | | mad/Test.java:112:15:112:31 | (...)... | mad/Test.java:26:16:26:41 | getParameter(...) : String | mad/Test.java:112:15:112:31 | (...)... | Potential server-side request forgery due to a $@. | mad/Test.java:26:16:26:41 | getParameter(...) | user-provided value | edges -| ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:24:42:24:47 | source : String | provenance | Src:MaD:285 | -| ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:26:54:26:68 | (...)... : String | provenance | Src:MaD:285 | -| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | provenance | Sink:MaD:228 | -| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | provenance | Sink:MaD:229 | -| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | provenance | Sink:MaD:230 | -| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | provenance | Sink:MaD:231 | -| ApacheHttpClientExecuteSSRF.java:24:42:24:47 | source : String | ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | provenance | MaD:305 | -| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | provenance | Sink:MaD:232 | -| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | provenance | Sink:MaD:233 | -| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | provenance | Sink:MaD:234 | -| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | provenance | Sink:MaD:235 | -| ApacheHttpClientExecuteSSRF.java:26:54:26:68 | (...)... : String | ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | provenance | | +| ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:25:42:25:47 | source : String | provenance | Src:MaD:285 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:27:56:27:61 | source | provenance | Src:MaD:285 Sink:MaD:220 | +| ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | ApacheHttpClientExecuteSSRF.java:27:56:27:61 | source : String | provenance | Src:MaD:285 | +| ApacheHttpClientExecuteSSRF.java:25:29:25:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | provenance | Sink:MaD:228 | +| ApacheHttpClientExecuteSSRF.java:25:29:25:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | provenance | Sink:MaD:229 | +| ApacheHttpClientExecuteSSRF.java:25:29:25:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | provenance | Sink:MaD:230 | +| ApacheHttpClientExecuteSSRF.java:25:29:25:48 | new HttpHost(...) : HttpHost | ApacheHttpClientExecuteSSRF.java:35:28:35:31 | host | provenance | Sink:MaD:231 | +| ApacheHttpClientExecuteSSRF.java:25:42:25:47 | source : String | ApacheHttpClientExecuteSSRF.java:25:29:25:48 | new HttpHost(...) : HttpHost | provenance | MaD:307 | +| ApacheHttpClientExecuteSSRF.java:27:37:27:62 | get(...) : RequestBuilder | ApacheHttpClientExecuteSSRF.java:27:37:27:70 | build(...) : HttpUriRequest | provenance | MaD:304 | +| ApacheHttpClientExecuteSSRF.java:27:37:27:70 | build(...) : HttpUriRequest | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | provenance | Sink:MaD:232 | +| ApacheHttpClientExecuteSSRF.java:27:37:27:70 | build(...) : HttpUriRequest | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | provenance | Sink:MaD:233 | +| ApacheHttpClientExecuteSSRF.java:27:37:27:70 | build(...) : HttpUriRequest | ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | provenance | Sink:MaD:234 | +| ApacheHttpClientExecuteSSRF.java:27:37:27:70 | build(...) : HttpUriRequest | ApacheHttpClientExecuteSSRF.java:39:28:39:33 | uriReq | provenance | Sink:MaD:235 | +| ApacheHttpClientExecuteSSRF.java:27:56:27:61 | source : String | ApacheHttpClientExecuteSSRF.java:27:37:27:62 | get(...) : RequestBuilder | provenance | MaD:305 | | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | ApacheHttpSSRF.java:28:31:28:34 | sink : String | provenance | Src:MaD:285 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:30:43:30:45 | uri | provenance | Sink:MaD:211 | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | ApacheHttpSSRF.java:32:29:32:31 | uri | provenance | Sink:MaD:217 | @@ -425,11 +428,11 @@ edges | ApacheHttpSSRF.java:28:31:28:34 | sink : String | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | provenance | Config | | ApacheHttpSSRF.java:28:31:28:34 | sink : String | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | provenance | MaD:293 | | ApacheHttpSSRF.java:42:62:42:64 | uri : URI | ApacheHttpSSRF.java:42:62:42:75 | toString(...) : String | provenance | MaD:295 | -| ApacheHttpSSRF.java:42:62:42:75 | toString(...) : String | ApacheHttpSSRF.java:42:34:42:82 | new BasicRequestLine(...) | provenance | MaD:304 Sink:MaD:239 | +| ApacheHttpSSRF.java:42:62:42:75 | toString(...) : String | ApacheHttpSSRF.java:42:34:42:82 | new BasicRequestLine(...) | provenance | MaD:306 Sink:MaD:239 | | ApacheHttpSSRF.java:43:41:43:43 | uri : URI | ApacheHttpSSRF.java:43:41:43:54 | toString(...) | provenance | MaD:295 Sink:MaD:240 | | ApacheHttpSSRF.java:44:41:44:43 | uri : URI | ApacheHttpSSRF.java:44:41:44:54 | toString(...) | provenance | MaD:295 Sink:MaD:241 | | ApacheHttpSSRF.java:46:77:46:79 | uri : URI | ApacheHttpSSRF.java:46:77:46:90 | toString(...) : String | provenance | MaD:295 | -| ApacheHttpSSRF.java:46:77:46:90 | toString(...) : String | ApacheHttpSSRF.java:46:49:46:97 | new BasicRequestLine(...) | provenance | MaD:304 Sink:MaD:236 | +| ApacheHttpSSRF.java:46:77:46:90 | toString(...) : String | ApacheHttpSSRF.java:46:49:46:97 | new BasicRequestLine(...) | provenance | MaD:306 Sink:MaD:236 | | ApacheHttpSSRF.java:47:56:47:58 | uri : URI | ApacheHttpSSRF.java:47:56:47:69 | toString(...) | provenance | MaD:295 Sink:MaD:237 | | ApacheHttpSSRF.java:48:56:48:58 | uri : URI | ApacheHttpSSRF.java:48:56:48:69 | toString(...) | provenance | MaD:295 Sink:MaD:238 | | ApacheHttpSSRFVersion5.java:41:30:41:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:42:31:42:37 | uriSink : String | provenance | Src:MaD:285 | @@ -1402,22 +1405,26 @@ models | 301 | Summary: java.util; Map; false; of; ; ; Argument[3]; ReturnValue.MapValue; value; manual | | 302 | Summary: java.util; Properties; true; setProperty; (String,String); ; Argument[1]; Argument[this].MapValue; value; manual | | 303 | Summary: org.apache.hc.core5.http; HttpHost; true; HttpHost; (String); ; Argument[0]; Argument[this]; taint; hq-manual | -| 304 | Summary: org.apache.http.message; BasicRequestLine; false; BasicRequestLine; ; ; Argument[1]; Argument[this]; taint; manual | -| 305 | Summary: org.apache.http; HttpHost; true; HttpHost; (String); ; Argument[0]; Argument[this]; taint; hq-manual | +| 304 | Summary: org.apache.http.client.methods; RequestBuilder; true; build; (); ; Argument[this]; ReturnValue; taint; ai-manual | +| 305 | Summary: org.apache.http.client.methods; RequestBuilder; true; get; (String); ; Argument[0]; ReturnValue; taint; ai-manual | +| 306 | Summary: org.apache.http.message; BasicRequestLine; false; BasicRequestLine; ; ; Argument[1]; Argument[this]; taint; manual | +| 307 | Summary: org.apache.http; HttpHost; true; HttpHost; (String); ; Argument[0]; Argument[this]; taint; hq-manual | nodes -| ApacheHttpClientExecuteSSRF.java:22:29:22:56 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| ApacheHttpClientExecuteSSRF.java:24:29:24:48 | new HttpHost(...) : HttpHost | semmle.label | new HttpHost(...) : HttpHost | -| ApacheHttpClientExecuteSSRF.java:24:42:24:47 | source : String | semmle.label | source : String | -| ApacheHttpClientExecuteSSRF.java:26:37:26:68 | (...)... : String | semmle.label | (...)... : String | -| ApacheHttpClientExecuteSSRF.java:26:54:26:68 | (...)... : String | semmle.label | (...)... : String | -| ApacheHttpClientExecuteSSRF.java:31:28:31:31 | host | semmle.label | host | +| ApacheHttpClientExecuteSSRF.java:23:29:23:56 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| ApacheHttpClientExecuteSSRF.java:25:29:25:48 | new HttpHost(...) : HttpHost | semmle.label | new HttpHost(...) : HttpHost | +| ApacheHttpClientExecuteSSRF.java:25:42:25:47 | source : String | semmle.label | source : String | +| ApacheHttpClientExecuteSSRF.java:27:37:27:62 | get(...) : RequestBuilder | semmle.label | get(...) : RequestBuilder | +| ApacheHttpClientExecuteSSRF.java:27:37:27:70 | build(...) : HttpUriRequest | semmle.label | build(...) : HttpUriRequest | +| ApacheHttpClientExecuteSSRF.java:27:56:27:61 | source | semmle.label | source | +| ApacheHttpClientExecuteSSRF.java:27:56:27:61 | source : String | semmle.label | source : String | | ApacheHttpClientExecuteSSRF.java:32:28:32:31 | host | semmle.label | host | | ApacheHttpClientExecuteSSRF.java:33:28:33:31 | host | semmle.label | host | | ApacheHttpClientExecuteSSRF.java:34:28:34:31 | host | semmle.label | host | -| ApacheHttpClientExecuteSSRF.java:35:28:35:33 | uriReq | semmle.label | uriReq | +| ApacheHttpClientExecuteSSRF.java:35:28:35:31 | host | semmle.label | host | | ApacheHttpClientExecuteSSRF.java:36:28:36:33 | uriReq | semmle.label | uriReq | | ApacheHttpClientExecuteSSRF.java:37:28:37:33 | uriReq | semmle.label | uriReq | | ApacheHttpClientExecuteSSRF.java:38:28:38:33 | uriReq | semmle.label | uriReq | +| ApacheHttpClientExecuteSSRF.java:39:28:39:33 | uriReq | semmle.label | uriReq | | ApacheHttpSSRF.java:27:27:27:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | | ApacheHttpSSRF.java:28:23:28:35 | new URI(...) : URI | semmle.label | new URI(...) : URI | | ApacheHttpSSRF.java:28:31:28:34 | sink : String | semmle.label | sink : String | From 80c6f082d114ce5772dd38330b528868e3914363 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 May 2026 11:34:02 +0100 Subject: [PATCH 138/226] Fix TODO in `containerStep` --- .../new/internal/TaintTrackingPrivate.qll | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 2d2cceb73c1..de5a06eaaad 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -11,21 +11,35 @@ private import semmle.python.ApiGraphs */ predicate defaultTaintSanitizer(DataFlow::Node node) { none() } +/** + * Holds if default taint tracking should read content `contentSet` implicitly and + * propagate taint from a container to reads of that content. + */ +private predicate defaultTaintReadContent(DataFlow::ContentSet contentSet) { + // Tuple and dictionary content is precise, so use wildcard content sets to avoid + // blowing up the size of `Stage1::readSetEx` (otherwise this predicate would + // expand to one row per (node, distinct key or index) and the framework's + // read-set relation grows quadratically). `ContentSet.getAReadContent` expands + // these wildcards back to the specific contents when matching against stores. + contentSet.isAnyTupleElement() + or + contentSet.isAnyDictionaryElement() + or + // List and set element content is already imprecise, so no wildcard expansion is + // needed. + contentSet.getAStoreContent() instanceof DataFlow::ListElementContent + or + contentSet.getAStoreContent() instanceof DataFlow::SetElementContent +} + /** * Holds if default `TaintTracking::Configuration`s should allow implicit reads * of `c` at sinks and inputs to additional taint steps. */ bindingset[node] predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { - // We allow implicit reads of precise content; imprecise content has already - // bubbled up. We use the wildcard content sets here rather than the - // per-key/per-index ones to avoid blowing up the size of `Stage1::readSetEx` - // (otherwise this predicate would expand to one row per (node, distinct key - // or index) and the framework's read-set relation grows quadratically). - // `ContentSet.getAReadContent` expands these wildcards back to the specific - // contents when matching against stores. exists(node) and - (c.isAnyTupleElement() or c.isAnyDictionaryElement()) + defaultTaintReadContent(c) } private module Cached { @@ -171,28 +185,15 @@ predicate stringManipulation(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeT } /** - * Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to containers - * (lists/sets/dictionaries): literals, constructor invocation, methods. Note that this - * is currently very imprecise, as an example, since we model `dict.get`, we treat any - * `.get()` will be tainted, whether it's true or not. + * Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to reading + * content from containers (lists/sets/dictionaries/tuples): subscripts, iteration, + * constructor invocation, methods. */ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - // construction by literal - // - // TODO: once we have proper flow-summary modeling, we might not need this step any - // longer -- but there needs to be a matching read-step for the store-step, and we - // don't provide that right now. - DataFlowPrivate::listStoreStep(nodeFrom, _, nodeTo) - or - DataFlowPrivate::setStoreStep(nodeFrom, _, nodeTo) - or - // comprehension, so there is taint-flow from `x` in `[x for x in xs]` to the - // resulting list of the list-comprehension. - // - // TODO: once we have proper flow-summary modeling, we might not need this step any - // longer -- but there needs to be a matching read-step for the store-step, and we - // don't provide that right now. - DataFlowPrivate::yieldStoreStep(nodeFrom, _, nodeTo) + exists(DataFlow::ContentSet contentSet | + DataFlowPrivate::readStep(nodeFrom, contentSet, nodeTo) and + defaultTaintReadContent(contentSet) + ) } /** From 812e8e6b34e09795f3013a89c2a77922b72819d7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 May 2026 11:37:54 +0100 Subject: [PATCH 139/226] Add change note --- .../2026-05-28-remove-imprecise-containter-steps.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/lib/change-notes/2026-05-28-remove-imprecise-containter-steps.md diff --git a/python/ql/lib/change-notes/2026-05-28-remove-imprecise-containter-steps.md b/python/ql/lib/change-notes/2026-05-28-remove-imprecise-containter-steps.md new file mode 100644 index 00000000000..25c664d6c05 --- /dev/null +++ b/python/ql/lib/change-notes/2026-05-28-remove-imprecise-containter-steps.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Python taint tracking is now more precise for values flowing through container contents, such as list, set, tuple, and dictionary elements. This may remove some false positive alerts. From f8ab76e1baff6b8b300bf96c6717c5674f0aba60 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 28 May 2026 12:14:10 +0100 Subject: [PATCH 140/226] Swift: Update the new metatype sinks to not rely on name matching '.Type'. --- .../WeakPasswordHashingExtensions.qll | 21 ++++++++++++++----- .../WeakSensitiveDataHashingExtensions.qll | 21 ++++++++++++++----- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll index 9442812ba2c..1700c5dc60e 100644 --- a/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakPasswordHashingExtensions.qll @@ -121,12 +121,23 @@ private class WeakPasswordHashingMetatypeSink extends WeakPasswordHashingSink { string algorithm; WeakPasswordHashingMetatypeSink() { - exists(CallExpr c | - c.getAnArgument().getExpr() = this.asExpr() and + exists(CallExpr ce, Type t | + // call target + ce.getStaticTarget().getName() = + ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] and + // argument + ce.getAnArgument().getExpr() = this.asExpr() and + // qualifier + t = ce.getQualifier().getType() and algorithm = ["SHA256", "SHA384", "SHA512"] and - c.getQualifier().getType().getFullName() = algorithm + ["", ".Type"] and - c.getStaticTarget().getName() = - ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] + ( + t.getFullName() = algorithm + or + exists(TypeDecl td | + td.getInterfaceType() = t and + td.getFullName() = algorithm + ) + ) ) } diff --git a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll index 58d9f466b78..02cb82a22c8 100755 --- a/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/WeakSensitiveDataHashingExtensions.qll @@ -86,12 +86,23 @@ private class WeakSensitiveDataHashingMetatypeSink extends WeakSensitiveDataHash string algorithm; WeakSensitiveDataHashingMetatypeSink() { - exists(CallExpr c | - c.getAnArgument().getExpr() = this.asExpr() and + exists(CallExpr ce, Type t | + // call target + ce.getStaticTarget().getName() = + ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] and + // argument + ce.getAnArgument().getExpr() = this.asExpr() and + // qualifier + t = ce.getQualifier().getType() and algorithm = ["MD5", "SHA1"] and - c.getQualifier().getType().getFullName() = "Insecure." + algorithm + ["", ".Type"] and - c.getStaticTarget().getName() = - ["hash(data:)", "hash(bufferPointer:)", "update(data:)", "update(bufferPointer:)"] + ( + t.getFullName() = "Insecure." + algorithm + or + exists(TypeDecl td | + td.getInterfaceType() = t and + td.getFullName() = "Insecure." + algorithm + ) + ) ) } From 8393b40b59083b4feff88d086105b6954020aa03 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 May 2026 17:13:48 +0200 Subject: [PATCH 141/226] C++: Use the new extensionals to map template functions and classes to their fully templated versions. --- .../semmle/code/cpp/dataflow/ExternalFlow.qll | 70 ++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index 5bab7dd00f2..4ec2f2f3997 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -277,11 +277,44 @@ private predicate isClassConstructedFrom(Class c, Class templateClass) { } /** Gets the fully templated version of `f`. */ -private Class getFullyTemplatedClass(Class c) { +private Class getFullyTemplatedClassOld(Class c) { not c.isFromUninstantiatedTemplate(_) and isClassConstructedFrom(c, result) } +private TemplateClass getOriginalClassTemplate(TemplateClass tc) { + result = tc.getOriginalTemplate() + or + not exists(tc.getOriginalTemplate()) and + result = tc +} + +/** Gets the fully templated version of `f`. */ +private Class getFullyTemplatedClassNew(Class c) { + not c.isFromUninstantiatedTemplate(_) and + exists(Class mid | + c.isConstructedFrom(mid) + or + not c.isConstructedFrom(_) and c = mid + | + result = getOriginalClassTemplate(mid) + or + not mid instanceof TemplateClass and mid = result + ) +} + +/** Gets the fully templated version of `c`. */ +private Class getFullyTemplatedClass(Class c) { + // The `Class::getOriginalTemplate` predicate was introduced in CodeQL + // version 2.25.6 and the upgrade script leaves the + // `class_template_generated_from` extensionals empty if the database + // was generated with an older extractor. So we use the old implementation + // if the `class_template_generated_from` extensional is empty. + if class_template_generated_from(_, _) + then result = getFullyTemplatedClassNew(c) + else result = getFullyTemplatedClassOld(c) +} + /** * Holds if `f` is an instantiation of a function template `templateFunc`, or * holds with `f = templateFunc` if `f` is not an instantiation of any function @@ -298,7 +331,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) { } /** Gets the fully templated version of `f`. */ -Function getFullyTemplatedFunction(Function f) { +private Function getFullyTemplatedFunctionOld(Function f) { not f.isFromUninstantiatedTemplate(_) and ( exists(Class c, Class templateClass, int i | @@ -312,6 +345,39 @@ Function getFullyTemplatedFunction(Function f) { ) } +private TemplateFunction getOriginalFunctionTemplate(TemplateFunction tf) { + result = tf.getOriginalTemplate() + or + not exists(tf.getOriginalTemplate()) and + result = tf +} + +/** Gets the fully templated version of `f`. */ +private Function getFullyTemplatedFunctionNew(Function f) { + not f.isFromUninstantiatedTemplate(_) and + exists(Function mid | + f.isConstructedFrom(mid) + or + not f.isConstructedFrom(_) and f = mid + | + result = getOriginalFunctionTemplate(mid) + or + not mid instanceof TemplateFunction and mid = result + ) +} + +/** Gets the fully templated version of `f`. */ +Function getFullyTemplatedFunction(Function f) { + // The `Function::getOriginalTemplate` predicate was introduced in CodeQL + // version 2.25.6 and the upgrade script leaves the + // `function_template_generated_from` extensionals empty if the database + // was generated with an older extractor. So we use the old implementation + // if the `function_template_generated_from` extensional is empty. + if function_template_generated_from(_, _) + then result = getFullyTemplatedFunctionNew(f) + else result = getFullyTemplatedFunctionOld(f) +} + /** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */ bindingset[s, t] private string withConst(string s, Type t) { From 9f211cebd5f415ec3f67f8c329826c189ba53dde Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 27 May 2026 17:13:55 +0200 Subject: [PATCH 142/226] C++: Accept test changes. --- .../taint-tests/test_mad-signatures.expected | 79 ++++++++++--------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected index 5ad32759da5..d494c09e71d 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.expected @@ -27383,54 +27383,55 @@ getParameterTypeName | stl.h:91:24:91:33 | operator++ | 0 | int | | stl.h:95:44:95:44 | back_inserter | 0 | func:0 & | | stl.h:95:44:95:44 | back_inserter | 0 | func:0 & | -| stl.h:148:3:148:14 | basic_string | 0 | const class:2 & | -| stl.h:149:33:149:44 | basic_string | 0 | const class:0 * | -| stl.h:149:33:149:44 | basic_string | 1 | const class:2 & | -| stl.h:151:16:151:20 | c_str | 0 | func:0 | -| stl.h:151:16:151:20 | c_str | 1 | func:0 | -| stl.h:151:16:151:20 | c_str | 2 | const class:2 & | +| stl.h:147:12:147:23 | basic_string | 0 | const class:2 & | +| stl.h:148:3:148:14 | basic_string | 0 | const class:0 * | +| stl.h:148:3:148:14 | basic_string | 1 | const class:2 & | +| stl.h:149:33:149:44 | basic_string | 0 | func:0 | +| stl.h:149:33:149:44 | basic_string | 1 | func:0 | +| stl.h:149:33:149:44 | basic_string | 2 | const class:2 & | +| stl.h:165:8:165:16 | push_back | 0 | class:0 | | stl.h:173:13:173:22 | operator[] | 0 | size_type | | stl.h:175:13:175:14 | at | 0 | size_type | -| stl.h:176:35:176:44 | operator+= | 0 | size_type | -| stl.h:176:35:176:44 | operator+= | 0 | size_type | -| stl.h:177:17:177:26 | operator+= | 0 | const func:0 & | -| stl.h:178:17:178:22 | append | 0 | const class:0 * | -| stl.h:179:17:179:22 | append | 0 | const basic_string & | -| stl.h:180:17:180:22 | append | 0 | const class:0 * | -| stl.h:181:47:181:52 | append | 0 | size_type | -| stl.h:181:47:181:52 | append | 1 | class:0 | -| stl.h:182:17:182:22 | assign | 0 | func:0 | -| stl.h:182:17:182:22 | assign | 1 | func:0 | -| stl.h:183:17:183:22 | assign | 0 | const basic_string & | -| stl.h:184:47:184:52 | assign | 0 | size_type | -| stl.h:184:47:184:52 | assign | 1 | class:0 | -| stl.h:185:17:185:22 | insert | 0 | func:0 | -| stl.h:185:17:185:22 | insert | 1 | func:0 | +| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & | +| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & | +| stl.h:177:17:177:26 | operator+= | 0 | const class:0 * | +| stl.h:178:17:178:22 | append | 0 | const basic_string & | +| stl.h:179:17:179:22 | append | 0 | const class:0 * | +| stl.h:180:17:180:22 | append | 0 | size_type | +| stl.h:180:17:180:22 | append | 1 | class:0 | +| stl.h:181:47:181:52 | append | 0 | func:0 | +| stl.h:181:47:181:52 | append | 1 | func:0 | +| stl.h:182:17:182:22 | assign | 0 | const basic_string & | +| stl.h:183:17:183:22 | assign | 0 | size_type | +| stl.h:183:17:183:22 | assign | 1 | class:0 | +| stl.h:184:47:184:52 | assign | 0 | func:0 | +| stl.h:184:47:184:52 | assign | 1 | func:0 | +| stl.h:185:17:185:22 | insert | 0 | size_type | +| stl.h:185:17:185:22 | insert | 1 | const basic_string & | | stl.h:186:17:186:22 | insert | 0 | size_type | -| stl.h:186:17:186:22 | insert | 1 | const basic_string & | +| stl.h:186:17:186:22 | insert | 1 | size_type | +| stl.h:186:17:186:22 | insert | 2 | class:0 | | stl.h:187:17:187:22 | insert | 0 | size_type | -| stl.h:187:17:187:22 | insert | 1 | size_type | -| stl.h:187:17:187:22 | insert | 2 | class:0 | -| stl.h:188:12:188:17 | insert | 0 | size_type | -| stl.h:188:12:188:17 | insert | 1 | const class:0 * | +| stl.h:187:17:187:22 | insert | 1 | const class:0 * | +| stl.h:188:12:188:17 | insert | 0 | const_iterator | +| stl.h:188:12:188:17 | insert | 1 | size_type | +| stl.h:188:12:188:17 | insert | 2 | class:0 | | stl.h:189:42:189:47 | insert | 0 | const_iterator | -| stl.h:189:42:189:47 | insert | 1 | size_type | -| stl.h:189:42:189:47 | insert | 2 | class:0 | -| stl.h:190:17:190:23 | replace | 0 | const_iterator | -| stl.h:190:17:190:23 | replace | 1 | func:0 | -| stl.h:190:17:190:23 | replace | 2 | func:0 | +| stl.h:189:42:189:47 | insert | 1 | func:0 | +| stl.h:189:42:189:47 | insert | 2 | func:0 | +| stl.h:190:17:190:23 | replace | 0 | size_type | +| stl.h:190:17:190:23 | replace | 1 | size_type | +| stl.h:190:17:190:23 | replace | 2 | const basic_string & | | stl.h:191:17:191:23 | replace | 0 | size_type | | stl.h:191:17:191:23 | replace | 1 | size_type | -| stl.h:191:17:191:23 | replace | 2 | const basic_string & | -| stl.h:192:13:192:16 | copy | 0 | size_type | +| stl.h:191:17:191:23 | replace | 2 | size_type | +| stl.h:191:17:191:23 | replace | 3 | class:0 | +| stl.h:192:13:192:16 | copy | 0 | class:0 * | | stl.h:192:13:192:16 | copy | 1 | size_type | | stl.h:192:13:192:16 | copy | 2 | size_type | -| stl.h:192:13:192:16 | copy | 3 | class:0 | -| stl.h:193:8:193:12 | clear | 0 | class:0 * | -| stl.h:193:8:193:12 | clear | 1 | size_type | -| stl.h:193:8:193:12 | clear | 2 | size_type | -| stl.h:195:8:195:11 | swap | 0 | size_type | -| stl.h:195:8:195:11 | swap | 1 | size_type | +| stl.h:194:16:194:21 | substr | 0 | size_type | +| stl.h:194:16:194:21 | substr | 1 | size_type | +| stl.h:195:8:195:11 | swap | 0 | basic_string & | | stl.h:198:94:198:102 | operator+ | 0 | const basic_string & | | stl.h:198:94:198:102 | operator+ | 1 | const basic_string & | | stl.h:199:94:199:102 | operator+ | 0 | const basic_string & | From 2d581504f7b8dfd4b5aaa4ed72af023f20600f2e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 28 May 2026 12:07:50 +0200 Subject: [PATCH 143/226] C++: Fix Copilot comments. --- cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll index 4ec2f2f3997..4a89e91c74e 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll @@ -276,7 +276,7 @@ private predicate isClassConstructedFrom(Class c, Class templateClass) { not c.isConstructedFrom(_) and c = templateClass } -/** Gets the fully templated version of `f`. */ +/** Gets the fully templated version of `c`. */ private Class getFullyTemplatedClassOld(Class c) { not c.isFromUninstantiatedTemplate(_) and isClassConstructedFrom(c, result) @@ -289,7 +289,7 @@ private TemplateClass getOriginalClassTemplate(TemplateClass tc) { result = tc } -/** Gets the fully templated version of `f`. */ +/** Gets the fully templated version of `c`. */ private Class getFullyTemplatedClassNew(Class c) { not c.isFromUninstantiatedTemplate(_) and exists(Class mid | From df15a719cb77241ab46f4268ec7c424c206aa03d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 28 May 2026 16:48:23 +0100 Subject: [PATCH 144/226] Add a `ContentSet` for any tuple or dictionary element --- .../semmle/python/dataflow/new/internal/DataFlowPrivate.qll | 4 ++-- .../semmle/python/dataflow/new/internal/DataFlowPublic.qll | 6 +++++- .../semmle/python/dataflow/new/internal/FlowSummaryImpl.qll | 2 ++ .../python/dataflow/new/internal/TaintTrackingPrivate.qll | 4 +--- .../LoopVariableCapture/LoopVariableCaptureQuery.qll | 4 +--- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 1c9ec5dff17..1ea5765dc37 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -1078,7 +1078,7 @@ module Conversions { nodeFrom = decoding.getAnInput() and nodeTo = decoding.getOutput() ) and - (c.isAnyTupleElement() or c.isAnyDictionaryElement()) + c.isAnyTupleOrDictionaryElement() } predicate encoderReadStep(Node nodeFrom, ContentSet c, Node nodeTo) { @@ -1086,7 +1086,7 @@ module Conversions { nodeFrom = encoding.getAnInput() and nodeTo = encoding.getOutput() ) and - (c.isAnyTupleElement() or c.isAnyDictionaryElement()) + c.isAnyTupleOrDictionaryElement() } predicate formatReadStep(Node nodeFrom, ContentSet c, Node nodeTo) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 173a5598149..c1e01cf08a9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -914,7 +914,8 @@ class CapturedVariableContent extends Content, TCapturedVariableContent { private newtype TContentSet = TSingletonContent(Content c) or TAnyTupleElement() or - TAnyDictionaryElement() + TAnyDictionaryElement() or + TAnyTupleOrDictionaryElement() /** * An entity that represents a set of `Content`s. @@ -932,6 +933,9 @@ class ContentSet extends TContentSet { /** Holds if this content set is the wildcard for all dictionary elements. */ predicate isAnyDictionaryElement() { this = TAnyDictionaryElement() } + /** Holds if this content set is the wildcard for all tuple elements or dictionary elements. */ + predicate isAnyTupleOrDictionaryElement() { this = TAnyTupleOrDictionaryElement() } + /** Gets a content that may be stored into when storing into this set. */ Content getAStoreContent() { this = TSingletonContent(result) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index 1e9ffcf463c..0931fcca0dc 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -87,6 +87,8 @@ module Input implements InputSig cs.isAnyTupleElement() and result = "AnyTupleElement" and arg = "" or cs.isAnyDictionaryElement() and result = "AnyDictionaryElement" and arg = "" + or + cs.isAnyTupleOrDictionaryElement() and result = "AnyTupleOrDictionaryElement" and arg = "" } bindingset[token] diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index de5a06eaaad..7f25d276c07 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -21,9 +21,7 @@ private predicate defaultTaintReadContent(DataFlow::ContentSet contentSet) { // expand to one row per (node, distinct key or index) and the framework's // read-set relation grows quadratically). `ContentSet.getAReadContent` expands // these wildcards back to the specific contents when matching against stores. - contentSet.isAnyTupleElement() - or - contentSet.isAnyDictionaryElement() + contentSet.isAnyTupleOrDictionaryElement() or // List and set element content is already imprecise, so no wildcard expansion is // needed. diff --git a/python/ql/src/Variables/LoopVariableCapture/LoopVariableCaptureQuery.qll b/python/ql/src/Variables/LoopVariableCapture/LoopVariableCaptureQuery.qll index 6b3e428b995..80577805e6d 100644 --- a/python/ql/src/Variables/LoopVariableCapture/LoopVariableCaptureQuery.qll +++ b/python/ql/src/Variables/LoopVariableCapture/LoopVariableCaptureQuery.qll @@ -61,9 +61,7 @@ module EscapingCaptureFlowConfig implements DataFlow::ConfigSig { predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet cs) { isSink(node) and ( - cs.isAnyTupleElement() - or - cs.isAnyDictionaryElement() + cs.isAnyTupleOrDictionaryElement() or cs.getAStoreContent() instanceof DataFlow::ListElementContent or From 09371339d7b95e84e68ae0a27e10816d1d823214 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 28 May 2026 10:49:04 +0200 Subject: [PATCH 145/226] Ruby: Adopt shared local name resolution library --- ruby/ql/lib/codeql/ruby/ast/Parameter.qll | 14 +- ruby/ql/lib/codeql/ruby/ast/internal/AST.qll | 4 +- .../codeql/ruby/ast/internal/Parameter.qll | 2 +- .../ql/lib/codeql/ruby/ast/internal/Scope.qll | 12 +- .../codeql/ruby/ast/internal/Synthesis.qll | 47 ++-- .../lib/codeql/ruby/ast/internal/Variable.qll | 266 +++++++++++------- ruby/ql/lib/qlpack.yml | 1 + 7 files changed, 209 insertions(+), 137 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/Parameter.qll b/ruby/ql/lib/codeql/ruby/ast/Parameter.qll index 5b3994378c1..953d3f01d92 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Parameter.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Parameter.qll @@ -134,7 +134,7 @@ class BlockParameter extends NamedParameter, TBlockParameter { final override string getName() { result = g.getName().getValue() } final override LocalVariable getVariable() { - result = TLocalVariableReal(_, _, g.getName()) or + result.(LocalVariableReal).getDefiningNode() = g.getName() or result = TLocalVariableSynth(this, 0) } @@ -164,7 +164,7 @@ class HashSplatParameter extends NamedParameter, THashSplatParameter { final override string getAPrimaryQlClass() { result = "HashSplatParameter" } final override LocalVariable getVariable() { - result = TLocalVariableReal(_, _, g.getName()) or + result.(LocalVariableReal).getDefiningNode() = g.getName() or result = TLocalVariableSynth(this, 0) } @@ -212,7 +212,9 @@ class KeywordParameter extends NamedParameter, TKeywordParameter { final override string getAPrimaryQlClass() { result = "KeywordParameter" } - final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) } + final override LocalVariable getVariable() { + result.(LocalVariableReal).getDefiningNode() = g.getName() + } /** * Gets the default value, i.e. the value assigned to the parameter when one @@ -262,7 +264,9 @@ class OptionalParameter extends NamedParameter, TOptionalParameter { */ final Expr getDefaultValue() { toGenerated(result) = g.getValue() } - final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) } + final override LocalVariable getVariable() { + result.(LocalVariableReal).getDefiningNode() = g.getName() + } final override string toString() { result = this.getName() } @@ -293,7 +297,7 @@ class SplatParameter extends NamedParameter, TSplatParameter { final override string getAPrimaryQlClass() { result = "SplatParameter" } final override LocalVariable getVariable() { - result = TLocalVariableReal(_, _, g.getName()) or + result.(LocalVariableReal).getDefiningNode() = g.getName() or result = TLocalVariableSynth(this, 0) } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll b/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll index ee46fbe8b66..8059a1d95aa 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/AST.qll @@ -200,9 +200,7 @@ private module Cached { TLambda(Ruby::Lambda g) or TLine(Ruby::Line g) or TLeftAssignmentList(Ruby::LeftAssignmentList g) or - TLocalVariableAccessReal(Ruby::Identifier g, TLocalVariableReal v) { - LocalVariableAccess::range(g, v) - } or + TLocalVariableAccessReal(Ruby::Identifier g, TLocalVariableReal v) { access(g, v) } or TLocalVariableAccessSynth(Ast::AstNode parent, int i, Ast::LocalVariable v) { mkSynthChild(LocalVariableAccessRealKind(v), parent, i) or diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Parameter.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Parameter.qll index 8f07554fb0c..94d25aee032 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Parameter.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Parameter.qll @@ -33,7 +33,7 @@ class SimpleParameterRealImpl extends SimpleParameterImpl, TSimpleParameterReal SimpleParameterRealImpl() { this = TSimpleParameterReal(g) } - override LocalVariable getVariableImpl() { result = TLocalVariableReal(_, _, g) } + override LocalVariable getVariableImpl() { result.(LocalVariableReal).getDefiningNode() = g } override string getNameImpl() { result = g.getValue() } } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Scope.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Scope.qll index 03fe2ce4350..9b77a342d53 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Scope.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Scope.qll @@ -118,7 +118,7 @@ private Ruby::AstNode specialParentOf(Ruby::AstNode n) { ] } -private Ruby::AstNode parentOf(Ruby::AstNode n) { +Ruby::AstNode parentOf(Ruby::AstNode n) { n = getHereDocBody(result) or result = specialParentOf(n).getParent() @@ -172,13 +172,15 @@ private module Cached { } } -bindingset[n] -pragma[inline_late] -Scope::Range scopeOf(Ruby::AstNode n) { result = Cached::scopeOfImpl(n) } +import Cached bindingset[n] pragma[inline_late] -Scope scopeOfInclSynth(AstNode n) { result = Cached::scopeOfInclSynthImpl(n) } +Scope::Range scopeOf(Ruby::AstNode n) { result = scopeOfImpl(n) } + +bindingset[n] +pragma[inline_late] +Scope scopeOfInclSynth(AstNode n) { result = scopeOfInclSynthImpl(n) } abstract class ScopeImpl extends AstNode, TScopeType { final Scope getOuterScopeImpl() { result = scopeOfInclSynth(this) } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index f2be91a63e5..63ac4950ba8 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -296,9 +296,12 @@ private predicate hasLocation(AstNode n, Location l) { private module ImplicitSelfSynthesis { pragma[nomagic] private predicate identifierMethodCallSelfSynthesis(AstNode mc, int i, Child child) { - child = SynthChild(SelfKind(TSelfVariable(scopeOf(toGenerated(mc)).getEnclosingSelfScope()))) and - mc = TIdentifierMethodCall(_) and - i = 0 + exists(SelfVariableImpl self | + self.getDeclaringScopeImpl() = scopeOf(toGenerated(mc)).getEnclosingSelfScope() and + child = SynthChild(SelfKind(self)) and + mc = TIdentifierMethodCall(_) and + i = 0 + ) } private class IdentifierMethodCallSelfSynthesis extends Synthesis { @@ -309,13 +312,14 @@ private module ImplicitSelfSynthesis { pragma[nomagic] private predicate regularMethodCallSelfSynthesis(TRegularMethodCall mc, int i, Child child) { - exists(Ruby::AstNode g | + exists(Ruby::AstNode g, SelfVariableImpl self | mc = TRegularMethodCall(g) and // If there's no explicit receiver, then the receiver is implicitly `self`. - not exists(g.(Ruby::Call).getReceiver()) - ) and - child = SynthChild(SelfKind(TSelfVariable(scopeOf(toGenerated(mc)).getEnclosingSelfScope()))) and - i = 0 + not exists(g.(Ruby::Call).getReceiver()) and + self.getDeclaringScopeImpl() = scopeOf(toGenerated(mc)).getEnclosingSelfScope() and + child = SynthChild(SelfKind(self)) and + i = 0 + ) } private class RegularMethodCallSelfSynthesis extends Synthesis { @@ -338,9 +342,10 @@ private module ImplicitSelfSynthesis { */ pragma[nomagic] private SelfKind getSelfKind(InstanceVariableAccess var) { - exists(Ruby::AstNode owner | + exists(Ruby::AstNode owner, SelfVariableImpl self | + self.getDeclaringScopeImpl() = scopeOf(owner).getEnclosingSelfScope() and owner = toGenerated(instanceVarAccessSynthParentStar(var)) and - result = SelfKind(TSelfVariable(scopeOf(owner).getEnclosingSelfScope())) + result = SelfKind(self) ) } @@ -1556,20 +1561,20 @@ private module ForLoopDesugar { * { a: a } * ``` */ -private module ImplicitHashValueSynthesis { - private Ruby::AstNode keyWithoutValue(AstNode parent, int i) { +module ImplicitHashValueSynthesis { + Ruby::AstNode keyWithoutValue(Ruby::AstNode parent, int i) { exists(Ruby::KeywordPattern pair | result = pair.getKey() and - result = toGenerated(parent.(HashPattern).getKey(i)) and + result = parent.(Ruby::HashPattern).getChild(i).(Ruby::KeywordPattern).getKey() and not exists(pair.getValue()) ) or - exists(Ruby::Pair pair | - i = 0 and - result = pair.getKey() and - pair = toGenerated(parent) and - not exists(pair.getValue()) - ) + parent = + any(Ruby::Pair pair | + i = 0 and + result = pair.getKey() and + not exists(pair.getValue()) + ) } private string keyName(Ruby::AstNode key) { @@ -1579,7 +1584,7 @@ private module ImplicitHashValueSynthesis { private class ImplicitHashValueSynthesis extends Synthesis { final override predicate child(AstNode parent, int i, Child child) { - exists(Ruby::AstNode key | key = keyWithoutValue(parent, i) | + exists(Ruby::AstNode key | key = keyWithoutValue(toGenerated(parent), i) | exists(TVariableReal variable | access(key, variable) and child = SynthChild(LocalVariableAccessRealKind(variable)) @@ -1606,7 +1611,7 @@ private module ImplicitHashValueSynthesis { } final override predicate location(AstNode n, Location l) { - exists(AstNode p, int i | l = keyWithoutValue(p, i).getLocation() | + exists(AstNode p, int i | l = keyWithoutValue(toGenerated(p), i).getLocation() | n = p.(HashPattern).getValue(i) or i = 0 and n = p.(Pair).getValue() diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Variable.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Variable.qll index 7c130220a86..6e92b54c246 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Variable.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Variable.qll @@ -2,6 +2,7 @@ overlay[local] module; private import TreeSitter +private import codeql.namebinding.LocalNameBinding private import codeql.ruby.AST private import codeql.ruby.CFG private import codeql.ruby.ast.internal.AST @@ -94,10 +95,11 @@ predicate scopeDefinesParameterVariable( // In case of overlapping parameter names (e.g. `_`), only the first // parameter will give rise to a variable i = - min(Ruby::Identifier other | - parameterAssignment(scope, name, other, _) + min(Ruby::Identifier other, int startline, int startcolumn | + parameterAssignment(scope, name, other, _) and + other.getLocation().hasLocationInfo(_, startline, startcolumn, _, _) | - other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn() + other order by startline, startcolumn ) and parameterAssignment(scope, name, _, pos) or @@ -113,7 +115,8 @@ predicate scopeDefinesParameterVariable( ) } -pragma[nomagic] +bindingset[i] +pragma[inline_late] private string variableNameInScope(Ruby::AstNode i, Scope::Range scope) { scope = scopeOf(i) and ( @@ -137,40 +140,142 @@ private predicate scopeAssigns(Scope::Range scope, string name, Ruby::AstNode i) name = variableNameInScope(i, scope) } +private module Input implements LocalNameBindingInputSig { + predicate cacheRevRef() { exists(TVariable v) implies any() } + + class AstNode = Ruby::AstNode; + + AstNode getChild(AstNode parent, int index) { + parent = parentOf(result) and + ( + index = result.getParentIndex() + or + not exists(result.getParentIndex()) and + index = -1 + ) + } + + class Conditional extends AstNode { + Conditional() { none() } + + AstNode getCondition() { none() } + + AstNode getThen() { none() } + + AstNode getElse() { none() } + } + + class SiblingShadowingDecl extends AstNode { + SiblingShadowingDecl() { none() } + + AstNode getLhs() { none() } + + AstNode getRhs() { none() } + + AstNode getElse() { none() } + } + + predicate isTopScope(AstNode scope) { + scope instanceof Scope::Range and + not ( + scope instanceof Ruby::Block or + scope instanceof Ruby::DoBlock or + scope instanceof Ruby::Lambda + ) + } + + private Scope::Range getParentScope(Scope::Range scope) { + result = scopeOf(scope) and + not isTopScope(scope) + } + + bindingset[name, scope] + pragma[inline_late] + private predicate declInScope0(AstNode definingNode, string name, AstNode scope) { + scopeDefinesParameterVariable(scope, name, definingNode, _) or + scopeAssigns(scope, name, definingNode) + } + + predicate declInScope(AstNode definingNode, string name, AstNode scope) { + scopeDefinesParameterVariable(scope, name, definingNode, _) + or + /* + * Variables are not declared explicitly in Ruby, so we consider the _first_ assignment to + * be the declaration: + * + * ```rb + * a = 1 # declares `a` + * a = 2 # does not declare `a` + * 1.times do | x | # declares `x` + * a = 2 # does not declare `a` + * end + * ``` + */ + + scopeAssigns(scope, name, definingNode) and + not scopeDefinesParameterVariable(scope, name, _, _) and + not exists(AstNode prev, AstNode prevScope | + prevScope = getParentScope*(scope) and + declInScope0(prev, name, prevScope) and + prev.getLocation().strictlyBefore(definingNode.getLocation()) + ) + } + + predicate implicitDeclInScope(string name, AstNode scope) { + name = "self" and + scope instanceof SelfBase::Range + } + + predicate accessCand(AstNode n, string name) { + name = variableNameInScope(n, _) and + ( + explicitAssignmentNode(n, _) + or + implicitAssignmentNode(n) + or + scopeDefinesParameterVariable(_, _, n, _) + or + vcall(n) + or + n = any(Ruby::VariableReferencePattern vr).getName() + or + n = ImplicitHashValueSynthesis::keyWithoutValue(_, _) + ) + or + n instanceof Ruby::Self and + name = "self" + } +} + +private import LocalNameBinding + cached private module Cached { cached newtype TVariable = - TGlobalVariable(string name) { name = any(Ruby::GlobalVariable var).getValue() } or + TGlobalVariable(string name) { + CachedStage::ref() and + name = any(Ruby::GlobalVariable var).getValue() + } or TClassVariable(Scope::Range scope, string name, Ruby::AstNode decl) { decl = - min(Ruby::ClassVariable other | - classVariableAccess(other, name, scope) + min(Ruby::ClassVariable other, int startline, int startcolumn | + classVariableAccess(other, name, scope) and + other.getLocation().hasLocationInfo(_, startline, startcolumn, _, _) | - other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn() + other order by startline, startcolumn ) } or TInstanceVariable(Scope::Range scope, string name, boolean instance, Ruby::AstNode decl) { decl = - min(Ruby::InstanceVariable other | - instanceVariableAccess(other, name, scope, instance) + min(Ruby::InstanceVariable other, int startline, int startcolumn | + instanceVariableAccess(other, name, scope, instance) and + other.getLocation().hasLocationInfo(_, startline, startcolumn, _, _) | - other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn() + other order by startline, startcolumn ) } or - TLocalVariableReal(Scope::Range scope, string name, Ruby::AstNode i) { - scopeDefinesParameterVariable(scope, name, i, _) - or - i = - min(Ruby::AstNode other | - scopeAssigns(scope, name, other) - | - other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn() - ) and - not scopeDefinesParameterVariable(scope, name, _, _) and - not inherits(scope, name, _) - } or - TSelfVariable(SelfBase::Range scope) or + TLocalVariableReal(Local l) or TLocalVariableSynth(AstNode n, int i) { any(Synthesis s).localVariable(n, i) } // Db types that can be vcalls @@ -321,39 +426,37 @@ private module Cached { i = any(Ruby::ExpressionReferencePattern x).getValue() } - pragma[nomagic] - private predicate hasScopeAndName(VariableReal variable, Scope::Range scope, string name) { - variable.getNameImpl() = name and - scope = variable.getDeclaringScopeImpl() - } - cached predicate access(Ruby::AstNode access, VariableReal variable) { - exists(string name, Scope::Range scope | - pragma[only_bind_into](name) = variableNameInScope(access, scope) + exists(Local l | + variable = TLocalVariableReal(l) and + access = l.getAnAccess() | - hasScopeAndName(variable, scope, name) and - not access.getLocation().strictlyBefore(variable.getLocationImpl()) and - // In case of overlapping parameter names, later parameters should not - // be considered accesses to the first parameter - if parameterAssignment(_, _, access, _) - then scopeDefinesParameterVariable(_, _, access, _) - else any() + l instanceof ImplicitLocal or - exists(Scope::Range declScope | - hasScopeAndName(variable, declScope, pragma[only_bind_into](name)) and - inherits(scope, name, declScope) - ) + /* + * In the example below, `a` is declared in the scope of `M`, but only the + * second mention of `a` is an actual access: + * + * ```rb + * module M + * puts a # calls method `a` + * a = 1 # declares `a` + * puts a # accesses variable `a` + * end + * ``` + */ + + not access.getLocation().strictlyBefore(l.getDefiningNode().getLocation()) ) } private class Access extends Ruby::Token { Access() { - access(this.(Ruby::Identifier), _) or + access(this, _) or this instanceof Ruby::GlobalVariable or this instanceof Ruby::InstanceVariable or - this instanceof Ruby::ClassVariable or - this instanceof Ruby::Self + this instanceof Ruby::ClassVariable } } @@ -398,29 +501,6 @@ private module Cached { import Cached -/** Holds if this scope inherits `name` from an outer scope `outer`. */ -private predicate inherits(Scope::Range scope, string name, Scope::Range outer) { - ( - scope instanceof Ruby::Block or - scope instanceof Ruby::DoBlock or - scope instanceof Ruby::Lambda - ) and - not scopeDefinesParameterVariable(scope, name, _, _) and - ( - outer = scope.getOuterScope() and - ( - scopeDefinesParameterVariable(outer, name, _, _) - or - exists(Ruby::AstNode i | - scopeAssigns(outer, name, i) and - i.getLocation().strictlyBefore(scope.getLocation()) - ) - ) - or - inherits(scope.getOuterScope(), name, outer) - ) -} - abstract class VariableImpl extends TVariable { abstract string getNameImpl(); @@ -429,10 +509,9 @@ abstract class VariableImpl extends TVariable { abstract Location getLocationImpl(); } -class TVariableReal = - TGlobalVariable or TClassVariable or TInstanceVariable or TLocalVariableReal or TSelfVariable; +class TVariableReal = TGlobalVariable or TClassVariable or TInstanceVariable or TLocalVariableReal; -class TLocalVariable = TLocalVariableReal or TLocalVariableSynth or TSelfVariable; +class TLocalVariable = TLocalVariableReal or TLocalVariableSynth; /** * A "real" (i.e. non-synthesized) variable. This class only exists to @@ -458,19 +537,19 @@ private class VariableRealAdapter extends VariableImpl, TVariableReal instanceof } class LocalVariableReal extends VariableReal, TLocalVariableReal { - private Scope::Range scope; - private string name; - private Ruby::AstNode i; + private Local l; - LocalVariableReal() { this = TLocalVariableReal(scope, name, i) } + LocalVariableReal() { this = TLocalVariableReal(l) } - final override string getNameImpl() { result = name } + Ruby::AstNode getDefiningNode() { result = l.getDefiningNode() } - final override Location getLocationImpl() { result = i.getLocation() } + final override string getNameImpl() { result = l.getName() } - final override Scope::Range getDeclaringScopeImpl() { result = scope } + final override Location getLocationImpl() { result = l.getLocation() } - final VariableAccess getDefiningAccessImpl() { toGenerated(result) = i } + final override Scope::Range getDeclaringScopeImpl() { result = l.getScope() } + + final VariableAccess getDefiningAccessImpl() { toGenerated(result) = l.getDefiningNode() } } class LocalVariableSynth extends VariableImpl, TLocalVariableSynth { @@ -531,34 +610,16 @@ class ClassVariableImpl extends VariableReal, TClassVariable { final override Scope::Range getDeclaringScopeImpl() { result = scope } } -class SelfVariableImpl extends VariableReal, TSelfVariable { - private SelfBase::Range scope; +class SelfVariableImpl extends LocalVariableReal { + private ImplicitLocal l; - SelfVariableImpl() { this = TSelfVariable(scope) } - - final override string getNameImpl() { result = "self" } - - final override Location getLocationImpl() { result = scope.getLocation() } - - final override Scope::Range getDeclaringScopeImpl() { result = scope } + SelfVariableImpl() { this = TLocalVariableReal(l) } } abstract class VariableAccessImpl extends Expr, TVariableAccess { abstract VariableImpl getVariableImpl(); } -module LocalVariableAccess { - predicate range(Ruby::Identifier id, TLocalVariableReal v) { - access(id, v) and - ( - explicitWriteAccess(id, _) or - implicitWriteAccess(id) or - vcall(id) or - id = any(Ruby::VariableReferencePattern vr).getName() - ) - } -} - class TVariableAccessReal = TLocalVariableAccessReal or TGlobalVariableAccess or TInstanceVariableAccess or TClassVariableAccess; @@ -681,7 +742,8 @@ private class SelfVariableAccessReal extends SelfVariableAccessImpl, TSelfReal { SelfVariableAccessReal() { exists(Ruby::Self self | - this = TSelfReal(self) and var = TSelfVariable(scopeOf(self).getEnclosingSelfScope()) + this = TSelfReal(self) and + access(self, var) ) } diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index df8efbe68de..157bc031a71 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -14,6 +14,7 @@ dependencies: codeql/ssa: ${workspace} codeql/tutorial: ${workspace} codeql/util: ${workspace} + codeql/namebinding: ${workspace} dataExtensions: - codeql/ruby/frameworks/**/model.yml - codeql/ruby/frameworks/**/*.model.yml From aee33a0cc90918b121717ee26719fc25fe51a174 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 29 May 2026 10:26:24 +0100 Subject: [PATCH 146/226] Add missing code for `TAnyTupleOrDictionaryElement` --- .../python/dataflow/new/internal/DataFlowPublic.qll | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index c1e01cf08a9..bb393630463 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -950,6 +950,13 @@ class ContentSet extends TContentSet { or this = TAnyDictionaryElement() and (result instanceof DictionaryElementContent or result instanceof DictionaryElementAnyContent) + or + this = TAnyTupleOrDictionaryElement() and + ( + result instanceof TupleElementContent or + result instanceof DictionaryElementContent or + result instanceof DictionaryElementAnyContent + ) } /** Gets a textual representation of this content set. */ @@ -959,6 +966,8 @@ class ContentSet extends TContentSet { this = TAnyTupleElement() and result = "Any tuple element" or this = TAnyDictionaryElement() and result = "Any dictionary element" + or + this = TAnyTupleOrDictionaryElement() and result = "Any tuple or dictionary element" } } From 9bc0c1b1ab2cf222b8117c834875d5b1d236cc44 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Fri, 29 May 2026 12:13:50 +0100 Subject: [PATCH 147/226] Revert "Release preparation for version 2.25.6" --- actions/ql/lib/CHANGELOG.md | 6 ------ ...2026-05-12-improved-alphanumeric-regex.md} | 9 ++++----- actions/ql/lib/codeql-pack.release.yml | 2 +- actions/ql/lib/qlpack.yml | 2 +- actions/ql/src/CHANGELOG.md | 19 ------------------- .../2026-05-05-untrusted-checkout-high.md | 4 ++++ .../2026-05-12-sha256-pinned-actions.md | 4 ++++ ...n-untrusted-checkout-improvements-alert.md | 4 ++++ ...ntrusted-checkout-improvements-helpfile.md | 4 ++++ ...ntrusted-checkout-improvements-metadata.md | 4 ++++ .../ql/src/change-notes/released/0.6.29.md | 18 ------------------ actions/ql/src/codeql-pack.release.yml | 2 +- actions/ql/src/qlpack.yml | 2 +- cpp/ql/lib/CHANGELOG.md | 16 ---------------- .../change-notes/2026-05-15-secure-scanf.md | 5 +++++ .../change-notes/2026-05-16-alias-template.md | 4 ++++ .../lib/change-notes/2026-05-18-alias-type.md | 4 ++++ .../change-notes/2026-05-21-generated-from.md | 4 ++++ cpp/ql/lib/change-notes/released/10.2.0.md | 15 --------------- cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 4 ---- cpp/ql/src/change-notes/released/1.6.4.md | 3 --- cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ---- .../lib/change-notes/released/1.7.68.md | 3 --- .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ---- .../src/change-notes/released/1.7.68.md | 3 --- .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 7 ------- .../2026-05-12-user-increment-decrement.md | 4 ++++ ...0.2.md => 2026-05-20-csharp14-dotnet10.md} | 8 +++----- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 4 ---- csharp/ql/src/change-notes/released/1.7.4.md | 3 --- csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.51.md | 3 --- .../codeql-pack.release.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 4 ---- go/ql/lib/change-notes/released/7.1.2.md | 3 --- go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ---- go/ql/src/change-notes/released/1.6.4.md | 3 --- go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 6 ------ .../9.1.2.md => 2026-05-19-avro-mads.md} | 7 +++---- java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 4 ---- java/ql/src/change-notes/released/1.11.4.md | 3 --- java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 6 ------ .../2.7.2.md => 2026-05-14-sensitive-data.md} | 7 +++---- javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 4 ---- .../ql/src/change-notes/released/2.3.11.md | 3 --- javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.51.md | 3 --- misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 6 ------ .../7.1.2.md => 2026-05-14-sensitive-data.md} | 7 +++---- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ---- python/ql/src/change-notes/released/1.8.4.md | 3 --- python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 4 ---- ruby/ql/lib/change-notes/released/5.2.2.md | 3 --- ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ---- ruby/ql/src/change-notes/released/1.6.4.md | 3 --- ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- rust/ql/lib/CHANGELOG.md | 6 ------ ...0.2.15.md => 2026-05-14-sensitive-data.md} | 7 +++---- rust/ql/lib/codeql-pack.release.yml | 2 +- rust/ql/lib/qlpack.yml | 2 +- rust/ql/src/CHANGELOG.md | 4 ---- rust/ql/src/change-notes/released/0.1.36.md | 3 --- rust/ql/src/codeql-pack.release.yml | 2 +- rust/ql/src/qlpack.yml | 2 +- shared/concepts/CHANGELOG.md | 4 ---- .../concepts/change-notes/released/0.0.25.md | 3 --- shared/concepts/codeql-pack.release.yml | 2 +- shared/concepts/qlpack.yml | 2 +- shared/controlflow/CHANGELOG.md | 4 ---- .../change-notes/released/2.0.35.md | 3 --- shared/controlflow/codeql-pack.release.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/CHANGELOG.md | 4 ---- .../dataflow/change-notes/released/2.1.7.md | 3 --- shared/dataflow/codeql-pack.release.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/CHANGELOG.md | 4 ---- shared/mad/change-notes/released/1.0.51.md | 3 --- shared/mad/codeql-pack.release.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/quantum/CHANGELOG.md | 4 ---- .../quantum/change-notes/released/0.0.29.md | 3 --- shared/quantum/codeql-pack.release.yml | 2 +- shared/quantum/qlpack.yml | 2 +- shared/rangeanalysis/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.51.md | 3 --- shared/rangeanalysis/codeql-pack.release.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ---- shared/regex/change-notes/released/1.0.51.md | 3 --- shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ---- shared/ssa/change-notes/released/2.0.27.md | 3 --- shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/CHANGELOG.md | 4 ---- .../change-notes/released/1.0.51.md | 3 --- shared/threat-models/codeql-pack.release.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ---- .../tutorial/change-notes/released/1.0.51.md | 3 --- shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/CHANGELOG.md | 4 ---- .../typeflow/change-notes/released/1.0.51.md | 3 --- shared/typeflow/codeql-pack.release.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typeinference/CHANGELOG.md | 4 ---- .../change-notes/released/0.0.32.md | 3 --- shared/typeinference/codeql-pack.release.yml | 2 +- shared/typeinference/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ---- .../change-notes/released/2.0.35.md | 3 --- shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ---- shared/typos/change-notes/released/1.0.51.md | 3 --- shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 4 ---- shared/util/change-notes/released/2.0.38.md | 3 --- shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/CHANGELOG.md | 4 ---- shared/xml/change-notes/released/1.0.51.md | 3 --- shared/xml/codeql-pack.release.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ---- shared/yaml/change-notes/released/1.0.51.md | 3 --- shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/CHANGELOG.md | 10 ---------- .../6.7.0.md => 2026-05-14-sensitive-data.md} | 11 +++-------- .../change-notes/2026-05-19-swift-6.3.2.md | 4 ++++ swift/ql/lib/codeql-pack.release.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/CHANGELOG.md | 4 ---- swift/ql/src/change-notes/released/1.3.4.md | 3 --- swift/ql/src/codeql-pack.release.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 175 files changed, 149 insertions(+), 455 deletions(-) rename actions/ql/lib/change-notes/{released/0.4.37.md => 2026-05-12-improved-alphanumeric-regex.md} (80%) create mode 100644 actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md create mode 100644 actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md create mode 100644 actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md create mode 100644 actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md create mode 100644 actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md delete mode 100644 actions/ql/src/change-notes/released/0.6.29.md create mode 100644 cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md create mode 100644 cpp/ql/lib/change-notes/2026-05-16-alias-template.md create mode 100644 cpp/ql/lib/change-notes/2026-05-18-alias-type.md create mode 100644 cpp/ql/lib/change-notes/2026-05-21-generated-from.md delete mode 100644 cpp/ql/lib/change-notes/released/10.2.0.md delete mode 100644 cpp/ql/src/change-notes/released/1.6.4.md delete mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md delete mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md create mode 100644 csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md rename csharp/ql/lib/change-notes/{released/6.0.2.md => 2026-05-20-csharp14-dotnet10.md} (67%) delete mode 100644 csharp/ql/src/change-notes/released/1.7.4.md delete mode 100644 go/ql/consistency-queries/change-notes/released/1.0.51.md delete mode 100644 go/ql/lib/change-notes/released/7.1.2.md delete mode 100644 go/ql/src/change-notes/released/1.6.4.md rename java/ql/lib/change-notes/{released/9.1.2.md => 2026-05-19-avro-mads.md} (61%) delete mode 100644 java/ql/src/change-notes/released/1.11.4.md rename javascript/ql/lib/change-notes/{released/2.7.2.md => 2026-05-14-sensitive-data.md} (89%) delete mode 100644 javascript/ql/src/change-notes/released/2.3.11.md delete mode 100644 misc/suite-helpers/change-notes/released/1.0.51.md rename python/ql/lib/change-notes/{released/7.1.2.md => 2026-05-14-sensitive-data.md} (90%) delete mode 100644 python/ql/src/change-notes/released/1.8.4.md delete mode 100644 ruby/ql/lib/change-notes/released/5.2.2.md delete mode 100644 ruby/ql/src/change-notes/released/1.6.4.md rename rust/ql/lib/change-notes/{released/0.2.15.md => 2026-05-14-sensitive-data.md} (89%) delete mode 100644 rust/ql/src/change-notes/released/0.1.36.md delete mode 100644 shared/concepts/change-notes/released/0.0.25.md delete mode 100644 shared/controlflow/change-notes/released/2.0.35.md delete mode 100644 shared/dataflow/change-notes/released/2.1.7.md delete mode 100644 shared/mad/change-notes/released/1.0.51.md delete mode 100644 shared/quantum/change-notes/released/0.0.29.md delete mode 100644 shared/rangeanalysis/change-notes/released/1.0.51.md delete mode 100644 shared/regex/change-notes/released/1.0.51.md delete mode 100644 shared/ssa/change-notes/released/2.0.27.md delete mode 100644 shared/threat-models/change-notes/released/1.0.51.md delete mode 100644 shared/tutorial/change-notes/released/1.0.51.md delete mode 100644 shared/typeflow/change-notes/released/1.0.51.md delete mode 100644 shared/typeinference/change-notes/released/0.0.32.md delete mode 100644 shared/typetracking/change-notes/released/2.0.35.md delete mode 100644 shared/typos/change-notes/released/1.0.51.md delete mode 100644 shared/util/change-notes/released/2.0.38.md delete mode 100644 shared/xml/change-notes/released/1.0.51.md delete mode 100644 shared/yaml/change-notes/released/1.0.51.md rename swift/ql/lib/change-notes/{released/6.7.0.md => 2026-05-14-sensitive-data.md} (76%) create mode 100644 swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md delete mode 100644 swift/ql/src/change-notes/released/1.3.4.md diff --git a/actions/ql/lib/CHANGELOG.md b/actions/ql/lib/CHANGELOG.md index 7a61a60c379..ddd0b0f1aec 100644 --- a/actions/ql/lib/CHANGELOG.md +++ b/actions/ql/lib/CHANGELOG.md @@ -1,9 +1,3 @@ -## 0.4.37 - -### Minor Analysis Improvements - -* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. - ## 0.4.36 ### Minor Analysis Improvements diff --git a/actions/ql/lib/change-notes/released/0.4.37.md b/actions/ql/lib/change-notes/2026-05-12-improved-alphanumeric-regex.md similarity index 80% rename from actions/ql/lib/change-notes/released/0.4.37.md rename to actions/ql/lib/change-notes/2026-05-12-improved-alphanumeric-regex.md index 4809796b3ab..df3aaf3613f 100644 --- a/actions/ql/lib/change-notes/released/0.4.37.md +++ b/actions/ql/lib/change-notes/2026-05-12-improved-alphanumeric-regex.md @@ -1,5 +1,4 @@ -## 0.4.37 - -### Minor Analysis Improvements - -* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. +--- +category: minorAnalysis +--- +* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. \ No newline at end of file diff --git a/actions/ql/lib/codeql-pack.release.yml b/actions/ql/lib/codeql-pack.release.yml index df274514780..45433e3ec03 100644 --- a/actions/ql/lib/codeql-pack.release.yml +++ b/actions/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.37 +lastReleaseVersion: 0.4.36 diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml index 71c9cadbf28..ae4a57aa944 100644 --- a/actions/ql/lib/qlpack.yml +++ b/actions/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-all -version: 0.4.37 +version: 0.4.37-dev library: true warnOnImplicitThis: true dependencies: diff --git a/actions/ql/src/CHANGELOG.md b/actions/ql/src/CHANGELOG.md index c37cd20761b..1670f0af5be 100644 --- a/actions/ql/src/CHANGELOG.md +++ b/actions/ql/src/CHANGELOG.md @@ -1,22 +1,3 @@ -## 0.6.29 - -### Query Metadata Changes - -* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`. - -### Major Analysis Improvements - -* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. - -### Minor Analysis Improvements - -* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`. -* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. - -### Bug Fixes - -* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. - ## 0.6.28 ### Query Metadata Changes diff --git a/actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md b/actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md new file mode 100644 index 00000000000..098c60a3753 --- /dev/null +++ b/actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. \ No newline at end of file diff --git a/actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md b/actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md new file mode 100644 index 00000000000..521a5878c37 --- /dev/null +++ b/actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. diff --git a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md new file mode 100644 index 00000000000..f5ad3271a62 --- /dev/null +++ b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`. \ No newline at end of file diff --git a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md new file mode 100644 index 00000000000..83e6528c86b --- /dev/null +++ b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. \ No newline at end of file diff --git a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md new file mode 100644 index 00000000000..5df1f3347ea --- /dev/null +++ b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md @@ -0,0 +1,4 @@ +--- +category: queryMetadata +--- +* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`. \ No newline at end of file diff --git a/actions/ql/src/change-notes/released/0.6.29.md b/actions/ql/src/change-notes/released/0.6.29.md deleted file mode 100644 index 82ca8174954..00000000000 --- a/actions/ql/src/change-notes/released/0.6.29.md +++ /dev/null @@ -1,18 +0,0 @@ -## 0.6.29 - -### Query Metadata Changes - -* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`. - -### Major Analysis Improvements - -* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. - -### Minor Analysis Improvements - -* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`. -* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. - -### Bug Fixes - -* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. diff --git a/actions/ql/src/codeql-pack.release.yml b/actions/ql/src/codeql-pack.release.yml index e785984cacc..90f3f09295a 100644 --- a/actions/ql/src/codeql-pack.release.yml +++ b/actions/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.29 +lastReleaseVersion: 0.6.28 diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml index 3615c08b583..33ab175fb18 100644 --- a/actions/ql/src/qlpack.yml +++ b/actions/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-queries -version: 0.6.29 +version: 0.6.29-dev library: false warnOnImplicitThis: true groups: [actions, queries] diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 0b3413f9d3c..3b95c10fbb5 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,19 +1,3 @@ -## 10.2.0 - -### Deprecated APIs - -* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead. - -### New Features - -* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. -* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. - -### Minor Analysis Improvements - -* Added flow source models for `scanf_s` and related functions. -* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported. - ## 10.1.1 ### Minor Analysis Improvements diff --git a/cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md b/cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md new file mode 100644 index 00000000000..0b8d5a79a72 --- /dev/null +++ b/cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Added flow source models for `scanf_s` and related functions. +* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2026-05-16-alias-template.md b/cpp/ql/lib/change-notes/2026-05-16-alias-template.md new file mode 100644 index 00000000000..2777da94abf --- /dev/null +++ b/cpp/ql/lib/change-notes/2026-05-16-alias-template.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. diff --git a/cpp/ql/lib/change-notes/2026-05-18-alias-type.md b/cpp/ql/lib/change-notes/2026-05-18-alias-type.md new file mode 100644 index 00000000000..b744dd2fa95 --- /dev/null +++ b/cpp/ql/lib/change-notes/2026-05-18-alias-type.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead. diff --git a/cpp/ql/lib/change-notes/2026-05-21-generated-from.md b/cpp/ql/lib/change-notes/2026-05-21-generated-from.md new file mode 100644 index 00000000000..bf3ddcb1070 --- /dev/null +++ b/cpp/ql/lib/change-notes/2026-05-21-generated-from.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. diff --git a/cpp/ql/lib/change-notes/released/10.2.0.md b/cpp/ql/lib/change-notes/released/10.2.0.md deleted file mode 100644 index cb514b82cbb..00000000000 --- a/cpp/ql/lib/change-notes/released/10.2.0.md +++ /dev/null @@ -1,15 +0,0 @@ -## 10.2.0 - -### Deprecated APIs - -* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead. - -### New Features - -* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. -* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. - -### Minor Analysis Improvements - -* Added flow source models for `scanf_s` and related functions. -* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index a230efed2a4..940a668bbf3 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 10.2.0 +lastReleaseVersion: 10.1.1 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 04ee2d76ae9..bca102a1048 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 10.2.0 +version: 10.1.2-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index e8a2af1383c..901d2092283 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.6.4 - -No user-facing changes. - ## 1.6.3 ### Minor Analysis Improvements diff --git a/cpp/ql/src/change-notes/released/1.6.4.md b/cpp/ql/src/change-notes/released/1.6.4.md deleted file mode 100644 index 5c811dc4638..00000000000 --- a/cpp/ql/src/change-notes/released/1.6.4.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.6.4 - -No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 1910e09d6a6..00b51441d88 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.4 +lastReleaseVersion: 1.6.3 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 4915f969278..74055b4cf11 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.6.4 +version: 1.6.4-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 3ceb4374a77..eefb35f174a 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.7.68 - -No user-facing changes. - ## 1.7.67 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md deleted file mode 100644 index 774ffcebdfe..00000000000 --- a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.7.68 - -No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index f737dfa0972..0293fdade8f 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.68 +lastReleaseVersion: 1.7.67 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 1de44f9e1d8..659dd5b0038 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.68 +version: 1.7.68-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 3ceb4374a77..eefb35f174a 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.7.68 - -No user-facing changes. - ## 1.7.67 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md deleted file mode 100644 index 774ffcebdfe..00000000000 --- a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.7.68 - -No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index f737dfa0972..0293fdade8f 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.68 +lastReleaseVersion: 1.7.67 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index e99c5a26b32..c7f243d86f0 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.68 +version: 1.7.68-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index a45a993832e..17fd83bcda7 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,10 +1,3 @@ -## 6.0.2 - -### Minor Analysis Improvements - -* Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime. -* C# 14: Added support for user-defined instance increment/decrement operators. - ## 6.0.1 No user-facing changes. diff --git a/csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md b/csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md new file mode 100644 index 00000000000..a840fdf4fe3 --- /dev/null +++ b/csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* C# 14: Added support for user-defined instance increment/decrement operators. diff --git a/csharp/ql/lib/change-notes/released/6.0.2.md b/csharp/ql/lib/change-notes/2026-05-20-csharp14-dotnet10.md similarity index 67% rename from csharp/ql/lib/change-notes/released/6.0.2.md rename to csharp/ql/lib/change-notes/2026-05-20-csharp14-dotnet10.md index ea98fb2257e..84e3833860a 100644 --- a/csharp/ql/lib/change-notes/released/6.0.2.md +++ b/csharp/ql/lib/change-notes/2026-05-20-csharp14-dotnet10.md @@ -1,6 +1,4 @@ -## 6.0.2 - -### Minor Analysis Improvements - +--- +category: minorAnalysis +--- * Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime. -* C# 14: Added support for user-defined instance increment/decrement operators. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 70437ec53b8..d1f3c68c812 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 6.0.2 +lastReleaseVersion: 6.0.1 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 0745dfdd527..b3a0dab7303 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 6.0.2 +version: 6.0.2-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 5c196df3614..8c4388fe2bb 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.7.4 - -No user-facing changes. - ## 1.7.3 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/1.7.4.md b/csharp/ql/src/change-notes/released/1.7.4.md deleted file mode 100644 index 801ed5f5e71..00000000000 --- a/csharp/ql/src/change-notes/released/1.7.4.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.7.4 - -No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index f4f3a4d5120..9f9661b1e77 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.4 +lastReleaseVersion: 1.7.3 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index d9269a9fd1b..bfb1852bacb 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.7.4 +version: 1.7.4-dev groups: - csharp - queries diff --git a/go/ql/consistency-queries/CHANGELOG.md b/go/ql/consistency-queries/CHANGELOG.md index 14258018aea..512a5732ccd 100644 --- a/go/ql/consistency-queries/CHANGELOG.md +++ b/go/ql/consistency-queries/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/go/ql/consistency-queries/change-notes/released/1.0.51.md b/go/ql/consistency-queries/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/go/ql/consistency-queries/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/go/ql/consistency-queries/codeql-pack.release.yml b/go/ql/consistency-queries/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/go/ql/consistency-queries/codeql-pack.release.yml +++ b/go/ql/consistency-queries/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index c07260f76da..4c65036e5cf 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.51 +version: 1.0.51-dev groups: - go - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 0d5738ad029..54afc3a977b 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,7 +1,3 @@ -## 7.1.2 - -No user-facing changes. - ## 7.1.1 No user-facing changes. diff --git a/go/ql/lib/change-notes/released/7.1.2.md b/go/ql/lib/change-notes/released/7.1.2.md deleted file mode 100644 index d55cf91e249..00000000000 --- a/go/ql/lib/change-notes/released/7.1.2.md +++ /dev/null @@ -1,3 +0,0 @@ -## 7.1.2 - -No user-facing changes. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 547681cc440..8e970df6cae 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.1.2 +lastReleaseVersion: 7.1.1 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 8a9a9624de5..f12cd33e5e0 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 7.1.2 +version: 7.1.2-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index c58883ee3c2..84d9ae7de59 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.6.4 - -No user-facing changes. - ## 1.6.3 No user-facing changes. diff --git a/go/ql/src/change-notes/released/1.6.4.md b/go/ql/src/change-notes/released/1.6.4.md deleted file mode 100644 index 5c811dc4638..00000000000 --- a/go/ql/src/change-notes/released/1.6.4.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.6.4 - -No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 1910e09d6a6..00b51441d88 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.4 +lastReleaseVersion: 1.6.3 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 601e81ea035..40ad8f32001 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.6.4 +version: 1.6.4-dev groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 2e702064d7f..a6c0cfc278a 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,9 +1,3 @@ -## 9.1.2 - -### Minor Analysis Improvements - -* Added LLM-generated source and sink models for `org.apache.avro`. - ## 9.1.1 ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/released/9.1.2.md b/java/ql/lib/change-notes/2026-05-19-avro-mads.md similarity index 61% rename from java/ql/lib/change-notes/released/9.1.2.md rename to java/ql/lib/change-notes/2026-05-19-avro-mads.md index c10b69f0fe9..43368b098b1 100644 --- a/java/ql/lib/change-notes/released/9.1.2.md +++ b/java/ql/lib/change-notes/2026-05-19-avro-mads.md @@ -1,5 +1,4 @@ -## 9.1.2 - -### Minor Analysis Improvements - +--- +category: minorAnalysis +--- * Added LLM-generated source and sink models for `org.apache.avro`. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 1fd7d868f4e..02e630d3384 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 9.1.2 +lastReleaseVersion: 9.1.1 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 561ef7db55c..aa9a2957362 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 9.1.2 +version: 9.1.2-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index e013e79ce9e..fbbc339797b 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.11.4 - -No user-facing changes. - ## 1.11.3 ### Minor Analysis Improvements diff --git a/java/ql/src/change-notes/released/1.11.4.md b/java/ql/src/change-notes/released/1.11.4.md deleted file mode 100644 index 3ebd37b0be7..00000000000 --- a/java/ql/src/change-notes/released/1.11.4.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.11.4 - -No user-facing changes. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 813a925461f..220561dc648 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.11.4 +lastReleaseVersion: 1.11.3 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index cfd8dbc56c8..2005542ba0d 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.11.4 +version: 1.11.4-dev groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 6471aa3fe68..c201b3a4b13 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,9 +1,3 @@ -## 2.7.2 - -### Minor Analysis Improvements - -* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `js/clear-text-logging`) may find more correct results and fewer false positive results after these changes. - ## 2.7.1 No user-facing changes. diff --git a/javascript/ql/lib/change-notes/released/2.7.2.md b/javascript/ql/lib/change-notes/2026-05-14-sensitive-data.md similarity index 89% rename from javascript/ql/lib/change-notes/released/2.7.2.md rename to javascript/ql/lib/change-notes/2026-05-14-sensitive-data.md index 9d0eca2cb4e..f6e6caed325 100644 --- a/javascript/ql/lib/change-notes/released/2.7.2.md +++ b/javascript/ql/lib/change-notes/2026-05-14-sensitive-data.md @@ -1,5 +1,4 @@ -## 2.7.2 - -### Minor Analysis Improvements - +--- +category: minorAnalysis +--- * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `js/clear-text-logging`) may find more correct results and fewer false positive results after these changes. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 5160df7b1b7..820fb65a5c7 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.7.2 +lastReleaseVersion: 2.7.1 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 6caebf91399..6e8e84b394d 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.7.2 +version: 2.7.2-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index b3a62befc5e..1a69291d145 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 2.3.11 - -No user-facing changes. - ## 2.3.10 No user-facing changes. diff --git a/javascript/ql/src/change-notes/released/2.3.11.md b/javascript/ql/src/change-notes/released/2.3.11.md deleted file mode 100644 index 31b11998b74..00000000000 --- a/javascript/ql/src/change-notes/released/2.3.11.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2.3.11 - -No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 5ac091006e8..a4a2f98d509 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.3.11 +lastReleaseVersion: 2.3.10 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 03a7153c05a..e58cb3d2d94 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 2.3.11 +version: 2.3.11-dev groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 8f96c9ba8dd..8e20945c6bf 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/1.0.51.md b/misc/suite-helpers/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/misc/suite-helpers/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index a6aeeb719fa..fd00605cfd1 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.51 +version: 1.0.51-dev groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 3efb4e57482..3d09821803b 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,9 +1,3 @@ -## 7.1.2 - -### Minor Analysis Improvements - -* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes. - ## 7.1.1 No user-facing changes. diff --git a/python/ql/lib/change-notes/released/7.1.2.md b/python/ql/lib/change-notes/2026-05-14-sensitive-data.md similarity index 90% rename from python/ql/lib/change-notes/released/7.1.2.md rename to python/ql/lib/change-notes/2026-05-14-sensitive-data.md index 523a14edfbe..49754de35ce 100644 --- a/python/ql/lib/change-notes/released/7.1.2.md +++ b/python/ql/lib/change-notes/2026-05-14-sensitive-data.md @@ -1,5 +1,4 @@ -## 7.1.2 - -### Minor Analysis Improvements - +--- +category: minorAnalysis +--- * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 547681cc440..8e970df6cae 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.1.2 +lastReleaseVersion: 7.1.1 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index a53a716fbf0..981ab78ff33 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 7.1.2 +version: 7.1.2-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 27698f1d3df..544b9778d4d 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.8.4 - -No user-facing changes. - ## 1.8.3 No user-facing changes. diff --git a/python/ql/src/change-notes/released/1.8.4.md b/python/ql/src/change-notes/released/1.8.4.md deleted file mode 100644 index 9aef6d10d1c..00000000000 --- a/python/ql/src/change-notes/released/1.8.4.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.8.4 - -No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index f2a60cd1327..8071ef421ab 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.8.4 +lastReleaseVersion: 1.8.3 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index afa318334b6..2fc026ff480 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.8.4 +version: 1.8.4-dev groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index d26bfa6f205..07859d0f0e6 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,7 +1,3 @@ -## 5.2.2 - -No user-facing changes. - ## 5.2.1 No user-facing changes. diff --git a/ruby/ql/lib/change-notes/released/5.2.2.md b/ruby/ql/lib/change-notes/released/5.2.2.md deleted file mode 100644 index 22402d6e8fa..00000000000 --- a/ruby/ql/lib/change-notes/released/5.2.2.md +++ /dev/null @@ -1,3 +0,0 @@ -## 5.2.2 - -No user-facing changes. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index e3b1b0c079d..1684d0e72a2 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.2.2 +lastReleaseVersion: 5.2.1 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index b36aada4770..df8efbe68de 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 5.2.2 +version: 5.2.2-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 384ca633202..c874059c151 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.6.4 - -No user-facing changes. - ## 1.6.3 No user-facing changes. diff --git a/ruby/ql/src/change-notes/released/1.6.4.md b/ruby/ql/src/change-notes/released/1.6.4.md deleted file mode 100644 index 5c811dc4638..00000000000 --- a/ruby/ql/src/change-notes/released/1.6.4.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.6.4 - -No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 1910e09d6a6..00b51441d88 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.4 +lastReleaseVersion: 1.6.3 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index e0c8c6b4c0c..b68d13e5908 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.6.4 +version: 1.6.4-dev groups: - ruby - queries diff --git a/rust/ql/lib/CHANGELOG.md b/rust/ql/lib/CHANGELOG.md index 3651026d737..d85d27d88d6 100644 --- a/rust/ql/lib/CHANGELOG.md +++ b/rust/ql/lib/CHANGELOG.md @@ -1,9 +1,3 @@ -## 0.2.15 - -### Minor Analysis Improvements - -* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `rust/cleartext-logging`) may find more correct results and fewer false positive results after these changes. - ## 0.2.14 No user-facing changes. diff --git a/rust/ql/lib/change-notes/released/0.2.15.md b/rust/ql/lib/change-notes/2026-05-14-sensitive-data.md similarity index 89% rename from rust/ql/lib/change-notes/released/0.2.15.md rename to rust/ql/lib/change-notes/2026-05-14-sensitive-data.md index 3644126ec1f..5aa6febd49b 100644 --- a/rust/ql/lib/change-notes/released/0.2.15.md +++ b/rust/ql/lib/change-notes/2026-05-14-sensitive-data.md @@ -1,5 +1,4 @@ -## 0.2.15 - -### Minor Analysis Improvements - +--- +category: minorAnalysis +--- * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `rust/cleartext-logging`) may find more correct results and fewer false positive results after these changes. diff --git a/rust/ql/lib/codeql-pack.release.yml b/rust/ql/lib/codeql-pack.release.yml index 0f574e080e4..c53820a76d5 100644 --- a/rust/ql/lib/codeql-pack.release.yml +++ b/rust/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.15 +lastReleaseVersion: 0.2.14 diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 49c4dddd4c6..062c2f4e635 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-all -version: 0.2.15 +version: 0.2.15-dev groups: rust extractor: rust dbscheme: rust.dbscheme diff --git a/rust/ql/src/CHANGELOG.md b/rust/ql/src/CHANGELOG.md index 4f4807ff82e..ad1e8ef3bfe 100644 --- a/rust/ql/src/CHANGELOG.md +++ b/rust/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 0.1.36 - -No user-facing changes. - ## 0.1.35 No user-facing changes. diff --git a/rust/ql/src/change-notes/released/0.1.36.md b/rust/ql/src/change-notes/released/0.1.36.md deleted file mode 100644 index 8685189c564..00000000000 --- a/rust/ql/src/change-notes/released/0.1.36.md +++ /dev/null @@ -1,3 +0,0 @@ -## 0.1.36 - -No user-facing changes. diff --git a/rust/ql/src/codeql-pack.release.yml b/rust/ql/src/codeql-pack.release.yml index 270bd27a7aa..6a5806eec2b 100644 --- a/rust/ql/src/codeql-pack.release.yml +++ b/rust/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.36 +lastReleaseVersion: 0.1.35 diff --git a/rust/ql/src/qlpack.yml b/rust/ql/src/qlpack.yml index 853aefb020d..67966540de6 100644 --- a/rust/ql/src/qlpack.yml +++ b/rust/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-queries -version: 0.1.36 +version: 0.1.36-dev groups: - rust - queries diff --git a/shared/concepts/CHANGELOG.md b/shared/concepts/CHANGELOG.md index 787779674f0..e2de2975455 100644 --- a/shared/concepts/CHANGELOG.md +++ b/shared/concepts/CHANGELOG.md @@ -1,7 +1,3 @@ -## 0.0.25 - -No user-facing changes. - ## 0.0.24 No user-facing changes. diff --git a/shared/concepts/change-notes/released/0.0.25.md b/shared/concepts/change-notes/released/0.0.25.md deleted file mode 100644 index e41a9acfa06..00000000000 --- a/shared/concepts/change-notes/released/0.0.25.md +++ /dev/null @@ -1,3 +0,0 @@ -## 0.0.25 - -No user-facing changes. diff --git a/shared/concepts/codeql-pack.release.yml b/shared/concepts/codeql-pack.release.yml index 6d0e80a50c3..b956773a07f 100644 --- a/shared/concepts/codeql-pack.release.yml +++ b/shared/concepts/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.25 +lastReleaseVersion: 0.0.24 diff --git a/shared/concepts/qlpack.yml b/shared/concepts/qlpack.yml index 98ae75ca6ca..c51537b2228 100644 --- a/shared/concepts/qlpack.yml +++ b/shared/concepts/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/concepts -version: 0.0.25 +version: 0.0.25-dev groups: shared library: true dependencies: diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index 8ac7faf2554..dc02f115c99 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,7 +1,3 @@ -## 2.0.35 - -No user-facing changes. - ## 2.0.34 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/2.0.35.md b/shared/controlflow/change-notes/released/2.0.35.md deleted file mode 100644 index 526e1fc9f4c..00000000000 --- a/shared/controlflow/change-notes/released/2.0.35.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2.0.35 - -No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index 27eb8ef8ece..339a3ce7c57 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.35 +lastReleaseVersion: 2.0.34 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index a28d74ae749..e33617ca4f0 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 2.0.35 +version: 2.0.35-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index b2cf75110ac..7ecbeda3b21 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,7 +1,3 @@ -## 2.1.7 - -No user-facing changes. - ## 2.1.6 No user-facing changes. diff --git a/shared/dataflow/change-notes/released/2.1.7.md b/shared/dataflow/change-notes/released/2.1.7.md deleted file mode 100644 index af7772169fe..00000000000 --- a/shared/dataflow/change-notes/released/2.1.7.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2.1.7 - -No user-facing changes. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index cfa57a47251..1c810b60c4a 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.1.7 +lastReleaseVersion: 2.1.6 diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 6564305a246..2058b35be64 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 2.1.7 +version: 2.1.7-dev groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index 6619a18079c..964c1bb1d98 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/shared/mad/change-notes/released/1.0.51.md b/shared/mad/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/shared/mad/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index c8d8eb47b4a..fb135546a90 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.51 +version: 1.0.51-dev groups: shared library: true dependencies: diff --git a/shared/quantum/CHANGELOG.md b/shared/quantum/CHANGELOG.md index c8b656e4f35..7153b9314b1 100644 --- a/shared/quantum/CHANGELOG.md +++ b/shared/quantum/CHANGELOG.md @@ -1,7 +1,3 @@ -## 0.0.29 - -No user-facing changes. - ## 0.0.28 No user-facing changes. diff --git a/shared/quantum/change-notes/released/0.0.29.md b/shared/quantum/change-notes/released/0.0.29.md deleted file mode 100644 index 4428927c79d..00000000000 --- a/shared/quantum/change-notes/released/0.0.29.md +++ /dev/null @@ -1,3 +0,0 @@ -## 0.0.29 - -No user-facing changes. diff --git a/shared/quantum/codeql-pack.release.yml b/shared/quantum/codeql-pack.release.yml index c81f1813120..3462db7d348 100644 --- a/shared/quantum/codeql-pack.release.yml +++ b/shared/quantum/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.29 +lastReleaseVersion: 0.0.28 diff --git a/shared/quantum/qlpack.yml b/shared/quantum/qlpack.yml index a8d3a71823b..951cce392ae 100644 --- a/shared/quantum/qlpack.yml +++ b/shared/quantum/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/quantum -version: 0.0.29 +version: 0.0.29-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/CHANGELOG.md b/shared/rangeanalysis/CHANGELOG.md index a400a91f8c9..e2a893046c9 100644 --- a/shared/rangeanalysis/CHANGELOG.md +++ b/shared/rangeanalysis/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/shared/rangeanalysis/change-notes/released/1.0.51.md b/shared/rangeanalysis/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/shared/rangeanalysis/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/shared/rangeanalysis/codeql-pack.release.yml b/shared/rangeanalysis/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/shared/rangeanalysis/codeql-pack.release.yml +++ b/shared/rangeanalysis/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index 5ea1c83b182..41f319731b0 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.51 +version: 1.0.51-dev groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index c4b7fc6e87f..bb83dfc0a1f 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/shared/regex/change-notes/released/1.0.51.md b/shared/regex/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/shared/regex/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 3c01106e9b8..198bf43da04 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.51 +version: 1.0.51-dev groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 9cfe68398b2..f9145f2c88b 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,7 +1,3 @@ -## 2.0.27 - -No user-facing changes. - ## 2.0.26 No user-facing changes. diff --git a/shared/ssa/change-notes/released/2.0.27.md b/shared/ssa/change-notes/released/2.0.27.md deleted file mode 100644 index 639cf77090e..00000000000 --- a/shared/ssa/change-notes/released/2.0.27.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2.0.27 - -No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index a047558f018..63d57bef481 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.27 +lastReleaseVersion: 2.0.26 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index c10e0892660..5f8de945745 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 2.0.27 +version: 2.0.27-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/CHANGELOG.md b/shared/threat-models/CHANGELOG.md index 14258018aea..512a5732ccd 100644 --- a/shared/threat-models/CHANGELOG.md +++ b/shared/threat-models/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/shared/threat-models/change-notes/released/1.0.51.md b/shared/threat-models/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/shared/threat-models/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/shared/threat-models/codeql-pack.release.yml b/shared/threat-models/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/shared/threat-models/codeql-pack.release.yml +++ b/shared/threat-models/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 855242656c8..c3ac3656b3a 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.51 +version: 1.0.51-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index 9e78286a1a4..c98a035d149 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/1.0.51.md b/shared/tutorial/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/shared/tutorial/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 39bfd9cc21d..e68fe7948ff 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.51 +version: 1.0.51-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/CHANGELOG.md b/shared/typeflow/CHANGELOG.md index e9334c9da8d..de43834a84e 100644 --- a/shared/typeflow/CHANGELOG.md +++ b/shared/typeflow/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/shared/typeflow/change-notes/released/1.0.51.md b/shared/typeflow/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/shared/typeflow/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/shared/typeflow/codeql-pack.release.yml b/shared/typeflow/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/shared/typeflow/codeql-pack.release.yml +++ b/shared/typeflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index f06ea443f79..482138349ac 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.51 +version: 1.0.51-dev groups: shared library: true dependencies: diff --git a/shared/typeinference/CHANGELOG.md b/shared/typeinference/CHANGELOG.md index 24dc81f3aa2..3bbb96e59a9 100644 --- a/shared/typeinference/CHANGELOG.md +++ b/shared/typeinference/CHANGELOG.md @@ -1,7 +1,3 @@ -## 0.0.32 - -No user-facing changes. - ## 0.0.31 No user-facing changes. diff --git a/shared/typeinference/change-notes/released/0.0.32.md b/shared/typeinference/change-notes/released/0.0.32.md deleted file mode 100644 index c390443f09a..00000000000 --- a/shared/typeinference/change-notes/released/0.0.32.md +++ /dev/null @@ -1,3 +0,0 @@ -## 0.0.32 - -No user-facing changes. diff --git a/shared/typeinference/codeql-pack.release.yml b/shared/typeinference/codeql-pack.release.yml index 714fcfc1828..54b504d06ec 100644 --- a/shared/typeinference/codeql-pack.release.yml +++ b/shared/typeinference/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.32 +lastReleaseVersion: 0.0.31 diff --git a/shared/typeinference/qlpack.yml b/shared/typeinference/qlpack.yml index ece5dd3b6e8..d7dbeae2e09 100644 --- a/shared/typeinference/qlpack.yml +++ b/shared/typeinference/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeinference -version: 0.0.32 +version: 0.0.32-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index e9b5492b0d8..313862d5bc7 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,7 +1,3 @@ -## 2.0.35 - -No user-facing changes. - ## 2.0.34 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/2.0.35.md b/shared/typetracking/change-notes/released/2.0.35.md deleted file mode 100644 index 526e1fc9f4c..00000000000 --- a/shared/typetracking/change-notes/released/2.0.35.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2.0.35 - -No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index 27eb8ef8ece..339a3ce7c57 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.35 +lastReleaseVersion: 2.0.34 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index bd874407aff..891f8d0b1b1 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 2.0.35 +version: 2.0.35-dev groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index dbafbea9b98..5838cd3c535 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/shared/typos/change-notes/released/1.0.51.md b/shared/typos/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/shared/typos/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 9a2ed996444..b4705122b0a 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.51 +version: 1.0.51-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index df741ed9d73..24a4f7d09a2 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,7 +1,3 @@ -## 2.0.38 - -No user-facing changes. - ## 2.0.37 No user-facing changes. diff --git a/shared/util/change-notes/released/2.0.38.md b/shared/util/change-notes/released/2.0.38.md deleted file mode 100644 index 0fab2ede165..00000000000 --- a/shared/util/change-notes/released/2.0.38.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2.0.38 - -No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index 4ec9eb0980c..108259a7400 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.38 +lastReleaseVersion: 2.0.37 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index dc654fca261..6190a3b4275 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.38 +version: 2.0.38-dev groups: shared library: true dependencies: null diff --git a/shared/xml/CHANGELOG.md b/shared/xml/CHANGELOG.md index 685a8032d64..96dfbcadf56 100644 --- a/shared/xml/CHANGELOG.md +++ b/shared/xml/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/shared/xml/change-notes/released/1.0.51.md b/shared/xml/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/shared/xml/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/shared/xml/codeql-pack.release.yml b/shared/xml/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/shared/xml/codeql-pack.release.yml +++ b/shared/xml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index 40cf2695728..c8e51461dae 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.51 +version: 1.0.51-dev groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 4f57ee07cfa..e006acbeb21 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.0.51 - -No user-facing changes. - ## 1.0.50 No user-facing changes. diff --git a/shared/yaml/change-notes/released/1.0.51.md b/shared/yaml/change-notes/released/1.0.51.md deleted file mode 100644 index b96d48b8822..00000000000 --- a/shared/yaml/change-notes/released/1.0.51.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.51 - -No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index 232dbe38ec8..856137cc5db 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.51 +lastReleaseVersion: 1.0.50 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 0b4fd245f3b..c499501ab26 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.51 +version: 1.0.51-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index 1eb5afb48e7..01461fd5bfe 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,13 +1,3 @@ -## 6.7.0 - -### Major Analysis Improvements - -* Upgraded to allow analysis of Swift 6.3.2. - -### Minor Analysis Improvements - -* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `swift/cleartext-logging`) may find more correct results and fewer false positive results after these changes. - ## 6.6.0 ### New Features diff --git a/swift/ql/lib/change-notes/released/6.7.0.md b/swift/ql/lib/change-notes/2026-05-14-sensitive-data.md similarity index 76% rename from swift/ql/lib/change-notes/released/6.7.0.md rename to swift/ql/lib/change-notes/2026-05-14-sensitive-data.md index 8d7bf41cc1d..70e96a3469c 100644 --- a/swift/ql/lib/change-notes/released/6.7.0.md +++ b/swift/ql/lib/change-notes/2026-05-14-sensitive-data.md @@ -1,9 +1,4 @@ -## 6.7.0 - -### Major Analysis Improvements - -* Upgraded to allow analysis of Swift 6.3.2. - -### Minor Analysis Improvements - +--- +category: minorAnalysis +--- * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `swift/cleartext-logging`) may find more correct results and fewer false positive results after these changes. diff --git a/swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md b/swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md new file mode 100644 index 00000000000..530b7187e7a --- /dev/null +++ b/swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* Upgraded to allow analysis of Swift 6.3.2. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 55a13d309e5..4d7f31f2d8e 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 6.7.0 +lastReleaseVersion: 6.6.0 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index f62f77afa0e..5e2f7c2942d 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 6.7.0 +version: 6.6.1-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index 4e3b53c37b3..4bd8088718a 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,7 +1,3 @@ -## 1.3.4 - -No user-facing changes. - ## 1.3.3 No user-facing changes. diff --git a/swift/ql/src/change-notes/released/1.3.4.md b/swift/ql/src/change-notes/released/1.3.4.md deleted file mode 100644 index 5073aca7222..00000000000 --- a/swift/ql/src/change-notes/released/1.3.4.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.3.4 - -No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index 8263ddf2c8b..eb1f7dabc84 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.4 +lastReleaseVersion: 1.3.3 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 05710b29874..da4df6ae6d9 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.3.4 +version: 1.3.4-dev groups: - swift - queries From 8b6f969cdb9b1a09ce4379ccadad1e2c9ca46677 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 29 May 2026 11:27:54 +0000 Subject: [PATCH 148/226] Release preparation for version 2.25.6 --- actions/ql/lib/CHANGELOG.md | 6 ++++++ .../0.4.37.md} | 9 +++++---- actions/ql/lib/codeql-pack.release.yml | 2 +- actions/ql/lib/qlpack.yml | 2 +- actions/ql/src/CHANGELOG.md | 19 +++++++++++++++++++ .../2026-05-05-untrusted-checkout-high.md | 4 ---- .../2026-05-12-sha256-pinned-actions.md | 4 ---- ...n-untrusted-checkout-improvements-alert.md | 4 ---- ...ntrusted-checkout-improvements-helpfile.md | 4 ---- ...ntrusted-checkout-improvements-metadata.md | 4 ---- .../ql/src/change-notes/released/0.6.29.md | 18 ++++++++++++++++++ actions/ql/src/codeql-pack.release.yml | 2 +- actions/ql/src/qlpack.yml | 2 +- cpp/ql/lib/CHANGELOG.md | 16 ++++++++++++++++ .../change-notes/2026-05-15-secure-scanf.md | 5 ----- .../change-notes/2026-05-16-alias-template.md | 4 ---- .../lib/change-notes/2026-05-18-alias-type.md | 4 ---- .../change-notes/2026-05-21-generated-from.md | 4 ---- cpp/ql/lib/change-notes/released/10.2.0.md | 15 +++++++++++++++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 4 ++++ cpp/ql/src/change-notes/released/1.6.4.md | 3 +++ cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++++ .../lib/change-notes/released/1.7.68.md | 3 +++ .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- .../ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++++ .../src/change-notes/released/1.7.68.md | 3 +++ .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 7 +++++++ .../2026-05-12-user-increment-decrement.md | 4 ---- .../6.0.2.md} | 8 +++++--- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 4 ++++ csharp/ql/src/change-notes/released/1.7.4.md | 3 +++ csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.51.md | 3 +++ .../codeql-pack.release.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 4 ++++ go/ql/lib/change-notes/released/7.1.2.md | 3 +++ go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ++++ go/ql/src/change-notes/released/1.6.4.md | 3 +++ go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 6 ++++++ .../9.1.2.md} | 7 ++++--- java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 4 ++++ java/ql/src/change-notes/released/1.11.4.md | 3 +++ java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 6 ++++++ .../2.7.2.md} | 7 ++++--- javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 4 ++++ .../ql/src/change-notes/released/2.3.11.md | 3 +++ javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.51.md | 3 +++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 6 ++++++ .../7.1.2.md} | 7 ++++--- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ++++ python/ql/src/change-notes/released/1.8.4.md | 3 +++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 4 ++++ ruby/ql/lib/change-notes/released/5.2.2.md | 3 +++ ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ++++ ruby/ql/src/change-notes/released/1.6.4.md | 3 +++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- rust/ql/lib/CHANGELOG.md | 6 ++++++ .../0.2.15.md} | 7 ++++--- rust/ql/lib/codeql-pack.release.yml | 2 +- rust/ql/lib/qlpack.yml | 2 +- rust/ql/src/CHANGELOG.md | 4 ++++ rust/ql/src/change-notes/released/0.1.36.md | 3 +++ rust/ql/src/codeql-pack.release.yml | 2 +- rust/ql/src/qlpack.yml | 2 +- shared/concepts/CHANGELOG.md | 4 ++++ .../concepts/change-notes/released/0.0.25.md | 3 +++ shared/concepts/codeql-pack.release.yml | 2 +- shared/concepts/qlpack.yml | 2 +- shared/controlflow/CHANGELOG.md | 4 ++++ .../change-notes/released/2.0.35.md | 3 +++ shared/controlflow/codeql-pack.release.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/CHANGELOG.md | 4 ++++ .../dataflow/change-notes/released/2.1.7.md | 3 +++ shared/dataflow/codeql-pack.release.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/CHANGELOG.md | 4 ++++ shared/mad/change-notes/released/1.0.51.md | 3 +++ shared/mad/codeql-pack.release.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/quantum/CHANGELOG.md | 4 ++++ .../quantum/change-notes/released/0.0.29.md | 3 +++ shared/quantum/codeql-pack.release.yml | 2 +- shared/quantum/qlpack.yml | 2 +- shared/rangeanalysis/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.51.md | 3 +++ shared/rangeanalysis/codeql-pack.release.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ++++ shared/regex/change-notes/released/1.0.51.md | 3 +++ shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++++ shared/ssa/change-notes/released/2.0.27.md | 3 +++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/CHANGELOG.md | 4 ++++ .../change-notes/released/1.0.51.md | 3 +++ shared/threat-models/codeql-pack.release.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ++++ .../tutorial/change-notes/released/1.0.51.md | 3 +++ shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/CHANGELOG.md | 4 ++++ .../typeflow/change-notes/released/1.0.51.md | 3 +++ shared/typeflow/codeql-pack.release.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typeinference/CHANGELOG.md | 4 ++++ .../change-notes/released/0.0.32.md | 3 +++ shared/typeinference/codeql-pack.release.yml | 2 +- shared/typeinference/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ++++ .../change-notes/released/2.0.35.md | 3 +++ shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++++ shared/typos/change-notes/released/1.0.51.md | 3 +++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 4 ++++ shared/util/change-notes/released/2.0.38.md | 3 +++ shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/CHANGELOG.md | 4 ++++ shared/xml/change-notes/released/1.0.51.md | 3 +++ shared/xml/codeql-pack.release.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ++++ shared/yaml/change-notes/released/1.0.51.md | 3 +++ shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/CHANGELOG.md | 10 ++++++++++ .../change-notes/2026-05-19-swift-6.3.2.md | 4 ---- .../6.7.0.md} | 11 ++++++++--- swift/ql/lib/codeql-pack.release.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/CHANGELOG.md | 4 ++++ swift/ql/src/change-notes/released/1.3.4.md | 3 +++ swift/ql/src/codeql-pack.release.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 175 files changed, 455 insertions(+), 149 deletions(-) rename actions/ql/lib/change-notes/{2026-05-12-improved-alphanumeric-regex.md => released/0.4.37.md} (80%) delete mode 100644 actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md delete mode 100644 actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md delete mode 100644 actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md delete mode 100644 actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md delete mode 100644 actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md create mode 100644 actions/ql/src/change-notes/released/0.6.29.md delete mode 100644 cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md delete mode 100644 cpp/ql/lib/change-notes/2026-05-16-alias-template.md delete mode 100644 cpp/ql/lib/change-notes/2026-05-18-alias-type.md delete mode 100644 cpp/ql/lib/change-notes/2026-05-21-generated-from.md create mode 100644 cpp/ql/lib/change-notes/released/10.2.0.md create mode 100644 cpp/ql/src/change-notes/released/1.6.4.md create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md delete mode 100644 csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md rename csharp/ql/lib/change-notes/{2026-05-20-csharp14-dotnet10.md => released/6.0.2.md} (67%) create mode 100644 csharp/ql/src/change-notes/released/1.7.4.md create mode 100644 go/ql/consistency-queries/change-notes/released/1.0.51.md create mode 100644 go/ql/lib/change-notes/released/7.1.2.md create mode 100644 go/ql/src/change-notes/released/1.6.4.md rename java/ql/lib/change-notes/{2026-05-19-avro-mads.md => released/9.1.2.md} (61%) create mode 100644 java/ql/src/change-notes/released/1.11.4.md rename javascript/ql/lib/change-notes/{2026-05-14-sensitive-data.md => released/2.7.2.md} (89%) create mode 100644 javascript/ql/src/change-notes/released/2.3.11.md create mode 100644 misc/suite-helpers/change-notes/released/1.0.51.md rename python/ql/lib/change-notes/{2026-05-14-sensitive-data.md => released/7.1.2.md} (90%) create mode 100644 python/ql/src/change-notes/released/1.8.4.md create mode 100644 ruby/ql/lib/change-notes/released/5.2.2.md create mode 100644 ruby/ql/src/change-notes/released/1.6.4.md rename rust/ql/lib/change-notes/{2026-05-14-sensitive-data.md => released/0.2.15.md} (89%) create mode 100644 rust/ql/src/change-notes/released/0.1.36.md create mode 100644 shared/concepts/change-notes/released/0.0.25.md create mode 100644 shared/controlflow/change-notes/released/2.0.35.md create mode 100644 shared/dataflow/change-notes/released/2.1.7.md create mode 100644 shared/mad/change-notes/released/1.0.51.md create mode 100644 shared/quantum/change-notes/released/0.0.29.md create mode 100644 shared/rangeanalysis/change-notes/released/1.0.51.md create mode 100644 shared/regex/change-notes/released/1.0.51.md create mode 100644 shared/ssa/change-notes/released/2.0.27.md create mode 100644 shared/threat-models/change-notes/released/1.0.51.md create mode 100644 shared/tutorial/change-notes/released/1.0.51.md create mode 100644 shared/typeflow/change-notes/released/1.0.51.md create mode 100644 shared/typeinference/change-notes/released/0.0.32.md create mode 100644 shared/typetracking/change-notes/released/2.0.35.md create mode 100644 shared/typos/change-notes/released/1.0.51.md create mode 100644 shared/util/change-notes/released/2.0.38.md create mode 100644 shared/xml/change-notes/released/1.0.51.md create mode 100644 shared/yaml/change-notes/released/1.0.51.md delete mode 100644 swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md rename swift/ql/lib/change-notes/{2026-05-14-sensitive-data.md => released/6.7.0.md} (76%) create mode 100644 swift/ql/src/change-notes/released/1.3.4.md diff --git a/actions/ql/lib/CHANGELOG.md b/actions/ql/lib/CHANGELOG.md index ddd0b0f1aec..7a61a60c379 100644 --- a/actions/ql/lib/CHANGELOG.md +++ b/actions/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.37 + +### Minor Analysis Improvements + +* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. + ## 0.4.36 ### Minor Analysis Improvements diff --git a/actions/ql/lib/change-notes/2026-05-12-improved-alphanumeric-regex.md b/actions/ql/lib/change-notes/released/0.4.37.md similarity index 80% rename from actions/ql/lib/change-notes/2026-05-12-improved-alphanumeric-regex.md rename to actions/ql/lib/change-notes/released/0.4.37.md index df3aaf3613f..4809796b3ab 100644 --- a/actions/ql/lib/change-notes/2026-05-12-improved-alphanumeric-regex.md +++ b/actions/ql/lib/change-notes/released/0.4.37.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- -* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. \ No newline at end of file +## 0.4.37 + +### Minor Analysis Improvements + +* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. diff --git a/actions/ql/lib/codeql-pack.release.yml b/actions/ql/lib/codeql-pack.release.yml index 45433e3ec03..df274514780 100644 --- a/actions/ql/lib/codeql-pack.release.yml +++ b/actions/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.36 +lastReleaseVersion: 0.4.37 diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml index ae4a57aa944..71c9cadbf28 100644 --- a/actions/ql/lib/qlpack.yml +++ b/actions/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-all -version: 0.4.37-dev +version: 0.4.37 library: true warnOnImplicitThis: true dependencies: diff --git a/actions/ql/src/CHANGELOG.md b/actions/ql/src/CHANGELOG.md index 1670f0af5be..c37cd20761b 100644 --- a/actions/ql/src/CHANGELOG.md +++ b/actions/ql/src/CHANGELOG.md @@ -1,3 +1,22 @@ +## 0.6.29 + +### Query Metadata Changes + +* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`. + +### Major Analysis Improvements + +* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. + +### Minor Analysis Improvements + +* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`. +* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. + +### Bug Fixes + +* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. + ## 0.6.28 ### Query Metadata Changes diff --git a/actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md b/actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md deleted file mode 100644 index 098c60a3753..00000000000 --- a/actions/ql/src/change-notes/2026-05-05-untrusted-checkout-high.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. \ No newline at end of file diff --git a/actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md b/actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md deleted file mode 100644 index 521a5878c37..00000000000 --- a/actions/ql/src/change-notes/2026-05-12-sha256-pinned-actions.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. diff --git a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md deleted file mode 100644 index f5ad3271a62..00000000000 --- a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-alert.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`. \ No newline at end of file diff --git a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md deleted file mode 100644 index 83e6528c86b..00000000000 --- a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-helpfile.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: fix ---- -* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. \ No newline at end of file diff --git a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md b/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md deleted file mode 100644 index 5df1f3347ea..00000000000 --- a/actions/ql/src/change-notes/2026-05-14-further-iteration-untrusted-checkout-improvements-metadata.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: queryMetadata ---- -* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`. \ No newline at end of file diff --git a/actions/ql/src/change-notes/released/0.6.29.md b/actions/ql/src/change-notes/released/0.6.29.md new file mode 100644 index 00000000000..82ca8174954 --- /dev/null +++ b/actions/ql/src/change-notes/released/0.6.29.md @@ -0,0 +1,18 @@ +## 0.6.29 + +### Query Metadata Changes + +* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`. + +### Major Analysis Improvements + +* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. + +### Minor Analysis Improvements + +* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`. +* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. + +### Bug Fixes + +* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. diff --git a/actions/ql/src/codeql-pack.release.yml b/actions/ql/src/codeql-pack.release.yml index 90f3f09295a..e785984cacc 100644 --- a/actions/ql/src/codeql-pack.release.yml +++ b/actions/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.28 +lastReleaseVersion: 0.6.29 diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml index 33ab175fb18..3615c08b583 100644 --- a/actions/ql/src/qlpack.yml +++ b/actions/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-queries -version: 0.6.29-dev +version: 0.6.29 library: false warnOnImplicitThis: true groups: [actions, queries] diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 3b95c10fbb5..0b3413f9d3c 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,19 @@ +## 10.2.0 + +### Deprecated APIs + +* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead. + +### New Features + +* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. +* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. + +### Minor Analysis Improvements + +* Added flow source models for `scanf_s` and related functions. +* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported. + ## 10.1.1 ### Minor Analysis Improvements diff --git a/cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md b/cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md deleted file mode 100644 index 0b8d5a79a72..00000000000 --- a/cpp/ql/lib/change-notes/2026-05-15-secure-scanf.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* Added flow source models for `scanf_s` and related functions. -* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2026-05-16-alias-template.md b/cpp/ql/lib/change-notes/2026-05-16-alias-template.md deleted file mode 100644 index 2777da94abf..00000000000 --- a/cpp/ql/lib/change-notes/2026-05-16-alias-template.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. diff --git a/cpp/ql/lib/change-notes/2026-05-18-alias-type.md b/cpp/ql/lib/change-notes/2026-05-18-alias-type.md deleted file mode 100644 index b744dd2fa95..00000000000 --- a/cpp/ql/lib/change-notes/2026-05-18-alias-type.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: deprecated ---- -* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead. diff --git a/cpp/ql/lib/change-notes/2026-05-21-generated-from.md b/cpp/ql/lib/change-notes/2026-05-21-generated-from.md deleted file mode 100644 index bf3ddcb1070..00000000000 --- a/cpp/ql/lib/change-notes/2026-05-21-generated-from.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. diff --git a/cpp/ql/lib/change-notes/released/10.2.0.md b/cpp/ql/lib/change-notes/released/10.2.0.md new file mode 100644 index 00000000000..cb514b82cbb --- /dev/null +++ b/cpp/ql/lib/change-notes/released/10.2.0.md @@ -0,0 +1,15 @@ +## 10.2.0 + +### Deprecated APIs + +* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead. + +### New Features + +* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. +* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. + +### Minor Analysis Improvements + +* Added flow source models for `scanf_s` and related functions. +* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 940a668bbf3..a230efed2a4 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 10.1.1 +lastReleaseVersion: 10.2.0 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index bca102a1048..04ee2d76ae9 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 10.1.2-dev +version: 10.2.0 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 901d2092283..e8a2af1383c 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.4 + +No user-facing changes. + ## 1.6.3 ### Minor Analysis Improvements diff --git a/cpp/ql/src/change-notes/released/1.6.4.md b/cpp/ql/src/change-notes/released/1.6.4.md new file mode 100644 index 00000000000..5c811dc4638 --- /dev/null +++ b/cpp/ql/src/change-notes/released/1.6.4.md @@ -0,0 +1,3 @@ +## 1.6.4 + +No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 00b51441d88..1910e09d6a6 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.3 +lastReleaseVersion: 1.6.4 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 74055b4cf11..4915f969278 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.6.4-dev +version: 1.6.4 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index eefb35f174a..3ceb4374a77 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.68 + +No user-facing changes. + ## 1.7.67 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md new file mode 100644 index 00000000000..774ffcebdfe --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.68.md @@ -0,0 +1,3 @@ +## 1.7.68 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 0293fdade8f..f737dfa0972 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.67 +lastReleaseVersion: 1.7.68 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 659dd5b0038..1de44f9e1d8 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.68-dev +version: 1.7.68 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index eefb35f174a..3ceb4374a77 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.68 + +No user-facing changes. + ## 1.7.67 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md new file mode 100644 index 00000000000..774ffcebdfe --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.68.md @@ -0,0 +1,3 @@ +## 1.7.68 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 0293fdade8f..f737dfa0972 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.67 +lastReleaseVersion: 1.7.68 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index c7f243d86f0..e99c5a26b32 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.68-dev +version: 1.7.68 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 17fd83bcda7..a45a993832e 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 6.0.2 + +### Minor Analysis Improvements + +* Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime. +* C# 14: Added support for user-defined instance increment/decrement operators. + ## 6.0.1 No user-facing changes. diff --git a/csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md b/csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md deleted file mode 100644 index a840fdf4fe3..00000000000 --- a/csharp/ql/lib/change-notes/2026-05-12-user-increment-decrement.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* C# 14: Added support for user-defined instance increment/decrement operators. diff --git a/csharp/ql/lib/change-notes/2026-05-20-csharp14-dotnet10.md b/csharp/ql/lib/change-notes/released/6.0.2.md similarity index 67% rename from csharp/ql/lib/change-notes/2026-05-20-csharp14-dotnet10.md rename to csharp/ql/lib/change-notes/released/6.0.2.md index 84e3833860a..ea98fb2257e 100644 --- a/csharp/ql/lib/change-notes/2026-05-20-csharp14-dotnet10.md +++ b/csharp/ql/lib/change-notes/released/6.0.2.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 6.0.2 + +### Minor Analysis Improvements + * Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime. +* C# 14: Added support for user-defined instance increment/decrement operators. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index d1f3c68c812..70437ec53b8 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 6.0.1 +lastReleaseVersion: 6.0.2 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index b3a0dab7303..0745dfdd527 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 6.0.2-dev +version: 6.0.2 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 8c4388fe2bb..5c196df3614 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.4 + +No user-facing changes. + ## 1.7.3 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/1.7.4.md b/csharp/ql/src/change-notes/released/1.7.4.md new file mode 100644 index 00000000000..801ed5f5e71 --- /dev/null +++ b/csharp/ql/src/change-notes/released/1.7.4.md @@ -0,0 +1,3 @@ +## 1.7.4 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 9f9661b1e77..f4f3a4d5120 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.3 +lastReleaseVersion: 1.7.4 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index bfb1852bacb..d9269a9fd1b 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.7.4-dev +version: 1.7.4 groups: - csharp - queries diff --git a/go/ql/consistency-queries/CHANGELOG.md b/go/ql/consistency-queries/CHANGELOG.md index 512a5732ccd..14258018aea 100644 --- a/go/ql/consistency-queries/CHANGELOG.md +++ b/go/ql/consistency-queries/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/go/ql/consistency-queries/change-notes/released/1.0.51.md b/go/ql/consistency-queries/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/go/ql/consistency-queries/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/go/ql/consistency-queries/codeql-pack.release.yml b/go/ql/consistency-queries/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/go/ql/consistency-queries/codeql-pack.release.yml +++ b/go/ql/consistency-queries/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 4c65036e5cf..c07260f76da 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.51-dev +version: 1.0.51 groups: - go - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 54afc3a977b..0d5738ad029 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 7.1.2 + +No user-facing changes. + ## 7.1.1 No user-facing changes. diff --git a/go/ql/lib/change-notes/released/7.1.2.md b/go/ql/lib/change-notes/released/7.1.2.md new file mode 100644 index 00000000000..d55cf91e249 --- /dev/null +++ b/go/ql/lib/change-notes/released/7.1.2.md @@ -0,0 +1,3 @@ +## 7.1.2 + +No user-facing changes. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 8e970df6cae..547681cc440 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.1.1 +lastReleaseVersion: 7.1.2 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index f12cd33e5e0..8a9a9624de5 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 7.1.2-dev +version: 7.1.2 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 84d9ae7de59..c58883ee3c2 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.4 + +No user-facing changes. + ## 1.6.3 No user-facing changes. diff --git a/go/ql/src/change-notes/released/1.6.4.md b/go/ql/src/change-notes/released/1.6.4.md new file mode 100644 index 00000000000..5c811dc4638 --- /dev/null +++ b/go/ql/src/change-notes/released/1.6.4.md @@ -0,0 +1,3 @@ +## 1.6.4 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 00b51441d88..1910e09d6a6 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.3 +lastReleaseVersion: 1.6.4 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 40ad8f32001..601e81ea035 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.6.4-dev +version: 1.6.4 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index a6c0cfc278a..2e702064d7f 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 9.1.2 + +### Minor Analysis Improvements + +* Added LLM-generated source and sink models for `org.apache.avro`. + ## 9.1.1 ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/2026-05-19-avro-mads.md b/java/ql/lib/change-notes/released/9.1.2.md similarity index 61% rename from java/ql/lib/change-notes/2026-05-19-avro-mads.md rename to java/ql/lib/change-notes/released/9.1.2.md index 43368b098b1..c10b69f0fe9 100644 --- a/java/ql/lib/change-notes/2026-05-19-avro-mads.md +++ b/java/ql/lib/change-notes/released/9.1.2.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 9.1.2 + +### Minor Analysis Improvements + * Added LLM-generated source and sink models for `org.apache.avro`. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 02e630d3384..1fd7d868f4e 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 9.1.1 +lastReleaseVersion: 9.1.2 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index aa9a2957362..561ef7db55c 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 9.1.2-dev +version: 9.1.2 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index fbbc339797b..e013e79ce9e 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.11.4 + +No user-facing changes. + ## 1.11.3 ### Minor Analysis Improvements diff --git a/java/ql/src/change-notes/released/1.11.4.md b/java/ql/src/change-notes/released/1.11.4.md new file mode 100644 index 00000000000..3ebd37b0be7 --- /dev/null +++ b/java/ql/src/change-notes/released/1.11.4.md @@ -0,0 +1,3 @@ +## 1.11.4 + +No user-facing changes. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 220561dc648..813a925461f 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.11.3 +lastReleaseVersion: 1.11.4 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 2005542ba0d..cfd8dbc56c8 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.11.4-dev +version: 1.11.4 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index c201b3a4b13..6471aa3fe68 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.7.2 + +### Minor Analysis Improvements + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `js/clear-text-logging`) may find more correct results and fewer false positive results after these changes. + ## 2.7.1 No user-facing changes. diff --git a/javascript/ql/lib/change-notes/2026-05-14-sensitive-data.md b/javascript/ql/lib/change-notes/released/2.7.2.md similarity index 89% rename from javascript/ql/lib/change-notes/2026-05-14-sensitive-data.md rename to javascript/ql/lib/change-notes/released/2.7.2.md index f6e6caed325..9d0eca2cb4e 100644 --- a/javascript/ql/lib/change-notes/2026-05-14-sensitive-data.md +++ b/javascript/ql/lib/change-notes/released/2.7.2.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 2.7.2 + +### Minor Analysis Improvements + * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `js/clear-text-logging`) may find more correct results and fewer false positive results after these changes. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 820fb65a5c7..5160df7b1b7 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.7.1 +lastReleaseVersion: 2.7.2 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 6e8e84b394d..6caebf91399 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.7.2-dev +version: 2.7.2 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 1a69291d145..b3a62befc5e 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.3.11 + +No user-facing changes. + ## 2.3.10 No user-facing changes. diff --git a/javascript/ql/src/change-notes/released/2.3.11.md b/javascript/ql/src/change-notes/released/2.3.11.md new file mode 100644 index 00000000000..31b11998b74 --- /dev/null +++ b/javascript/ql/src/change-notes/released/2.3.11.md @@ -0,0 +1,3 @@ +## 2.3.11 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index a4a2f98d509..5ac091006e8 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.3.10 +lastReleaseVersion: 2.3.11 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index e58cb3d2d94..03a7153c05a 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 2.3.11-dev +version: 2.3.11 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 8e20945c6bf..8f96c9ba8dd 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/1.0.51.md b/misc/suite-helpers/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/misc/suite-helpers/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index fd00605cfd1..a6aeeb719fa 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.51-dev +version: 1.0.51 groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 3d09821803b..3efb4e57482 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 7.1.2 + +### Minor Analysis Improvements + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes. + ## 7.1.1 No user-facing changes. diff --git a/python/ql/lib/change-notes/2026-05-14-sensitive-data.md b/python/ql/lib/change-notes/released/7.1.2.md similarity index 90% rename from python/ql/lib/change-notes/2026-05-14-sensitive-data.md rename to python/ql/lib/change-notes/released/7.1.2.md index 49754de35ce..523a14edfbe 100644 --- a/python/ql/lib/change-notes/2026-05-14-sensitive-data.md +++ b/python/ql/lib/change-notes/released/7.1.2.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 7.1.2 + +### Minor Analysis Improvements + * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 8e970df6cae..547681cc440 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.1.1 +lastReleaseVersion: 7.1.2 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 981ab78ff33..a53a716fbf0 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 7.1.2-dev +version: 7.1.2 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 544b9778d4d..27698f1d3df 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.8.4 + +No user-facing changes. + ## 1.8.3 No user-facing changes. diff --git a/python/ql/src/change-notes/released/1.8.4.md b/python/ql/src/change-notes/released/1.8.4.md new file mode 100644 index 00000000000..9aef6d10d1c --- /dev/null +++ b/python/ql/src/change-notes/released/1.8.4.md @@ -0,0 +1,3 @@ +## 1.8.4 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 8071ef421ab..f2a60cd1327 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.8.3 +lastReleaseVersion: 1.8.4 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 2fc026ff480..afa318334b6 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.8.4-dev +version: 1.8.4 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 07859d0f0e6..d26bfa6f205 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.2.2 + +No user-facing changes. + ## 5.2.1 No user-facing changes. diff --git a/ruby/ql/lib/change-notes/released/5.2.2.md b/ruby/ql/lib/change-notes/released/5.2.2.md new file mode 100644 index 00000000000..22402d6e8fa --- /dev/null +++ b/ruby/ql/lib/change-notes/released/5.2.2.md @@ -0,0 +1,3 @@ +## 5.2.2 + +No user-facing changes. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 1684d0e72a2..e3b1b0c079d 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.2.1 +lastReleaseVersion: 5.2.2 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index df8efbe68de..b36aada4770 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 5.2.2-dev +version: 5.2.2 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index c874059c151..384ca633202 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.4 + +No user-facing changes. + ## 1.6.3 No user-facing changes. diff --git a/ruby/ql/src/change-notes/released/1.6.4.md b/ruby/ql/src/change-notes/released/1.6.4.md new file mode 100644 index 00000000000..5c811dc4638 --- /dev/null +++ b/ruby/ql/src/change-notes/released/1.6.4.md @@ -0,0 +1,3 @@ +## 1.6.4 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 00b51441d88..1910e09d6a6 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.3 +lastReleaseVersion: 1.6.4 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index b68d13e5908..e0c8c6b4c0c 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.6.4-dev +version: 1.6.4 groups: - ruby - queries diff --git a/rust/ql/lib/CHANGELOG.md b/rust/ql/lib/CHANGELOG.md index d85d27d88d6..3651026d737 100644 --- a/rust/ql/lib/CHANGELOG.md +++ b/rust/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.15 + +### Minor Analysis Improvements + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `rust/cleartext-logging`) may find more correct results and fewer false positive results after these changes. + ## 0.2.14 No user-facing changes. diff --git a/rust/ql/lib/change-notes/2026-05-14-sensitive-data.md b/rust/ql/lib/change-notes/released/0.2.15.md similarity index 89% rename from rust/ql/lib/change-notes/2026-05-14-sensitive-data.md rename to rust/ql/lib/change-notes/released/0.2.15.md index 5aa6febd49b..3644126ec1f 100644 --- a/rust/ql/lib/change-notes/2026-05-14-sensitive-data.md +++ b/rust/ql/lib/change-notes/released/0.2.15.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.2.15 + +### Minor Analysis Improvements + * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `rust/cleartext-logging`) may find more correct results and fewer false positive results after these changes. diff --git a/rust/ql/lib/codeql-pack.release.yml b/rust/ql/lib/codeql-pack.release.yml index c53820a76d5..0f574e080e4 100644 --- a/rust/ql/lib/codeql-pack.release.yml +++ b/rust/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.14 +lastReleaseVersion: 0.2.15 diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 062c2f4e635..49c4dddd4c6 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-all -version: 0.2.15-dev +version: 0.2.15 groups: rust extractor: rust dbscheme: rust.dbscheme diff --git a/rust/ql/src/CHANGELOG.md b/rust/ql/src/CHANGELOG.md index ad1e8ef3bfe..4f4807ff82e 100644 --- a/rust/ql/src/CHANGELOG.md +++ b/rust/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.36 + +No user-facing changes. + ## 0.1.35 No user-facing changes. diff --git a/rust/ql/src/change-notes/released/0.1.36.md b/rust/ql/src/change-notes/released/0.1.36.md new file mode 100644 index 00000000000..8685189c564 --- /dev/null +++ b/rust/ql/src/change-notes/released/0.1.36.md @@ -0,0 +1,3 @@ +## 0.1.36 + +No user-facing changes. diff --git a/rust/ql/src/codeql-pack.release.yml b/rust/ql/src/codeql-pack.release.yml index 6a5806eec2b..270bd27a7aa 100644 --- a/rust/ql/src/codeql-pack.release.yml +++ b/rust/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.35 +lastReleaseVersion: 0.1.36 diff --git a/rust/ql/src/qlpack.yml b/rust/ql/src/qlpack.yml index 67966540de6..853aefb020d 100644 --- a/rust/ql/src/qlpack.yml +++ b/rust/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-queries -version: 0.1.36-dev +version: 0.1.36 groups: - rust - queries diff --git a/shared/concepts/CHANGELOG.md b/shared/concepts/CHANGELOG.md index e2de2975455..787779674f0 100644 --- a/shared/concepts/CHANGELOG.md +++ b/shared/concepts/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.25 + +No user-facing changes. + ## 0.0.24 No user-facing changes. diff --git a/shared/concepts/change-notes/released/0.0.25.md b/shared/concepts/change-notes/released/0.0.25.md new file mode 100644 index 00000000000..e41a9acfa06 --- /dev/null +++ b/shared/concepts/change-notes/released/0.0.25.md @@ -0,0 +1,3 @@ +## 0.0.25 + +No user-facing changes. diff --git a/shared/concepts/codeql-pack.release.yml b/shared/concepts/codeql-pack.release.yml index b956773a07f..6d0e80a50c3 100644 --- a/shared/concepts/codeql-pack.release.yml +++ b/shared/concepts/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.24 +lastReleaseVersion: 0.0.25 diff --git a/shared/concepts/qlpack.yml b/shared/concepts/qlpack.yml index c51537b2228..98ae75ca6ca 100644 --- a/shared/concepts/qlpack.yml +++ b/shared/concepts/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/concepts -version: 0.0.25-dev +version: 0.0.25 groups: shared library: true dependencies: diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index dc02f115c99..8ac7faf2554 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.35 + +No user-facing changes. + ## 2.0.34 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/2.0.35.md b/shared/controlflow/change-notes/released/2.0.35.md new file mode 100644 index 00000000000..526e1fc9f4c --- /dev/null +++ b/shared/controlflow/change-notes/released/2.0.35.md @@ -0,0 +1,3 @@ +## 2.0.35 + +No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index 339a3ce7c57..27eb8ef8ece 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.34 +lastReleaseVersion: 2.0.35 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index e33617ca4f0..a28d74ae749 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 2.0.35-dev +version: 2.0.35 groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index 7ecbeda3b21..b2cf75110ac 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.7 + +No user-facing changes. + ## 2.1.6 No user-facing changes. diff --git a/shared/dataflow/change-notes/released/2.1.7.md b/shared/dataflow/change-notes/released/2.1.7.md new file mode 100644 index 00000000000..af7772169fe --- /dev/null +++ b/shared/dataflow/change-notes/released/2.1.7.md @@ -0,0 +1,3 @@ +## 2.1.7 + +No user-facing changes. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index 1c810b60c4a..cfa57a47251 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.1.6 +lastReleaseVersion: 2.1.7 diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 2058b35be64..6564305a246 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 2.1.7-dev +version: 2.1.7 groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index 964c1bb1d98..6619a18079c 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/mad/change-notes/released/1.0.51.md b/shared/mad/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/mad/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index fb135546a90..c8d8eb47b4a 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/quantum/CHANGELOG.md b/shared/quantum/CHANGELOG.md index 7153b9314b1..c8b656e4f35 100644 --- a/shared/quantum/CHANGELOG.md +++ b/shared/quantum/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.29 + +No user-facing changes. + ## 0.0.28 No user-facing changes. diff --git a/shared/quantum/change-notes/released/0.0.29.md b/shared/quantum/change-notes/released/0.0.29.md new file mode 100644 index 00000000000..4428927c79d --- /dev/null +++ b/shared/quantum/change-notes/released/0.0.29.md @@ -0,0 +1,3 @@ +## 0.0.29 + +No user-facing changes. diff --git a/shared/quantum/codeql-pack.release.yml b/shared/quantum/codeql-pack.release.yml index 3462db7d348..c81f1813120 100644 --- a/shared/quantum/codeql-pack.release.yml +++ b/shared/quantum/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.28 +lastReleaseVersion: 0.0.29 diff --git a/shared/quantum/qlpack.yml b/shared/quantum/qlpack.yml index 951cce392ae..a8d3a71823b 100644 --- a/shared/quantum/qlpack.yml +++ b/shared/quantum/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/quantum -version: 0.0.29-dev +version: 0.0.29 groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/CHANGELOG.md b/shared/rangeanalysis/CHANGELOG.md index e2a893046c9..a400a91f8c9 100644 --- a/shared/rangeanalysis/CHANGELOG.md +++ b/shared/rangeanalysis/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/rangeanalysis/change-notes/released/1.0.51.md b/shared/rangeanalysis/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/rangeanalysis/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/rangeanalysis/codeql-pack.release.yml b/shared/rangeanalysis/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/rangeanalysis/codeql-pack.release.yml +++ b/shared/rangeanalysis/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index 41f319731b0..5ea1c83b182 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index bb83dfc0a1f..c4b7fc6e87f 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/regex/change-notes/released/1.0.51.md b/shared/regex/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/regex/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 198bf43da04..3c01106e9b8 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index f9145f2c88b..9cfe68398b2 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.27 + +No user-facing changes. + ## 2.0.26 No user-facing changes. diff --git a/shared/ssa/change-notes/released/2.0.27.md b/shared/ssa/change-notes/released/2.0.27.md new file mode 100644 index 00000000000..639cf77090e --- /dev/null +++ b/shared/ssa/change-notes/released/2.0.27.md @@ -0,0 +1,3 @@ +## 2.0.27 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index 63d57bef481..a047558f018 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.26 +lastReleaseVersion: 2.0.27 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 5f8de945745..c10e0892660 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 2.0.27-dev +version: 2.0.27 groups: shared library: true dependencies: diff --git a/shared/threat-models/CHANGELOG.md b/shared/threat-models/CHANGELOG.md index 512a5732ccd..14258018aea 100644 --- a/shared/threat-models/CHANGELOG.md +++ b/shared/threat-models/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/threat-models/change-notes/released/1.0.51.md b/shared/threat-models/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/threat-models/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/threat-models/codeql-pack.release.yml b/shared/threat-models/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/threat-models/codeql-pack.release.yml +++ b/shared/threat-models/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index c3ac3656b3a..855242656c8 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.51-dev +version: 1.0.51 library: true groups: shared dataExtensions: diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index c98a035d149..9e78286a1a4 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/1.0.51.md b/shared/tutorial/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/tutorial/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index e68fe7948ff..39bfd9cc21d 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/CHANGELOG.md b/shared/typeflow/CHANGELOG.md index de43834a84e..e9334c9da8d 100644 --- a/shared/typeflow/CHANGELOG.md +++ b/shared/typeflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/typeflow/change-notes/released/1.0.51.md b/shared/typeflow/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/typeflow/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/typeflow/codeql-pack.release.yml b/shared/typeflow/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/typeflow/codeql-pack.release.yml +++ b/shared/typeflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index 482138349ac..f06ea443f79 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/typeinference/CHANGELOG.md b/shared/typeinference/CHANGELOG.md index 3bbb96e59a9..24dc81f3aa2 100644 --- a/shared/typeinference/CHANGELOG.md +++ b/shared/typeinference/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.32 + +No user-facing changes. + ## 0.0.31 No user-facing changes. diff --git a/shared/typeinference/change-notes/released/0.0.32.md b/shared/typeinference/change-notes/released/0.0.32.md new file mode 100644 index 00000000000..c390443f09a --- /dev/null +++ b/shared/typeinference/change-notes/released/0.0.32.md @@ -0,0 +1,3 @@ +## 0.0.32 + +No user-facing changes. diff --git a/shared/typeinference/codeql-pack.release.yml b/shared/typeinference/codeql-pack.release.yml index 54b504d06ec..714fcfc1828 100644 --- a/shared/typeinference/codeql-pack.release.yml +++ b/shared/typeinference/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.31 +lastReleaseVersion: 0.0.32 diff --git a/shared/typeinference/qlpack.yml b/shared/typeinference/qlpack.yml index d7dbeae2e09..ece5dd3b6e8 100644 --- a/shared/typeinference/qlpack.yml +++ b/shared/typeinference/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeinference -version: 0.0.32-dev +version: 0.0.32 groups: shared library: true dependencies: diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index 313862d5bc7..e9b5492b0d8 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.35 + +No user-facing changes. + ## 2.0.34 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/2.0.35.md b/shared/typetracking/change-notes/released/2.0.35.md new file mode 100644 index 00000000000..526e1fc9f4c --- /dev/null +++ b/shared/typetracking/change-notes/released/2.0.35.md @@ -0,0 +1,3 @@ +## 2.0.35 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index 339a3ce7c57..27eb8ef8ece 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.34 +lastReleaseVersion: 2.0.35 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 891f8d0b1b1..bd874407aff 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 2.0.35-dev +version: 2.0.35 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 5838cd3c535..dbafbea9b98 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/typos/change-notes/released/1.0.51.md b/shared/typos/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/typos/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index b4705122b0a..9a2ed996444 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index 24a4f7d09a2..df741ed9d73 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.38 + +No user-facing changes. + ## 2.0.37 No user-facing changes. diff --git a/shared/util/change-notes/released/2.0.38.md b/shared/util/change-notes/released/2.0.38.md new file mode 100644 index 00000000000..0fab2ede165 --- /dev/null +++ b/shared/util/change-notes/released/2.0.38.md @@ -0,0 +1,3 @@ +## 2.0.38 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index 108259a7400..4ec9eb0980c 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.37 +lastReleaseVersion: 2.0.38 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 6190a3b4275..dc654fca261 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.38-dev +version: 2.0.38 groups: shared library: true dependencies: null diff --git a/shared/xml/CHANGELOG.md b/shared/xml/CHANGELOG.md index 96dfbcadf56..685a8032d64 100644 --- a/shared/xml/CHANGELOG.md +++ b/shared/xml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/xml/change-notes/released/1.0.51.md b/shared/xml/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/xml/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/xml/codeql-pack.release.yml b/shared/xml/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/xml/codeql-pack.release.yml +++ b/shared/xml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index c8e51461dae..40cf2695728 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index e006acbeb21..4f57ee07cfa 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.51 + +No user-facing changes. + ## 1.0.50 No user-facing changes. diff --git a/shared/yaml/change-notes/released/1.0.51.md b/shared/yaml/change-notes/released/1.0.51.md new file mode 100644 index 00000000000..b96d48b8822 --- /dev/null +++ b/shared/yaml/change-notes/released/1.0.51.md @@ -0,0 +1,3 @@ +## 1.0.51 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index 856137cc5db..232dbe38ec8 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.50 +lastReleaseVersion: 1.0.51 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index c499501ab26..0b4fd245f3b 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.51-dev +version: 1.0.51 groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index 01461fd5bfe..1eb5afb48e7 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 6.7.0 + +### Major Analysis Improvements + +* Upgraded to allow analysis of Swift 6.3.2. + +### Minor Analysis Improvements + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `swift/cleartext-logging`) may find more correct results and fewer false positive results after these changes. + ## 6.6.0 ### New Features diff --git a/swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md b/swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md deleted file mode 100644 index 530b7187e7a..00000000000 --- a/swift/ql/lib/change-notes/2026-05-19-swift-6.3.2.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Upgraded to allow analysis of Swift 6.3.2. diff --git a/swift/ql/lib/change-notes/2026-05-14-sensitive-data.md b/swift/ql/lib/change-notes/released/6.7.0.md similarity index 76% rename from swift/ql/lib/change-notes/2026-05-14-sensitive-data.md rename to swift/ql/lib/change-notes/released/6.7.0.md index 70e96a3469c..8d7bf41cc1d 100644 --- a/swift/ql/lib/change-notes/2026-05-14-sensitive-data.md +++ b/swift/ql/lib/change-notes/released/6.7.0.md @@ -1,4 +1,9 @@ ---- -category: minorAnalysis ---- +## 6.7.0 + +### Major Analysis Improvements + +* Upgraded to allow analysis of Swift 6.3.2. + +### Minor Analysis Improvements + * The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `swift/cleartext-logging`) may find more correct results and fewer false positive results after these changes. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 4d7f31f2d8e..55a13d309e5 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 6.6.0 +lastReleaseVersion: 6.7.0 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 5e2f7c2942d..f62f77afa0e 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 6.6.1-dev +version: 6.7.0 groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index 4bd8088718a..4e3b53c37b3 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.4 + +No user-facing changes. + ## 1.3.3 No user-facing changes. diff --git a/swift/ql/src/change-notes/released/1.3.4.md b/swift/ql/src/change-notes/released/1.3.4.md new file mode 100644 index 00000000000..5073aca7222 --- /dev/null +++ b/swift/ql/src/change-notes/released/1.3.4.md @@ -0,0 +1,3 @@ +## 1.3.4 + +No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index eb1f7dabc84..8263ddf2c8b 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.3 +lastReleaseVersion: 1.3.4 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index da4df6ae6d9..05710b29874 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.3.4-dev +version: 1.3.4 groups: - swift - queries From cfb18c247708d2fa77d74130c465f31d32a29487 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 29 May 2026 12:04:35 +0000 Subject: [PATCH 149/226] Post-release preparation for codeql-cli-2.25.6 --- actions/ql/lib/qlpack.yml | 2 +- actions/ql/src/qlpack.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- rust/ql/lib/qlpack.yml | 2 +- rust/ql/src/qlpack.yml | 2 +- shared/concepts/qlpack.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/quantum/qlpack.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typeinference/qlpack.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 41 files changed, 41 insertions(+), 41 deletions(-) diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml index 71c9cadbf28..5d47e3f3d67 100644 --- a/actions/ql/lib/qlpack.yml +++ b/actions/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-all -version: 0.4.37 +version: 0.4.38-dev library: true warnOnImplicitThis: true dependencies: diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml index 3615c08b583..19187efb071 100644 --- a/actions/ql/src/qlpack.yml +++ b/actions/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-queries -version: 0.6.29 +version: 0.6.30-dev library: false warnOnImplicitThis: true groups: [actions, queries] diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 04ee2d76ae9..6f63423d953 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 10.2.0 +version: 10.2.1-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 4915f969278..7f3df37c30a 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.6.4 +version: 1.6.5-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 1de44f9e1d8..52172a7a189 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.68 +version: 1.7.69-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index e99c5a26b32..cf63a439518 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.68 +version: 1.7.69-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 0745dfdd527..ca43ae8b07b 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 6.0.2 +version: 6.0.3-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index d9269a9fd1b..378d02fee3f 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.7.4 +version: 1.7.5-dev groups: - csharp - queries diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index c07260f76da..6938858c6ba 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.51 +version: 1.0.52-dev groups: - go - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 8a9a9624de5..6084bfbfee3 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 7.1.2 +version: 7.1.3-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 601e81ea035..3357004e466 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.6.4 +version: 1.6.5-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 561ef7db55c..18948bf45f5 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 9.1.2 +version: 9.1.3-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index cfd8dbc56c8..ac519484225 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.11.4 +version: 1.11.5-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 6caebf91399..870ad58a1b8 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.7.2 +version: 2.7.3-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 03a7153c05a..09303bab573 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 2.3.11 +version: 2.3.12-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index a6aeeb719fa..7ac4b0e1dc3 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.51 +version: 1.0.52-dev groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index a53a716fbf0..210e683a54f 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 7.1.2 +version: 7.1.3-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index afa318334b6..0eba954079e 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.8.4 +version: 1.8.5-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index b36aada4770..3029a6d098f 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 5.2.2 +version: 5.2.3-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index e0c8c6b4c0c..72b0258fa30 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.6.4 +version: 1.6.5-dev groups: - ruby - queries diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 49c4dddd4c6..e97302ac1f9 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-all -version: 0.2.15 +version: 0.2.16-dev groups: rust extractor: rust dbscheme: rust.dbscheme diff --git a/rust/ql/src/qlpack.yml b/rust/ql/src/qlpack.yml index 853aefb020d..9ba6302ecc0 100644 --- a/rust/ql/src/qlpack.yml +++ b/rust/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-queries -version: 0.1.36 +version: 0.1.37-dev groups: - rust - queries diff --git a/shared/concepts/qlpack.yml b/shared/concepts/qlpack.yml index 98ae75ca6ca..dd1f0280e79 100644 --- a/shared/concepts/qlpack.yml +++ b/shared/concepts/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/concepts -version: 0.0.25 +version: 0.0.26-dev groups: shared library: true dependencies: diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index a28d74ae749..b3518003b24 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 2.0.35 +version: 2.0.36-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 6564305a246..cdce161af7e 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 2.1.7 +version: 2.1.8-dev groups: shared library: true dependencies: diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index c8d8eb47b4a..21a06e7cc4d 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.51 +version: 1.0.52-dev groups: shared library: true dependencies: diff --git a/shared/quantum/qlpack.yml b/shared/quantum/qlpack.yml index a8d3a71823b..c430e4a69be 100644 --- a/shared/quantum/qlpack.yml +++ b/shared/quantum/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/quantum -version: 0.0.29 +version: 0.0.30-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index 5ea1c83b182..7cecb52325f 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.51 +version: 1.0.52-dev groups: shared library: true dependencies: diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 3c01106e9b8..a1ec511b126 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.51 +version: 1.0.52-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index c10e0892660..9c14b9e6469 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 2.0.27 +version: 2.0.28-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 855242656c8..c7326273c65 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.51 +version: 1.0.52-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 39bfd9cc21d..bb6eeeb2460 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.51 +version: 1.0.52-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index f06ea443f79..9790bbcaeae 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.51 +version: 1.0.52-dev groups: shared library: true dependencies: diff --git a/shared/typeinference/qlpack.yml b/shared/typeinference/qlpack.yml index ece5dd3b6e8..ab43c330dcc 100644 --- a/shared/typeinference/qlpack.yml +++ b/shared/typeinference/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeinference -version: 0.0.32 +version: 0.0.33-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index bd874407aff..de6ff4c16c9 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 2.0.35 +version: 2.0.36-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 9a2ed996444..0b6aee6fd1c 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.51 +version: 1.0.52-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index dc654fca261..2914785b146 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.38 +version: 2.0.39-dev groups: shared library: true dependencies: null diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index 40cf2695728..0476610fda8 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.51 +version: 1.0.52-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 0b4fd245f3b..ae27690a3f9 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.51 +version: 1.0.52-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index f62f77afa0e..960d679e6d9 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 6.7.0 +version: 6.7.1-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 05710b29874..578456c089a 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.3.4 +version: 1.3.5-dev groups: - swift - queries From caae5a8bf1de453e04eda77158ea2ee27e3e9825 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 29 May 2026 14:24:45 +0200 Subject: [PATCH 150/226] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll | 6 +++--- shared/namebinding/codeql/namebinding/LocalNameBinding.qll | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index f1df0a144b8..0327509c465 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -79,7 +79,7 @@ module Impl { * are parsed left-associatively, so the AST for the condition looks like * * ```rust - * ((let x1 = ... && let x2 = ...) && ...) & let xn = ... + * ((let x1 = ... && let x2 = ...) && ...) && let xn = ... * ``` * * This, however, does not work with scoping and shadowing, so we instead treat @@ -319,10 +319,10 @@ module Impl { result.(Param).getPat() = getAPatAncestor*(this.getPat()) } - /** Hold is this variable is mutable. */ + /** Holds if this variable is mutable. */ predicate isMutable() { this.getPat().isMut() or this.getSelfParam().isMut() } - /** Hold is this variable is immutable. */ + /** Holds if this variable is immutable. */ predicate isImmutable() { not this.isMutable() } } diff --git a/shared/namebinding/codeql/namebinding/LocalNameBinding.qll b/shared/namebinding/codeql/namebinding/LocalNameBinding.qll index 55f4fa13ba1..298f498e331 100644 --- a/shared/namebinding/codeql/namebinding/LocalNameBinding.qll +++ b/shared/namebinding/codeql/namebinding/LocalNameBinding.qll @@ -132,7 +132,7 @@ signature module LocalNameBindingInputSig { * * If `scope` declares a local with the name of `n`, then `scope` is guaranteed * to be the scope that `n` ultimately resolves to. This can thus be used to take - * full control of scope resolution for for specific types of references. + * full control of scope resolution for specific types of references. */ default predicate lookupStartsAt(AstNode n, AstNode scope) { none() } } From e18448dd5929046139b91e159365e8ed294aef30 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 29 May 2026 18:22:13 +0200 Subject: [PATCH 151/226] C++: Add more tests. --- .../dataflow/external-models/flow.expected | 66 ++++++++++++++----- .../dataflow/external-models/flow.ext.yml | 4 +- .../dataflow/external-models/sinks.expected | 2 + .../dataflow/external-models/sources.expected | 2 + .../dataflow/external-models/test.cpp | 27 ++++++++ 5 files changed, 84 insertions(+), 17 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index 4142b09473a..2b790a2838b 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -51,13 +51,15 @@ models | 50 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated | | 51 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual | | 52 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual | -| 53 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual | -| 54 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual | -| 55 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual | -| 56 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual | -| 57 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual | +| 53 | Summary: ; TemplateClass1; false; templateFunction; (T,U); ; Argument[0]; ReturnValue; value; manual | +| 54 | Summary: ; TemplateClass2; false; function; (U,T); ; Argument[1]; ReturnValue; value; manual | +| 55 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual | +| 56 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual | +| 57 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual | +| 58 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual | +| 59 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual | edges -| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:57 | +| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:59 | | asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 | | asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 | | asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction | @@ -66,24 +68,24 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | | | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | -| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:57 | -| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:56 | -| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:53 | -| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:54 | -| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:55 | +| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:59 | +| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:58 | +| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:55 | +| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:56 | +| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:57 | | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | | | azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 | | azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | | | azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | | | azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | | | azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | | -| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:53 | +| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:55 | | azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | | | azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | | -| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:54 | +| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:56 | | azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | | | azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | | -| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:55 | +| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:57 | | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | | | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | | | azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | | @@ -100,11 +102,11 @@ edges | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 | | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | | | azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | | -| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:55 | +| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:57 | | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | | | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | | | azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | | -| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:56 | +| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:58 | | azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | | | azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 | | azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | | @@ -180,6 +182,20 @@ edges | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 | | test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | | | test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:48 | +| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | provenance | MaD:53 | +| test.cpp:130:10:130:18 | call to ymlSource | test.cpp:130:10:130:18 | call to ymlSource | provenance | Src:MaD:25 | +| test.cpp:130:10:130:18 | call to ymlSource | test.cpp:131:45:131:45 | x | provenance | | +| test.cpp:131:13:131:43 | call to templateFunction | test.cpp:131:13:131:43 | call to templateFunction | provenance | | +| test.cpp:131:13:131:43 | call to templateFunction | test.cpp:132:10:132:10 | y | provenance | Sink:MaD:1 | +| test.cpp:131:45:131:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | provenance | | +| test.cpp:131:45:131:45 | x | test.cpp:131:13:131:43 | call to templateFunction | provenance | MaD:53 | +| test.cpp:137:4:137:11 | [summary param] 1 in function | test.cpp:137:4:137:11 | [summary] to write: ReturnValue in function | provenance | MaD:54 | +| test.cpp:143:10:143:18 | call to ymlSource | test.cpp:143:10:143:18 | call to ymlSource | provenance | Src:MaD:25 | +| test.cpp:143:10:143:18 | call to ymlSource | test.cpp:145:26:145:26 | x | provenance | | +| test.cpp:145:10:145:27 | call to function | test.cpp:145:10:145:27 | call to function | provenance | | +| test.cpp:145:10:145:27 | call to function | test.cpp:146:10:146:10 | z | provenance | Sink:MaD:1 | +| test.cpp:145:26:145:26 | x | test.cpp:137:4:137:11 | [summary param] 1 in function | provenance | | +| test.cpp:145:26:145:26 | x | test.cpp:145:10:145:27 | call to function | provenance | MaD:54 | | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:33 | | windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 | | windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | | @@ -483,6 +499,22 @@ nodes | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | semmle.label | call to callWithNonTypeTemplate | | test.cpp:118:44:118:44 | *x | semmle.label | *x | | test.cpp:119:10:119:11 | y2 | semmle.label | y2 | +| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | semmle.label | [summary param] 0 in templateFunction | +| test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | semmle.label | [summary] to write: ReturnValue in templateFunction | +| test.cpp:130:10:130:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:130:10:130:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:131:13:131:43 | call to templateFunction | semmle.label | call to templateFunction | +| test.cpp:131:13:131:43 | call to templateFunction | semmle.label | call to templateFunction | +| test.cpp:131:45:131:45 | x | semmle.label | x | +| test.cpp:132:10:132:10 | y | semmle.label | y | +| test.cpp:137:4:137:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function | +| test.cpp:137:4:137:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function | +| test.cpp:143:10:143:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:143:10:143:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:145:10:145:27 | call to function | semmle.label | call to function | +| test.cpp:145:10:145:27 | call to function | semmle.label | call to function | +| test.cpp:145:26:145:26 | x | semmle.label | x | +| test.cpp:146:10:146:10 | z | semmle.label | z | | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA | | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA | | windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA | @@ -688,6 +720,8 @@ subpaths | test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | | test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | +| test.cpp:131:45:131:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | test.cpp:131:13:131:43 | call to templateFunction | +| test.cpp:145:26:145:26 | x | test.cpp:137:4:137:11 | [summary param] 1 in function | test.cpp:137:4:137:11 | [summary] to write: ReturnValue in function | test.cpp:145:10:145:27 | call to function | | windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | | windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | | windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml b/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml index 8e200aabfbd..dfa9b981ef1 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml @@ -18,4 +18,6 @@ extensions: - ["", "", False, "ymlStepManual_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["", "", False, "ymlStepGenerated_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] - ["", "", False, "callWithArgument", "", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"] - - ["", "", False, "callWithNonTypeTemplate", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"] \ No newline at end of file + - ["", "", False, "callWithNonTypeTemplate", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"] + - ["", "TemplateClass1", False, "templateFunction", "(T,U)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["", "TemplateClass2", False, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/external-models/sinks.expected b/cpp/ql/test/library-tests/dataflow/external-models/sinks.expected index e28349b7159..379ce723806 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/sinks.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/sinks.expected @@ -15,3 +15,5 @@ | test.cpp:89:11:89:11 | y | test-sink | | test.cpp:116:10:116:11 | y1 | test-sink | | test.cpp:119:10:119:11 | y2 | test-sink | +| test.cpp:132:10:132:10 | y | test-sink | +| test.cpp:146:10:146:10 | z | test-sink | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected index b46aa87af6f..f13d75bc66b 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected @@ -9,6 +9,8 @@ | test.cpp:56:8:56:16 | call to ymlSource | local | | test.cpp:94:10:94:18 | call to ymlSource | local | | test.cpp:114:10:114:18 | call to ymlSource | local | +| test.cpp:130:10:130:18 | call to ymlSource | local | +| test.cpp:143:10:143:18 | call to ymlSource | local | | windows.cpp:22:15:22:29 | *call to GetCommandLineA | local | | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local | | windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/test.cpp b/cpp/ql/test/library-tests/dataflow/external-models/test.cpp index af11ff958f5..fb9b6ceb0e7 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/external-models/test.cpp @@ -118,3 +118,30 @@ void test_callWithNonTypeTemplate() { int y2 = callWithNonTypeTemplate(x); ymlSink(y2); // $ ir } + +template +struct TemplateClass1 { + template + U templateFunction(T, U); +}; + +void test_template_function_in_template_class() { + TemplateClass1 b; + int x = ymlSource(); + auto y = b.templateFunction(x, 0UL); + ymlSink(y); // $ ir +} + +template +struct TemplateClass2 { + T function(T, S); +}; + +template using PartialInstantiationOfTemplateClass2 = TemplateClass2; + +void test_partial_instantiation() { + int x = ymlSource(); + PartialInstantiationOfTemplateClass2 y; + int z = y.function(0UL, x); + ymlSink(z); // $ ir +} \ No newline at end of file From 5e5a0437e15842d9bacfe3115418417121441953 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Sat, 30 May 2026 07:27:56 +0100 Subject: [PATCH 152/226] Shared CFG: allow init stmts for IfStmt --- .../codeql/controlflow/ControlFlowGraph.qll | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index fff877b9fcd..68b230f735b 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -95,6 +95,9 @@ signature module AstSig { Stmt getElse(); } + /** Gets the initializer of this `if` statement, if any. */ + default AstNode getIfInit(IfStmt ifstmt) { none() } + /** * A loop statement. Loop statements are further subclassed into specific * types of loops. @@ -1509,6 +1512,13 @@ module Make0 Ast> { or exists(IfStmt ifstmt | n1.isBefore(ifstmt) and + ( + n2.isBefore(getIfInit(ifstmt)) + or + not exists(getIfInit(ifstmt)) and n2.isBefore(ifstmt.getCondition()) + ) + or + n1.isAfter(getIfInit(ifstmt)) and n2.isBefore(ifstmt.getCondition()) or n1.isAfterTrue(ifstmt.getCondition()) and From 22b08f1ea4e473832580604d243981afa4ca97ea Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Sun, 31 May 2026 12:47:31 +0200 Subject: [PATCH 153/226] C++: Add a test with a kind of "partial function template" instantiation. --- .../dataflow/external-models/flow.expected | 140 ++++++++++++------ .../dataflow/external-models/flow.ext.yml | 3 +- .../dataflow/external-models/sinks.expected | 6 +- .../dataflow/external-models/sources.expected | 6 +- .../dataflow/external-models/test.cpp | 29 +++- 5 files changed, 130 insertions(+), 54 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index 2b790a2838b..8d247738c98 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -51,15 +51,16 @@ models | 50 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated | | 51 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual | | 52 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual | -| 53 | Summary: ; TemplateClass1; false; templateFunction; (T,U); ; Argument[0]; ReturnValue; value; manual | -| 54 | Summary: ; TemplateClass2; false; function; (U,T); ; Argument[1]; ReturnValue; value; manual | -| 55 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual | -| 56 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual | -| 57 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual | -| 58 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual | -| 59 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual | +| 53 | Summary: ; TemplateClass1; true; templateFunction2; (U,V); ; Argument[1]; ReturnValue; value; manual | +| 54 | Summary: ; TemplateClass1; false; templateFunction; (T,U); ; Argument[0]; ReturnValue; value; manual | +| 55 | Summary: ; TemplateClass2; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual | +| 56 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual | +| 57 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual | +| 58 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual | +| 59 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual | +| 60 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual | edges -| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:59 | +| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:60 | | asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 | | asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 | | asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction | @@ -68,24 +69,24 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | | | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | -| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:59 | -| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:58 | -| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:55 | -| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:56 | -| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:57 | +| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:60 | +| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:59 | +| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:56 | +| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:57 | +| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:58 | | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | | | azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 | | azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | | | azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | | | azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | | | azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | | -| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:55 | +| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:56 | | azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | | | azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | | -| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:56 | +| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:57 | | azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | | | azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | | -| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:57 | +| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:58 | | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | | | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | | | azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | | @@ -102,11 +103,11 @@ edges | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 | | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | | | azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | | -| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:57 | +| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:58 | | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | | | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | | | azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | | -| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:58 | +| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:59 | | azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | | | azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 | | azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | | @@ -182,20 +183,39 @@ edges | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 | | test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | | | test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:48 | -| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | provenance | MaD:53 | -| test.cpp:130:10:130:18 | call to ymlSource | test.cpp:130:10:130:18 | call to ymlSource | provenance | Src:MaD:25 | -| test.cpp:130:10:130:18 | call to ymlSource | test.cpp:131:45:131:45 | x | provenance | | -| test.cpp:131:13:131:43 | call to templateFunction | test.cpp:131:13:131:43 | call to templateFunction | provenance | | -| test.cpp:131:13:131:43 | call to templateFunction | test.cpp:132:10:132:10 | y | provenance | Sink:MaD:1 | -| test.cpp:131:45:131:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | provenance | | -| test.cpp:131:45:131:45 | x | test.cpp:131:13:131:43 | call to templateFunction | provenance | MaD:53 | -| test.cpp:137:4:137:11 | [summary param] 1 in function | test.cpp:137:4:137:11 | [summary] to write: ReturnValue in function | provenance | MaD:54 | -| test.cpp:143:10:143:18 | call to ymlSource | test.cpp:143:10:143:18 | call to ymlSource | provenance | Src:MaD:25 | -| test.cpp:143:10:143:18 | call to ymlSource | test.cpp:145:26:145:26 | x | provenance | | -| test.cpp:145:10:145:27 | call to function | test.cpp:145:10:145:27 | call to function | provenance | | -| test.cpp:145:10:145:27 | call to function | test.cpp:146:10:146:10 | z | provenance | Sink:MaD:1 | -| test.cpp:145:26:145:26 | x | test.cpp:137:4:137:11 | [summary param] 1 in function | provenance | | -| test.cpp:145:26:145:26 | x | test.cpp:145:10:145:27 | call to function | provenance | MaD:54 | +| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | provenance | MaD:54 | +| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | provenance | MaD:53 | +| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:133:10:133:18 | call to ymlSource | provenance | Src:MaD:25 | +| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:134:45:134:45 | x | provenance | | +| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:134:13:134:43 | call to templateFunction | provenance | | +| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:135:10:135:10 | y | provenance | Sink:MaD:1 | +| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | provenance | | +| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:54 | +| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 | +| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 | +| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:146:10:146:18 | call to ymlSource | provenance | Src:MaD:25 | +| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:148:26:148:26 | x | provenance | | +| test.cpp:148:10:148:27 | call to function | test.cpp:148:10:148:27 | call to function | provenance | | +| test.cpp:148:10:148:27 | call to function | test.cpp:149:10:149:10 | z | provenance | Sink:MaD:1 | +| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | | +| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:55 | +| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:155:10:155:18 | call to ymlSource | provenance | Src:MaD:25 | +| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:157:26:157:26 | x | provenance | | +| test.cpp:157:13:157:20 | call to function | test.cpp:157:13:157:20 | call to function | provenance | | +| test.cpp:157:13:157:20 | call to function | test.cpp:158:10:158:10 | z | provenance | Sink:MaD:1 | +| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | | +| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:55 | +| test.cpp:164:34:164:34 | x | test.cpp:165:69:165:69 | x | provenance | | +| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:164:7:164:7 | *templateFunction3 | provenance | | +| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | | +| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | provenance | | +| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:53 | +| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:170:10:170:18 | call to ymlSource | provenance | Src:MaD:25 | +| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:172:51:172:51 | x | provenance | | +| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | | +| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:173:10:173:10 | y | provenance | Sink:MaD:1 | +| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | provenance | | +| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:53 | | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:33 | | windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 | | windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | | @@ -501,20 +521,41 @@ nodes | test.cpp:119:10:119:11 | y2 | semmle.label | y2 | | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | semmle.label | [summary param] 0 in templateFunction | | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | semmle.label | [summary] to write: ReturnValue in templateFunction | -| test.cpp:130:10:130:18 | call to ymlSource | semmle.label | call to ymlSource | -| test.cpp:130:10:130:18 | call to ymlSource | semmle.label | call to ymlSource | -| test.cpp:131:13:131:43 | call to templateFunction | semmle.label | call to templateFunction | -| test.cpp:131:13:131:43 | call to templateFunction | semmle.label | call to templateFunction | -| test.cpp:131:45:131:45 | x | semmle.label | x | -| test.cpp:132:10:132:10 | y | semmle.label | y | -| test.cpp:137:4:137:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function | -| test.cpp:137:4:137:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function | -| test.cpp:143:10:143:18 | call to ymlSource | semmle.label | call to ymlSource | -| test.cpp:143:10:143:18 | call to ymlSource | semmle.label | call to ymlSource | -| test.cpp:145:10:145:27 | call to function | semmle.label | call to function | -| test.cpp:145:10:145:27 | call to function | semmle.label | call to function | -| test.cpp:145:26:145:26 | x | semmle.label | x | -| test.cpp:146:10:146:10 | z | semmle.label | z | +| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | semmle.label | [summary param] 1 in templateFunction2 | +| test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | semmle.label | [summary] to write: ReturnValue in templateFunction2 | +| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction | +| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction | +| test.cpp:134:45:134:45 | x | semmle.label | x | +| test.cpp:135:10:135:10 | y | semmle.label | y | +| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function | +| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function | +| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function | +| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function | +| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:148:10:148:27 | call to function | semmle.label | call to function | +| test.cpp:148:10:148:27 | call to function | semmle.label | call to function | +| test.cpp:148:26:148:26 | x | semmle.label | x | +| test.cpp:149:10:149:10 | z | semmle.label | z | +| test.cpp:155:10:155:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:155:10:155:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:157:13:157:20 | call to function | semmle.label | call to function | +| test.cpp:157:13:157:20 | call to function | semmle.label | call to function | +| test.cpp:157:26:157:26 | x | semmle.label | x | +| test.cpp:158:10:158:10 | z | semmle.label | z | +| test.cpp:164:7:164:7 | *templateFunction3 | semmle.label | *templateFunction3 | +| test.cpp:164:34:164:34 | x | semmle.label | x | +| test.cpp:165:12:165:64 | call to templateFunction2 | semmle.label | call to templateFunction2 | +| test.cpp:165:12:165:64 | call to templateFunction2 | semmle.label | call to templateFunction2 | +| test.cpp:165:69:165:69 | x | semmle.label | x | +| test.cpp:170:10:170:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:170:10:170:18 | call to ymlSource | semmle.label | call to ymlSource | +| test.cpp:172:13:172:44 | call to templateFunction3 | semmle.label | call to templateFunction3 | +| test.cpp:172:13:172:44 | call to templateFunction3 | semmle.label | call to templateFunction3 | +| test.cpp:172:51:172:51 | x | semmle.label | x | +| test.cpp:173:10:173:10 | y | semmle.label | y | | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA | | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA | | windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA | @@ -720,8 +761,11 @@ subpaths | test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | | test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | -| test.cpp:131:45:131:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | test.cpp:131:13:131:43 | call to templateFunction | -| test.cpp:145:26:145:26 | x | test.cpp:137:4:137:11 | [summary param] 1 in function | test.cpp:137:4:137:11 | [summary] to write: ReturnValue in function | test.cpp:145:10:145:27 | call to function | +| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | test.cpp:134:13:134:43 | call to templateFunction | +| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:148:10:148:27 | call to function | +| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:157:13:157:20 | call to function | +| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 | +| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | test.cpp:164:7:164:7 | *templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 | | windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | | windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | | windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml b/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml index dfa9b981ef1..76d649152bd 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml @@ -20,4 +20,5 @@ extensions: - ["", "", False, "callWithArgument", "", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"] - ["", "", False, "callWithNonTypeTemplate", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"] - ["", "TemplateClass1", False, "templateFunction", "(T,U)", "", "Argument[0]", "ReturnValue", "value", "manual"] - - ["", "TemplateClass2", False, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"] \ No newline at end of file + - ["", "TemplateClass1", True, "templateFunction2", "(U,V)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["", "TemplateClass2", True, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/external-models/sinks.expected b/cpp/ql/test/library-tests/dataflow/external-models/sinks.expected index 379ce723806..03a0d442c1c 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/sinks.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/sinks.expected @@ -15,5 +15,7 @@ | test.cpp:89:11:89:11 | y | test-sink | | test.cpp:116:10:116:11 | y1 | test-sink | | test.cpp:119:10:119:11 | y2 | test-sink | -| test.cpp:132:10:132:10 | y | test-sink | -| test.cpp:146:10:146:10 | z | test-sink | +| test.cpp:135:10:135:10 | y | test-sink | +| test.cpp:149:10:149:10 | z | test-sink | +| test.cpp:158:10:158:10 | z | test-sink | +| test.cpp:173:10:173:10 | y | test-sink | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected index f13d75bc66b..4040cff4fd2 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected @@ -9,8 +9,10 @@ | test.cpp:56:8:56:16 | call to ymlSource | local | | test.cpp:94:10:94:18 | call to ymlSource | local | | test.cpp:114:10:114:18 | call to ymlSource | local | -| test.cpp:130:10:130:18 | call to ymlSource | local | -| test.cpp:143:10:143:18 | call to ymlSource | local | +| test.cpp:133:10:133:18 | call to ymlSource | local | +| test.cpp:146:10:146:18 | call to ymlSource | local | +| test.cpp:155:10:155:18 | call to ymlSource | local | +| test.cpp:170:10:170:18 | call to ymlSource | local | | windows.cpp:22:15:22:29 | *call to GetCommandLineA | local | | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local | | windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/test.cpp b/cpp/ql/test/library-tests/dataflow/external-models/test.cpp index fb9b6ceb0e7..01bf6cc4093 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/external-models/test.cpp @@ -123,6 +123,9 @@ template struct TemplateClass1 { template U templateFunction(T, U); + + template + V templateFunction2(U, V); }; void test_template_function_in_template_class() { @@ -139,9 +142,33 @@ struct TemplateClass2 { template using PartialInstantiationOfTemplateClass2 = TemplateClass2; -void test_partial_instantiation() { +void test_partial_class_instantiation() { int x = ymlSource(); PartialInstantiationOfTemplateClass2 y; int z = y.function(0UL, x); ymlSink(z); // $ ir +} + +template struct DeriveFromFromPartialTemplateInstantiation : TemplateClass2 { }; + +void test_inheritance() { + int x = ymlSource(); + DeriveFromFromPartialTemplateInstantiation y; + auto z = y.function(0L, x); + ymlSink(z); // $ ir +} + +template +struct Class1 : TemplateClass1 { + template + int templateFunction3(U u, int x) { + return TemplateClass1::template templateFunction2(u, x); + } +}; + +void test_class1() { + int x = ymlSource(); + Class1 c; + auto y = c.templateFunction3(0UL, x); + ymlSink(y); // $ ir } \ No newline at end of file From b38440490aa08908676522e16dd3683174f16de9 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Sun, 31 May 2026 21:41:57 +0100 Subject: [PATCH 154/226] Address review comment --- .../python/dataflow/new/internal/TaintTrackingPrivate.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 7f25d276c07..636e65dc088 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -190,7 +190,11 @@ predicate stringManipulation(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeT predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { exists(DataFlow::ContentSet contentSet | DataFlowPrivate::readStep(nodeFrom, contentSet, nodeTo) and - defaultTaintReadContent(contentSet) + exists(DataFlow::Content c | c = contentSet.getAReadContent() | + c instanceof DataFlow::TupleElementContent or + c instanceof DataFlow::DictionaryElementContent or + c instanceof DataFlow::DictionaryElementAnyContent + ) ) } From d2f474d998802eee8172fa9cdc0c12cbbda51236 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 29 May 2026 14:39:35 +0200 Subject: [PATCH 155/226] Address review comments --- rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll | 4 +++- shared/namebinding/codeql/namebinding/LocalNameBinding.qll | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 0327509c465..80f2259623b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -381,7 +381,9 @@ module Impl { class NestedFunctionAccess extends LocalAccess { private Function f; + NestedFunctionAccess() { f = super.getLocal().getDefiningNode() } + /** Gets the function being accessed. */ - Function getFunction() { result = super.getLocal().getDefiningNode() } + Function getFunction() { result = f } } } diff --git a/shared/namebinding/codeql/namebinding/LocalNameBinding.qll b/shared/namebinding/codeql/namebinding/LocalNameBinding.qll index 298f498e331..a467568f983 100644 --- a/shared/namebinding/codeql/namebinding/LocalNameBinding.qll +++ b/shared/namebinding/codeql/namebinding/LocalNameBinding.qll @@ -46,6 +46,10 @@ signature module LocalNameBindingInputSig { * // x is not in scope here * } * ``` + * + * If a local declaration inside the condition is a shadowing sibling declaration + * (see below), then it should use the declaration itself as scope, otherwise it + * should use the condition as scope. */ class Conditional extends AstNode { /** Gets the condition of this conditional. */ @@ -153,8 +157,6 @@ module LocalNameBinding implicitDeclInScope(_, this) or isTopScope(this) - or - lookupStartsAt(_, this) } } From c695c151ead63d2242d3fbf8b517da328246f226 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 1 Jun 2026 09:14:26 +0200 Subject: [PATCH 156/226] Rust: Rename `Impl::getTrait` to `Impl::getTraitTy` --- rust/ast-generator/src/main.rs | 1 + rust/extractor/src/generated/.generated.list | 2 +- rust/extractor/src/generated/top.rs | 6 +++--- rust/extractor/src/translate/generated.rs | 4 ++-- rust/ql/.generated.list | 10 +++++----- rust/ql/lib/codeql/rust/elements/Impl.qll | 2 +- .../codeql/rust/elements/internal/ImplImpl.qll | 8 ++++---- .../rust/elements/internal/generated/Impl.qll | 12 ++++++------ .../elements/internal/generated/ParentChild.qll | 10 +++++----- .../rust/elements/internal/generated/Raw.qll | 16 ++++++++-------- .../lib/codeql/rust/internal/PathResolution.qll | 2 +- .../typeinference/BlanketImplementation.qll | 2 +- .../internal/typeinference/TypeInference.qll | 8 ++++---- rust/ql/lib/rust.dbscheme | 4 ++-- .../modelgenerator/internal/CaptureModels.qll | 2 +- .../canonical_path/canonical_paths.ql | 2 +- .../generated/.generated_tests.list | 2 +- .../extractor-tests/generated/Impl/Impl.expected | 2 +- .../test/extractor-tests/generated/Impl/Impl.ql | 4 ++-- .../extractor-tests/generated/Impl/gen_impl.rs | 2 +- .../macro-expansion/PrintAst.expected | 8 ++++---- rust/schema/annotations.py | 2 +- rust/schema/ast.py | 2 +- 23 files changed, 57 insertions(+), 56 deletions(-) diff --git a/rust/ast-generator/src/main.rs b/rust/ast-generator/src/main.rs index b1de337f3ac..bcdab28dd62 100644 --- a/rust/ast-generator/src/main.rs +++ b/rust/ast-generator/src/main.rs @@ -45,6 +45,7 @@ fn property_name(type_name: &str, field_name: &str) -> String { (_, "ty") => "type_repr", ("Function", "body") => "function_body", ("ClosureExpr", "body") => "closure_body", + ("Impl", "trait_") => "trait_ty", _ if field_name.contains("record") => &field_name.replacen("record", "struct", 1), _ => field_name, }; diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index 89659a4811d..1cd4ba35b28 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1,2 @@ mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs ea9c28694da3d0e90d09fc7d31824e35817c34720ea91e7c8bf8e7e74ffe4ee8 ea9c28694da3d0e90d09fc7d31824e35817c34720ea91e7c8bf8e7e74ffe4ee8 +top.rs 2e8e3b4e42b172708bb3a6ec3a92a6577c576887019603ca3d0f045bbdbfdbac 2e8e3b4e42b172708bb3a6ec3a92a6577c576887019603ca3d0f045bbdbfdbac diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index 1c4fd0f00d6..b4a463bb4c7 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -9451,7 +9451,7 @@ pub struct Impl { pub is_default: bool, pub is_unsafe: bool, pub self_ty: Option>, - pub trait_: Option>, + pub trait_ty: Option>, pub visibility: Option>, pub where_clause: Option>, } @@ -9484,8 +9484,8 @@ impl trap::TrapEntry for Impl { if let Some(v) = self.self_ty { out.add_tuple("impl_self_ties", vec![id.into(), v.into()]); } - if let Some(v) = self.trait_ { - out.add_tuple("impl_traits", vec![id.into(), v.into()]); + if let Some(v) = self.trait_ty { + out.add_tuple("impl_trait_ties", vec![id.into(), v.into()]); } if let Some(v) = self.visibility { out.add_tuple("impl_visibilities", vec![id.into(), v.into()]); diff --git a/rust/extractor/src/translate/generated.rs b/rust/extractor/src/translate/generated.rs index e6cc06419fc..30ac31db712 100644 --- a/rust/extractor/src/translate/generated.rs +++ b/rust/extractor/src/translate/generated.rs @@ -1229,7 +1229,7 @@ impl Translator<'_> { let is_default = node.default_token().is_some(); let is_unsafe = node.unsafe_token().is_some(); let self_ty = node.self_ty().and_then(|x| self.emit_type(&x)); - let trait_ = node.trait_().and_then(|x| self.emit_type(&x)); + let trait_ty = node.trait_().and_then(|x| self.emit_type(&x)); let visibility = node.visibility().and_then(|x| self.emit_visibility(&x)); let where_clause = node.where_clause().and_then(|x| self.emit_where_clause(&x)); let label = self.trap.emit(generated::Impl { @@ -1241,7 +1241,7 @@ impl Translator<'_> { is_default, is_unsafe, self_ty, - trait_, + trait_ty, visibility, where_clause, }); diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 003ede90023..b7be8b26c70 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -69,7 +69,7 @@ lib/codeql/rust/elements/GenericParam.qll 87adf96aac385f2a182008a7b90aad46cf46d7 lib/codeql/rust/elements/GenericParamList.qll 25fcaa68bc7798d75974d12607fae0afc7f84d43091b2d0c66a504095ef05667 3b71115c6af0b8e7f84d8c2d5ac9f23595ad2b22dbd19a9ea71906ca99340878 lib/codeql/rust/elements/IdentPat.qll ad5f202316d4eeee3ca81ea445728f4ad7eb6bb7d81232bc958c22a93d064bf2 7ce2772e391e593d8fd23b2b44e26d0d7e780327ec973fcc9dce52a75fda0e36 lib/codeql/rust/elements/IfExpr.qll f62153e8098b3eb08b569d4e25c750bc686665651579db4bc9e11dcef8e75d63 55006a55d612f189e73caa02f7b4deda388c692f0a801cdda9f833f2afdca778 -lib/codeql/rust/elements/Impl.qll ce5225fd97b184db7235bcf2561cf23c679de2fc96fecaeb8cbcf7935dd48fbd 3fe755118c3d0b1eb626f359da362ad75dbdcd1e09f09825b10038fb41ddb35c +lib/codeql/rust/elements/Impl.qll 0d69c9ace5dac87ed095cfd5d4a8baf7e17ebce1132f3a7d6fa2bf4325deff8d d908fc5da7d3a59fb0a286a6ce581bdabdb48c4ac6ecd070455c271c2352208c lib/codeql/rust/elements/ImplTraitTypeRepr.qll 1d559b16c659f447a1bde94cc656718f20f133f767060437b755ac81eea9f852 de69c596701f0af4db28c5802d092a39c88a90bf42ea85aea25eecb79417e454 lib/codeql/rust/elements/IndexExpr.qll 0e2e9f018d06ae72be0fc4ddbc019a9aacd8a06f42b4c4431760bd149e7f2290 2bcfd557abd53a48e48de7915c4f2089107c62dfb3e732a904848248dfd3727b lib/codeql/rust/elements/InferTypeRepr.qll 1b8bdcb574a7b6e7dd49f4cfb96655a6ccc355744b424b8c2593fe8218090d53 c20a2a5b0346dc277721deb450e732a47812c8e872ffb60aaba351b1708e9477 @@ -512,7 +512,7 @@ lib/codeql/rust/elements/internal/generated/GenericParam.qll 85ac027a42b3300febc lib/codeql/rust/elements/internal/generated/GenericParamList.qll b18fa5fd435d94857c9863bbcc40571af0b1efba1b31ba9159c95568f5c58fce 6e70f1e9a1823d28d60e0e753ac8fbbe8deb10c94365f893b0c8f8ea4061b460 lib/codeql/rust/elements/internal/generated/IdentPat.qll 1fe5061759848fdc9588b27606efb1187ce9c13d12ad0a2a19666d250dd62db3 87dbc8b88c31079076a896b48e0c483a600d7d11c1c4bf266581bdfc9c93ae98 lib/codeql/rust/elements/internal/generated/IfExpr.qll 413dd7a20c6b98c0d2ad2e5b50981c14bf96c1a719ace3e341d78926219a5af7 c9a2d44e3baa6a265a29a683ca3c1683352457987c92f599c5771b4f3b4bafff -lib/codeql/rust/elements/internal/generated/Impl.qll 5afadb7f80c5ffbd5cd3816c6788ccb605fe4cb2d8c8507ec3f212913eac0ab5 761b72a5f35e2e766de6aa87d83b065f49b64f05b91ae47d0afbb20bb61c1003 +lib/codeql/rust/elements/internal/generated/Impl.qll bdc3da08b23ab098e92927a57c2e99eeb78ea8561cf11accc51db3033492b500 4b45be6b0c51f03999619705104574d78c262ed2497921f2ca8696844b17addc lib/codeql/rust/elements/internal/generated/ImplTraitTypeRepr.qll e376a2e34ba51df403d42b02afe25140543e3e53aaf04b9ea118eb575acb4644 dc3a7e3eac758423c90a9803cc40dfdf53818bd62ee894982cd636f6b1596dfc lib/codeql/rust/elements/internal/generated/IndexExpr.qll cf951fc40f6690e966b4dc78fa9a6221aa5c6cade44759dcb52254f799292d11 1572e71918cc4e0b7e028331b6d98c9db23100a3646cd3874d1915e06ab6211d lib/codeql/rust/elements/internal/generated/InferTypeRepr.qll 4f101c1cb1278e919f9195cac4aa0c768e304c1881394b500874e7627e62d6c4 dca3f85d0a78ecc8bf030b4324f0d219ffff60784a2ecf565a4257e888dea0ff @@ -558,7 +558,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll eaa0cd4402d3665013d47e lib/codeql/rust/elements/internal/generated/ParenExpr.qll 812d2ff65079277f39f15c084657a955a960a7c1c0e96dd60472a58d56b945eb eb8c607f43e1fcbb41f37a10de203a1db806690e10ff4f04d48ed874189cb0eb lib/codeql/rust/elements/internal/generated/ParenPat.qll 24f9dc7fce75827d6fddb856cd48f80168143151b27295c0bab6db5a06567a09 ebadbc6f5498e9ed754b39893ce0763840409a0721036a25b56e1ead7dcc09aa lib/codeql/rust/elements/internal/generated/ParenTypeRepr.qll 03f5c5b96a37adeb845352d7fcea3e098da9050e534972d14ac0f70d60a2d776 ed3d6e5d02086523087adebce4e89e35461eb95f2a66d1d4100fe23fc691b126 -lib/codeql/rust/elements/internal/generated/ParentChild.qll b0e3c13b2ca75faaf0d92b2ca3d70cac7b78b3729aaccf635063cc5836c163af a340e8f34a6d7425f38845e789b4aeb83aec90c11429a68ad6632a5aa132fa57 +lib/codeql/rust/elements/internal/generated/ParentChild.qll dc5e9e16e0d43cf25ebdce03b84aa3bf0f52fe0c61de4db4a9887c961290b37e b26f0f2c27b664d0fe53aba35955df31a58adad0963a951039b6c6bbd34f83ea lib/codeql/rust/elements/internal/generated/ParenthesizedArgList.qll d901fdc8142a5b8847cc98fc2afcfd16428b8ace4fbffb457e761b5fd3901a77 5dbb0aea5a13f937da666ccb042494af8f11e776ade1459d16b70a4dd193f9fb lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll 9b12afb46fc5a9ad3a811b05472621bbecccb900c47504feb7f29d96b28421ca bcacbffc36fb3e0c9b26523b5963af0ffa9fd6b19f00a2a31bdb2316071546bd @@ -573,7 +573,7 @@ lib/codeql/rust/elements/internal/generated/PtrTypeRepr.qll 8d0ea4f6c7f8203340bf lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll 80826a6a6868a803aa2372e31c52a03e1811a3f1f2abdb469f91ca0bfdd9ecb6 34ee1e208c1690cba505dff2c588837c0cd91e185e2a87d1fe673191962276a9 -lib/codeql/rust/elements/internal/generated/Raw.qll 6e32bd7167d3eece2d22f893a92410129b1bd18e59533b1cf82f72f31465b43a bb25c56118df0e2755be2350cf307c19e6c4d85b2a39388c08f2cc1bad303692 +lib/codeql/rust/elements/internal/generated/Raw.qll 6e38ac8ae1fbd7af0dd516f1c37e52e6ef1169103ad7dd998796ff8cd2dbac7a f4a7515e1757404b101ea3c8bb154d11d1babb138cb2afddf1618eab377d9625 lib/codeql/rust/elements/internal/generated/RefExpr.qll 7d995884e3dc1c25fc719f5d7253179344d63650e217e9ff6530285fe7a57f64 f2c3c12551deea4964b66553fb9b6423ee16fec53bd63db4796191aa60dc6c66 lib/codeql/rust/elements/internal/generated/RefPat.qll 456ede39837463ee22a630ec7ab6c8630d3664a8ea206fcc6e4f199e92fa564c 5622062765f32930465ba6b170e986706f159f6070f48adee3c20e24e8df4e05 lib/codeql/rust/elements/internal/generated/RefTypeRepr.qll 5b0663a6d234572fb3e467e276d019415caa95ef006438cc59b7af4e1783161e 0e27c8a8f0e323c0e4d6db01fca821bf07c0864d293cdf96fa891b10820c1e4b @@ -693,7 +693,7 @@ test/extractor-tests/generated/GenericArgList/GenericArgList.ql 9bd6873e56a381a6 test/extractor-tests/generated/GenericParamList/GenericParamList.ql 206f270690f5c142777d43cf87b65d6dda5ec9f3953c17ee943fe3d0e7b7761c 38a6e0bbca916778f85b106609df6d5929baed006d55811ec0d71c75fe137e92 test/extractor-tests/generated/IdentPat/IdentPat.ql 23006eddf0ca1188e11ba5ee25ad62a83157b83e0b99119bf924c7f74fd8e70d 6e572f48f607f0ced309113304019ccc0a828f6ddd71e818369504dcf832a0b5 test/extractor-tests/generated/IfExpr/IfExpr.ql 540b21838ad3e1ed879b66c1903eb8517d280f99babcbf3c5307c278db42f003 a6f84a7588ce7587936f24375518a365c571210844b99cb614596e14dd5e4dfd -test/extractor-tests/generated/Impl/Impl.ql a36ea392729a6be3ee0cc0d8871b3682cf8f0c15fb657d4d35f2ca76eeef3a74 1fa345ca3b4c16c740b5684c7fdaf1116d52c2932287703b33143a08e4d7d38e +test/extractor-tests/generated/Impl/Impl.ql c96ec30d703aa607b7aad9f6eaca1b0069799cdefcc1481f4aa4f7378f477f7f 3528e1502b6f7b323d964630ecfb8255f683486b75300457e2a2d95aa36771f3 test/extractor-tests/generated/ImplTraitTypeRepr/ImplTraitTypeRepr.ql 311c6c1e18bd74fbcd367f940d2cf91777eaba6b3d6307149beb529216d086fb 16c7c81618d7f49da30b4f026dcacfb23ed130dbfcfa19b5cb44dc6e15101401 test/extractor-tests/generated/IndexExpr/IndexExpr.ql ecfca80175a78b633bf41684a0f8f5eebe0b8a23f8de9ff27142936687711263 27d4832911f7272376a199550d57d8488e75e0eeeeb7abbfb3b135350a30d277 test/extractor-tests/generated/InferTypeRepr/InferTypeRepr.ql 6ba01a9e229e7dfdb2878a0bdbeb6c0888c4a068984b820e7a48d4b84995daa2 7120cafd267e956dbb4af5e19d57237275d334ffe5ff0fb635d65d309381aa46 diff --git a/rust/ql/lib/codeql/rust/elements/Impl.qll b/rust/ql/lib/codeql/rust/elements/Impl.qll index a1567f31582..3324e05dc51 100644 --- a/rust/ql/lib/codeql/rust/elements/Impl.qll +++ b/rust/ql/lib/codeql/rust/elements/Impl.qll @@ -13,7 +13,7 @@ import codeql.rust.elements.Visibility import codeql.rust.elements.WhereClause /** - * An `impl`` block. + * An `impl` block. * * For example: * ```rust diff --git a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll index 3ff04276c63..54bf6932420 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll @@ -13,7 +13,7 @@ private import codeql.rust.elements.internal.generated.Impl module Impl { // the following QLdoc is generated: if you need to edit it, do it in the schema file /** - * An `impl`` block. + * An `impl` block. * * For example: * ```rust @@ -26,9 +26,9 @@ module Impl { override string toStringImpl() { exists(string trait | ( - trait = this.getTrait().toAbbreviatedString() + " for " + trait = this.getTraitTy().toAbbreviatedString() + " for " or - not this.hasTrait() and trait = "" + not this.hasTraitTy() and trait = "" ) and result = "impl " + trait + this.getSelfTy().toAbbreviatedString() + " { ... }" ) @@ -38,6 +38,6 @@ module Impl { * Holds if this is an inherent `impl` block, that is, one that does not implement a trait. */ pragma[nomagic] - predicate isInherent() { not this.hasTrait() } + predicate isInherent() { not this.hasTraitTy() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Impl.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Impl.qll index ad307cb177f..915e8940fb0 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Impl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Impl.qll @@ -20,7 +20,7 @@ import codeql.rust.elements.WhereClause */ module Generated { /** - * An `impl`` block. + * An `impl` block. * * For example: * ```rust @@ -109,16 +109,16 @@ module Generated { final predicate hasSelfTy() { exists(this.getSelfTy()) } /** - * Gets the trait of this impl, if it exists. + * Gets the trait ty of this impl, if it exists. */ - TypeRepr getTrait() { - result = Synth::convertTypeReprFromRaw(Synth::convertImplToRaw(this).(Raw::Impl).getTrait()) + TypeRepr getTraitTy() { + result = Synth::convertTypeReprFromRaw(Synth::convertImplToRaw(this).(Raw::Impl).getTraitTy()) } /** - * Holds if `getTrait()` exists. + * Holds if `getTraitTy()` exists. */ - final predicate hasTrait() { exists(this.getTrait()) } + final predicate hasTraitTy() { exists(this.getTraitTy()) } /** * Gets the visibility of this impl, if it exists. diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index c593451b993..344898886c1 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -2328,7 +2328,7 @@ private module Impl { private Element getImmediateChildOfImpl(Impl e, int index, string partialPredicateCall) { exists( int n, int nAttributeMacroExpansion, int nAssocItemList, int nAttr, int nGenericParamList, - int nSelfTy, int nTrait, int nVisibility, int nWhereClause + int nSelfTy, int nTraitTy, int nVisibility, int nWhereClause | n = 0 and nAttributeMacroExpansion = n + 1 and @@ -2336,8 +2336,8 @@ private module Impl { nAttr = nAssocItemList + e.getNumberOfAttrs() and nGenericParamList = nAttr + 1 and nSelfTy = nGenericParamList + 1 and - nTrait = nSelfTy + 1 and - nVisibility = nTrait + 1 and + nTraitTy = nSelfTy + 1 and + nVisibility = nTraitTy + 1 and nWhereClause = nVisibility + 1 and ( none() @@ -2359,9 +2359,9 @@ private module Impl { or index = nGenericParamList and result = e.getSelfTy() and partialPredicateCall = "SelfTy()" or - index = nSelfTy and result = e.getTrait() and partialPredicateCall = "Trait()" + index = nSelfTy and result = e.getTraitTy() and partialPredicateCall = "TraitTy()" or - index = nTrait and result = e.getVisibility() and partialPredicateCall = "Visibility()" + index = nTraitTy and result = e.getVisibility() and partialPredicateCall = "Visibility()" or index = nVisibility and result = e.getWhereClause() and diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 01f54e7ab60..c2baf289b2e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -6209,7 +6209,7 @@ module Raw { /** * INTERNAL: Do not use. - * An `impl`` block. + * An `impl` block. * * For example: * ```rust @@ -6262,9 +6262,9 @@ module Raw { TypeRepr getSelfTy() { impl_self_ties(this, result) } /** - * Gets the trait of this impl, if it exists. + * Gets the trait ty of this impl, if it exists. */ - TypeRepr getTrait() { impl_traits(this, result) } + TypeRepr getTraitTy() { impl_trait_ties(this, result) } /** * Gets the visibility of this impl, if it exists. @@ -6280,7 +6280,7 @@ module Raw { private Element getImmediateChildOfImpl(Impl e, int index) { exists( int n, int nAttributeMacroExpansion, int nAssocItemList, int nAttr, int nGenericParamList, - int nSelfTy, int nTrait, int nVisibility, int nWhereClause + int nSelfTy, int nTraitTy, int nVisibility, int nWhereClause | n = 0 and nAttributeMacroExpansion = n + 1 and @@ -6288,8 +6288,8 @@ module Raw { nAttr = nAssocItemList + e.getNumberOfAttrs() and nGenericParamList = nAttr + 1 and nSelfTy = nGenericParamList + 1 and - nTrait = nSelfTy + 1 and - nVisibility = nTrait + 1 and + nTraitTy = nSelfTy + 1 and + nVisibility = nTraitTy + 1 and nWhereClause = nVisibility + 1 and ( none() @@ -6304,9 +6304,9 @@ module Raw { or index = nGenericParamList and result = e.getSelfTy() or - index = nSelfTy and result = e.getTrait() + index = nSelfTy and result = e.getTraitTy() or - index = nTrait and result = e.getVisibility() + index = nTraitTy and result = e.getVisibility() or index = nVisibility and result = e.getWhereClause() ) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 10d18786880..f3e29b97aab 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -806,7 +806,7 @@ private TypeItemNode resolveBuiltin(TypeRepr tr) { final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl { Path getSelfPath() { result = super.getSelfTy().(PathTypeRepr).getPath() } - Path getTraitPath() { result = super.getTrait().(PathTypeRepr).getPath() } + Path getTraitPath() { result = super.getTraitTy().(PathTypeRepr).getPath() } TypeItemNode resolveSelfTyBuiltin() { result = resolveBuiltin(this.(Impl).getSelfTy()) } diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll b/rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll index 86bcdbe4fe8..7c56300f358 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll @@ -42,7 +42,7 @@ private predicate hasFirstNonTrivialTraitBound(TypeParamItemNode tp, Path traitB */ pragma[nomagic] predicate isBlanketLike(ImplItemNode i, TypePath blanketSelfPath, TypeParam blanketTypeParam) { - i.(Impl).hasTrait() and + i.(Impl).hasTraitTy() and ( blanketTypeParam = i.getBlanketImplementationTypeParam() and blanketSelfPath.isEmpty() diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll index fd99060d404..b5ed2be06f9 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll @@ -174,7 +174,7 @@ private module Input2Common { exists(Impl impl | abs = impl and condition = impl.getSelfTy() and - constraint = impl.getTrait() + constraint = impl.getTraitTy() ) or transitive = true and @@ -1542,7 +1542,7 @@ private module AssocFunctionResolution { boolean hasReceiver | afc.hasSyntacticInfo(name, arity, typeQualifier, traitQualifier, hasReceiver) and - if not afc.hasATrait() and i.(Impl).hasTrait() + if not afc.hasATrait() and i.(Impl).hasTraitTy() then callVisibleImplTraitCandidate(afc, i) else any() | @@ -2532,7 +2532,7 @@ private module AssocFunctionResolution { AssocFunctionCallCand afcc, TypeAbstraction abs, AssocFunctionType constraint ) { potentialInstantiationOf0(afcc, abs, constraint) and - if abs.(Impl).hasTrait() + if abs.(Impl).hasTraitTy() then // inherent functions take precedence over trait functions, so only allow // trait functions when there are no matching inherent functions @@ -2584,7 +2584,7 @@ private module AssocFunctionResolution { exists(AssocFunctionCall afc, FunctionPosition selfPos | afcc = MkAssocFunctionCallCand(afc, selfPos, _, _) and blanketLikeCandidate(afc, _, selfPos, abs, constraint, _, _) and - if abs.(Impl).hasTrait() + if abs.(Impl).hasTraitTy() then // inherent functions take precedence over trait functions, so only allow // trait functions when there are no matching inherent functions diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index 66a48986364..77e9a70be4b 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -2907,9 +2907,9 @@ impl_self_ties( ); #keyset[id] -impl_traits( +impl_trait_ties( int id: @impl ref, - int trait: @type_repr ref + int trait_ty: @type_repr ref ); #keyset[id] diff --git a/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll index 8ec2f3354db..498195bdb8b 100644 --- a/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -26,7 +26,7 @@ private newtype TCallable = or // If a method implements a public trait it is exposed through the trait. // We overapproximate this by including all trait method implementations. - exists(R::Impl impl | impl.hasTrait() and impl.getAssocItemList().getAssocItem(_) = api) + exists(R::Impl impl | impl.hasTraitTy() and impl.getAssocItemList().getAssocItem(_) = api) ) } diff --git a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.ql b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.ql index e8b075ba482..90c01ff3a65 100644 --- a/rust/ql/test/extractor-tests/canonical_path/canonical_paths.ql +++ b/rust/ql/test/extractor-tests/canonical_path/canonical_paths.ql @@ -11,7 +11,7 @@ query predicate canonicalPath(Addressable a, string path) { a = any(ImplItemNode i | i.resolveSelfTy() instanceof Str and - not i.(Impl).hasTrait() + not i.(Impl).hasTraitTy() ).getAnAssocItem() and a.(Function).getName().getText() = "trim" ) and diff --git a/rust/ql/test/extractor-tests/generated/.generated_tests.list b/rust/ql/test/extractor-tests/generated/.generated_tests.list index 73e2a1b767d..0d23450af31 100644 --- a/rust/ql/test/extractor-tests/generated/.generated_tests.list +++ b/rust/ql/test/extractor-tests/generated/.generated_tests.list @@ -52,7 +52,7 @@ GenericArgList/gen_generic_arg_list.rs cfb072d3b48f9dd568c23d4dfefba28766628678f GenericParamList/gen_generic_param_list.rs 3a1981a7c4731329ad6da0d887f09be04f31342d94f44711ac0ac455930f773a 3a1981a7c4731329ad6da0d887f09be04f31342d94f44711ac0ac455930f773a IdentPat/gen_ident_pat.rs 87f9201ca47683ff6f12a0c844c062fdedb6d86546794522d358b117ba0fe477 87f9201ca47683ff6f12a0c844c062fdedb6d86546794522d358b117ba0fe477 IfExpr/gen_if_expr.rs 2df66735394ebb20db29d3fbf2721ad4812afbe8d4614d03f26265c1f481f1e8 2df66735394ebb20db29d3fbf2721ad4812afbe8d4614d03f26265c1f481f1e8 -Impl/gen_impl.rs cfab33eb5e98b425b1d88be5f09f742be6c4f8d402e1becd4421aabb0431aadd cfab33eb5e98b425b1d88be5f09f742be6c4f8d402e1becd4421aabb0431aadd +Impl/gen_impl.rs a3f91dbcbb89f660e1c67eb6211def495cced5ab069515c6151e442365f64899 a3f91dbcbb89f660e1c67eb6211def495cced5ab069515c6151e442365f64899 ImplTraitTypeRepr/gen_impl_trait_type_repr.rs ebfa4d350ae5759bf7df6adf790d2d892c7a0d708f3340ccf3e12a681cb78f00 ebfa4d350ae5759bf7df6adf790d2d892c7a0d708f3340ccf3e12a681cb78f00 IndexExpr/gen_index_expr.rs 22d7f81ba43dc63f1f49e21a2c25ce25a1b8f6e8e95e1a66f518f010a4d73c61 22d7f81ba43dc63f1f49e21a2c25ce25a1b8f6e8e95e1a66f518f010a4d73c61 InferTypeRepr/gen_infer_type_repr.rs cd50eaeffdf16e0e896b14b665590251a4d383c123502ed667d8b1f75000f559 cd50eaeffdf16e0e896b14b665590251a4d383c123502ed667d8b1f75000f559 diff --git a/rust/ql/test/extractor-tests/generated/Impl/Impl.expected b/rust/ql/test/extractor-tests/generated/Impl/Impl.expected index ec5e5705529..125fa8bc380 100644 --- a/rust/ql/test/extractor-tests/generated/Impl/Impl.expected +++ b/rust/ql/test/extractor-tests/generated/Impl/Impl.expected @@ -7,7 +7,7 @@ getAttr getGenericParamList getSelfTy | gen_impl.rs:4:5:9:5 | impl MyTrait for MyType { ... } | gen_impl.rs:7:22:7:27 | MyType | -getTrait +getTraitTy | gen_impl.rs:4:5:9:5 | impl MyTrait for MyType { ... } | gen_impl.rs:7:10:7:16 | MyTrait | getVisibility getWhereClause diff --git a/rust/ql/test/extractor-tests/generated/Impl/Impl.ql b/rust/ql/test/extractor-tests/generated/Impl/Impl.ql index 1d73e09a1a7..0a791b4659d 100644 --- a/rust/ql/test/extractor-tests/generated/Impl/Impl.ql +++ b/rust/ql/test/extractor-tests/generated/Impl/Impl.ql @@ -38,8 +38,8 @@ query predicate getSelfTy(Impl x, TypeRepr getSelfTy) { toBeTested(x) and not x.isUnknown() and getSelfTy = x.getSelfTy() } -query predicate getTrait(Impl x, TypeRepr getTrait) { - toBeTested(x) and not x.isUnknown() and getTrait = x.getTrait() +query predicate getTraitTy(Impl x, TypeRepr getTraitTy) { + toBeTested(x) and not x.isUnknown() and getTraitTy = x.getTraitTy() } query predicate getVisibility(Impl x, Visibility getVisibility) { diff --git a/rust/ql/test/extractor-tests/generated/Impl/gen_impl.rs b/rust/ql/test/extractor-tests/generated/Impl/gen_impl.rs index 717d2e29b87..a59507ae29d 100644 --- a/rust/ql/test/extractor-tests/generated/Impl/gen_impl.rs +++ b/rust/ql/test/extractor-tests/generated/Impl/gen_impl.rs @@ -1,7 +1,7 @@ // generated by codegen, do not edit fn test_impl() -> () { - // An `impl`` block. + // An `impl` block. // // For example: impl MyTrait for MyType { diff --git a/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected b/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected index 6f0b278d062..f55dc031f41 100644 --- a/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected +++ b/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected @@ -797,7 +797,7 @@ macro_expansion.rs: # 84| getSegment(): [PathSegment] MyDerive::<...> # 83| getGenericArgList(): [GenericArgList] <...> # 84| getIdentifier(): [NameRef] MyDerive -# 83| getTrait(): [PathTypeRepr] ...::Debug +# 83| getTraitTy(): [PathTypeRepr] ...::Debug # 83| getPath(): [Path] ...::Debug # 83| getQualifier(): [Path] ...::fmt # 83| getQualifier(): [Path] $crate @@ -901,7 +901,7 @@ macro_expansion.rs: # 89| getSegment(): [PathSegment] MyDeriveEnum::<...> # 88| getGenericArgList(): [GenericArgList] <...> # 89| getIdentifier(): [NameRef] MyDeriveEnum -# 88| getTrait(): [PathTypeRepr] ...::PartialEq +# 88| getTraitTy(): [PathTypeRepr] ...::PartialEq # 88| getPath(): [Path] ...::PartialEq # 88| getQualifier(): [Path] ...::cmp # 88| getQualifier(): [Path] $crate @@ -921,7 +921,7 @@ macro_expansion.rs: # 89| getSegment(): [PathSegment] MyDeriveEnum::<...> # 88| getGenericArgList(): [GenericArgList] <...> # 89| getIdentifier(): [NameRef] MyDeriveEnum -# 88| getTrait(): [PathTypeRepr] ...::Eq +# 88| getTraitTy(): [PathTypeRepr] ...::Eq # 88| getPath(): [Path] ...::Eq # 88| getQualifier(): [Path] ...::cmp # 88| getQualifier(): [Path] $crate @@ -984,7 +984,7 @@ macro_expansion.rs: # 99| getPath(): [Path] MyDeriveUnion # 99| getSegment(): [PathSegment] MyDeriveUnion # 99| getIdentifier(): [NameRef] MyDeriveUnion -# 98| getTrait(): [PathTypeRepr] MyTrait +# 98| getTraitTy(): [PathTypeRepr] MyTrait # 98| getPath(): [Path] MyTrait # 98| getSegment(): [PathSegment] MyTrait # 98| getIdentifier(): [NameRef] MyTrait diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index 6fb45ae05b9..3a338202027 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1269,7 +1269,7 @@ class _: @annotate(Impl) class _: """ - An `impl`` block. + An `impl` block. For example: ```rust diff --git a/rust/schema/ast.py b/rust/schema/ast.py index 5d8a7393ea6..2599cd92c7b 100644 --- a/rust/schema/ast.py +++ b/rust/schema/ast.py @@ -312,7 +312,7 @@ class Impl(Item, ): is_default: predicate is_unsafe: predicate self_ty: optional["TypeRepr"] | child - trait_: optional["TypeRepr"] | child + trait_ty: optional["TypeRepr"] | child visibility: optional["Visibility"] | child where_clause: optional["WhereClause"] | child From 00e95a075733f9ed97d2ffcccbfee5c63d593d83 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 1 Jun 2026 09:34:49 +0200 Subject: [PATCH 157/226] Rust: Add `Impl::getSelf()` and `Impl::getTrait()` --- .../rust/elements/internal/ImplImpl.qll | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll index 54bf6932420..87c42ed7dad 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll @@ -4,7 +4,11 @@ * INTERNAL: Do not use. */ +private import rust private import codeql.rust.elements.internal.generated.Impl +private import codeql.rust.internal.PathResolution as PathResolution +private import codeql.rust.internal.typeinference.Type +private import codeql.rust.internal.typeinference.TypeMention /** * INTERNAL: This module contains the customizable definition of `Impl` and should not @@ -39,5 +43,39 @@ module Impl { */ pragma[nomagic] predicate isInherent() { not this.hasTraitTy() } + + /** + * Gets the type being implemented. + * + * For example, in + * + * ```rust + * impl MyType { ... } + * + * impl MyTrait for MyType { ... } + * ``` + * + * the type being implemented is in both cases`MyType`. + */ + TypeItem getSelf() { + result = this.getSelfTy().(TypeMention).getType().(DataType).getTypeItem() + } + + /** + * Gets the trait being implemented, if any. + * + * For example, in + * + * ```rust + * impl MyType { ... } + * + * impl MyTrait for MyType { ... } + * ``` + * + * the trait being implemented is in the second case `MyTrait`. + */ + Trait getTrait() { + result = PathResolution::resolvePath(this.getTraitTy().(PathTypeRepr).getPath()) + } } } From d5f94475b5648deae5660feea5262e8042677987 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 1 Jun 2026 09:42:43 +0200 Subject: [PATCH 158/226] Rust: DB upgrade/downgrade scripts --- .../old.dbscheme | 3556 +++++++++++++++++ .../rust.dbscheme | 3556 +++++++++++++++++ .../upgrade.properties | 5 + .../old.dbscheme | 3556 +++++++++++++++++ .../rust.dbscheme | 3556 +++++++++++++++++ .../upgrade.properties | 5 + 6 files changed, 14234 insertions(+) create mode 100644 rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/old.dbscheme create mode 100644 rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/rust.dbscheme create mode 100644 rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/upgrade.properties create mode 100644 rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/old.dbscheme create mode 100644 rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/rust.dbscheme create mode 100644 rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/upgrade.properties diff --git a/rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/old.dbscheme b/rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/old.dbscheme new file mode 100644 index 00000000000..77e9a70be4b --- /dev/null +++ b/rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/old.dbscheme @@ -0,0 +1,3556 @@ +// generated by codegen, do not edit + +// from ../shared/tree-sitter-extractor/src/generator/prefix.dbscheme +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ + +/** + * The CLI will automatically emit applicable tuples for this table, + * such as `databaseMetadata("isOverlay", "true")` when building an + * overlay database. + */ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Overlay support -*/ + +/** + * The CLI will automatically emit tuples for each new/modified/deleted file + * when building an overlay database. + */ +overlayChangedFiles( + string path: string ref +); + + +// from prefix.dbscheme +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_default ref +); + + +// from schema + +@element = + @extractor_step +| @locatable +| @named_crate +| @unextracted +; + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int duration_ms: int ref +); + +#keyset[id] +extractor_step_files( + int id: @extractor_step ref, + int file: @file ref +); + +@locatable = + @ast_node +| @crate +; + +named_crates( + unique int id: @named_crate, + string name: string ref, + int crate: @crate ref +); + +@unextracted = + @missing +| @unimplemented +; + +@ast_node = + @abi +| @addressable +| @arg_list +| @asm_dir_spec +| @asm_operand +| @asm_operand_expr +| @asm_option +| @asm_piece +| @asm_reg_spec +| @assoc_item_list +| @attr +| @callable +| @expr +| @extern_item_list +| @field_list +| @for_binder +| @format_args_arg +| @generic_arg +| @generic_arg_list +| @generic_param +| @generic_param_list +| @item_list +| @label +| @let_else +| @macro_items +| @match_arm +| @match_arm_list +| @match_guard +| @meta +| @name +| @param_base +| @param_list +| @parenthesized_arg_list +| @pat +| @path +| @path_ast_node +| @path_segment +| @rename +| @ret_type_repr +| @return_type_syntax +| @source_file +| @stmt +| @stmt_list +| @struct_expr_field +| @struct_expr_field_list +| @struct_field +| @struct_pat_field +| @struct_pat_field_list +| @token +| @token_tree +| @tuple_field +| @type_bound +| @type_bound_list +| @type_repr +| @use_bound_generic_arg +| @use_bound_generic_args +| @use_tree +| @use_tree_list +| @variant_list +| @visibility +| @where_clause +| @where_pred +; + +crates( + unique int id: @crate +); + +#keyset[id] +crate_names( + int id: @crate ref, + string name: string ref +); + +#keyset[id] +crate_versions( + int id: @crate ref, + string version: string ref +); + +#keyset[id, index] +crate_cfg_options( + int id: @crate ref, + int index: int ref, + string cfg_option: string ref +); + +#keyset[id, index] +crate_named_dependencies( + int id: @crate ref, + int index: int ref, + int named_dependency: @named_crate ref +); + +missings( + unique int id: @missing +); + +unimplementeds( + unique int id: @unimplemented +); + +abis( + unique int id: @abi +); + +#keyset[id] +abi_abi_strings( + int id: @abi ref, + string abi_string: string ref +); + +@addressable = + @item +| @variant +; + +arg_lists( + unique int id: @arg_list +); + +#keyset[id, index] +arg_list_args( + int id: @arg_list ref, + int index: int ref, + int arg: @expr ref +); + +asm_dir_specs( + unique int id: @asm_dir_spec +); + +@asm_operand = + @asm_const +| @asm_label +| @asm_reg_operand +| @asm_sym +; + +asm_operand_exprs( + unique int id: @asm_operand_expr +); + +#keyset[id] +asm_operand_expr_in_exprs( + int id: @asm_operand_expr ref, + int in_expr: @expr ref +); + +#keyset[id] +asm_operand_expr_out_exprs( + int id: @asm_operand_expr ref, + int out_expr: @expr ref +); + +asm_options( + unique int id: @asm_option +); + +#keyset[id] +asm_option_is_raw( + int id: @asm_option ref +); + +@asm_piece = + @asm_clobber_abi +| @asm_operand_named +| @asm_options_list +; + +asm_reg_specs( + unique int id: @asm_reg_spec +); + +#keyset[id] +asm_reg_spec_identifiers( + int id: @asm_reg_spec ref, + int identifier: @name_ref ref +); + +assoc_item_lists( + unique int id: @assoc_item_list +); + +#keyset[id, index] +assoc_item_list_assoc_items( + int id: @assoc_item_list ref, + int index: int ref, + int assoc_item: @assoc_item ref +); + +#keyset[id, index] +assoc_item_list_attrs( + int id: @assoc_item_list ref, + int index: int ref, + int attr: @attr ref +); + +attrs( + unique int id: @attr +); + +#keyset[id] +attr_meta( + int id: @attr ref, + int meta: @meta ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_param_lists( + int id: @callable ref, + int param_list: @param_list ref +); + +#keyset[id, index] +callable_attrs( + int id: @callable ref, + int index: int ref, + int attr: @attr ref +); + +@expr = + @array_expr_internal +| @asm_expr +| @await_expr +| @become_expr +| @binary_expr +| @break_expr +| @call_expr +| @cast_expr +| @closure_expr +| @continue_expr +| @field_expr +| @format_args_expr +| @if_expr +| @index_expr +| @labelable_expr +| @let_expr +| @literal_expr +| @macro_expr +| @match_expr +| @method_call_expr +| @offset_of_expr +| @paren_expr +| @path_expr_base +| @prefix_expr +| @range_expr +| @ref_expr +| @return_expr +| @struct_expr +| @try_expr +| @tuple_expr +| @underscore_expr +| @yeet_expr +| @yield_expr +; + +extern_item_lists( + unique int id: @extern_item_list +); + +#keyset[id, index] +extern_item_list_attrs( + int id: @extern_item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +extern_item_list_extern_items( + int id: @extern_item_list ref, + int index: int ref, + int extern_item: @extern_item ref +); + +@field_list = + @struct_field_list +| @tuple_field_list +; + +for_binders( + unique int id: @for_binder +); + +#keyset[id] +for_binder_generic_param_lists( + int id: @for_binder ref, + int generic_param_list: @generic_param_list ref +); + +format_args_args( + unique int id: @format_args_arg +); + +#keyset[id] +format_args_arg_exprs( + int id: @format_args_arg ref, + int expr: @expr ref +); + +#keyset[id] +format_args_arg_names( + int id: @format_args_arg ref, + int name: @name ref +); + +@generic_arg = + @assoc_type_arg +| @const_arg +| @lifetime_arg +| @type_arg +; + +generic_arg_lists( + unique int id: @generic_arg_list +); + +#keyset[id, index] +generic_arg_list_generic_args( + int id: @generic_arg_list ref, + int index: int ref, + int generic_arg: @generic_arg ref +); + +@generic_param = + @const_param +| @lifetime_param +| @type_param +; + +generic_param_lists( + unique int id: @generic_param_list +); + +#keyset[id, index] +generic_param_list_generic_params( + int id: @generic_param_list ref, + int index: int ref, + int generic_param: @generic_param ref +); + +item_lists( + unique int id: @item_list +); + +#keyset[id, index] +item_list_attrs( + int id: @item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +item_list_items( + int id: @item_list ref, + int index: int ref, + int item: @item ref +); + +labels( + unique int id: @label +); + +#keyset[id] +label_lifetimes( + int id: @label ref, + int lifetime: @lifetime ref +); + +let_elses( + unique int id: @let_else +); + +#keyset[id] +let_else_block_exprs( + int id: @let_else ref, + int block_expr: @block_expr ref +); + +macro_items( + unique int id: @macro_items +); + +#keyset[id, index] +macro_items_items( + int id: @macro_items ref, + int index: int ref, + int item: @item ref +); + +match_arms( + unique int id: @match_arm +); + +#keyset[id, index] +match_arm_attrs( + int id: @match_arm ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_arm_exprs( + int id: @match_arm ref, + int expr: @expr ref +); + +#keyset[id] +match_arm_guards( + int id: @match_arm ref, + int guard: @match_guard ref +); + +#keyset[id] +match_arm_pats( + int id: @match_arm ref, + int pat: @pat ref +); + +match_arm_lists( + unique int id: @match_arm_list +); + +#keyset[id, index] +match_arm_list_arms( + int id: @match_arm_list ref, + int index: int ref, + int arm: @match_arm ref +); + +#keyset[id, index] +match_arm_list_attrs( + int id: @match_arm_list ref, + int index: int ref, + int attr: @attr ref +); + +match_guards( + unique int id: @match_guard +); + +#keyset[id] +match_guard_conditions( + int id: @match_guard ref, + int condition: @expr ref +); + +meta( + unique int id: @meta +); + +#keyset[id] +meta_exprs( + int id: @meta ref, + int expr: @expr ref +); + +#keyset[id] +meta_is_unsafe( + int id: @meta ref +); + +#keyset[id] +meta_paths( + int id: @meta ref, + int path: @path ref +); + +#keyset[id] +meta_token_trees( + int id: @meta ref, + int token_tree: @token_tree ref +); + +names( + unique int id: @name +); + +#keyset[id] +name_texts( + int id: @name ref, + string text: string ref +); + +@param_base = + @param +| @self_param +; + +#keyset[id, index] +param_base_attrs( + int id: @param_base ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +param_base_type_reprs( + int id: @param_base ref, + int type_repr: @type_repr ref +); + +param_lists( + unique int id: @param_list +); + +#keyset[id, index] +param_list_params( + int id: @param_list ref, + int index: int ref, + int param: @param ref +); + +#keyset[id] +param_list_self_params( + int id: @param_list ref, + int self_param: @self_param ref +); + +parenthesized_arg_lists( + unique int id: @parenthesized_arg_list +); + +#keyset[id, index] +parenthesized_arg_list_type_args( + int id: @parenthesized_arg_list ref, + int index: int ref, + int type_arg: @type_arg ref +); + +@pat = + @box_pat +| @const_block_pat +| @ident_pat +| @literal_pat +| @macro_pat +| @or_pat +| @paren_pat +| @path_pat +| @range_pat +| @ref_pat +| @rest_pat +| @slice_pat +| @struct_pat +| @tuple_pat +| @tuple_struct_pat +| @wildcard_pat +; + +paths( + unique int id: @path +); + +#keyset[id] +path_qualifiers( + int id: @path ref, + int qualifier: @path ref +); + +#keyset[id] +path_segments_( + int id: @path ref, + int segment: @path_segment ref +); + +@path_ast_node = + @path_expr +| @path_pat +| @struct_expr +| @struct_pat +| @tuple_struct_pat +; + +#keyset[id] +path_ast_node_paths( + int id: @path_ast_node ref, + int path: @path ref +); + +path_segments( + unique int id: @path_segment +); + +#keyset[id] +path_segment_generic_arg_lists( + int id: @path_segment ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +path_segment_identifiers( + int id: @path_segment ref, + int identifier: @name_ref ref +); + +#keyset[id] +path_segment_parenthesized_arg_lists( + int id: @path_segment ref, + int parenthesized_arg_list: @parenthesized_arg_list ref +); + +#keyset[id] +path_segment_ret_types( + int id: @path_segment ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +path_segment_return_type_syntaxes( + int id: @path_segment ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +path_segment_type_reprs( + int id: @path_segment ref, + int type_repr: @type_repr ref +); + +#keyset[id] +path_segment_trait_type_reprs( + int id: @path_segment ref, + int trait_type_repr: @path_type_repr ref +); + +renames( + unique int id: @rename +); + +#keyset[id] +rename_names( + int id: @rename ref, + int name: @name ref +); + +ret_type_reprs( + unique int id: @ret_type_repr +); + +#keyset[id] +ret_type_repr_type_reprs( + int id: @ret_type_repr ref, + int type_repr: @type_repr ref +); + +return_type_syntaxes( + unique int id: @return_type_syntax +); + +source_files( + unique int id: @source_file +); + +#keyset[id, index] +source_file_attrs( + int id: @source_file ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +source_file_items( + int id: @source_file ref, + int index: int ref, + int item: @item ref +); + +@stmt = + @expr_stmt +| @item +| @let_stmt +; + +stmt_lists( + unique int id: @stmt_list +); + +#keyset[id, index] +stmt_list_attrs( + int id: @stmt_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +stmt_list_statements( + int id: @stmt_list ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +stmt_list_tail_exprs( + int id: @stmt_list ref, + int tail_expr: @expr ref +); + +struct_expr_fields( + unique int id: @struct_expr_field +); + +#keyset[id, index] +struct_expr_field_attrs( + int id: @struct_expr_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_expr_field_exprs( + int id: @struct_expr_field ref, + int expr: @expr ref +); + +#keyset[id] +struct_expr_field_identifiers( + int id: @struct_expr_field ref, + int identifier: @name_ref ref +); + +struct_expr_field_lists( + unique int id: @struct_expr_field_list +); + +#keyset[id, index] +struct_expr_field_list_attrs( + int id: @struct_expr_field_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +struct_expr_field_list_fields( + int id: @struct_expr_field_list ref, + int index: int ref, + int field: @struct_expr_field ref +); + +#keyset[id] +struct_expr_field_list_spreads( + int id: @struct_expr_field_list ref, + int spread: @expr ref +); + +struct_fields( + unique int id: @struct_field +); + +#keyset[id, index] +struct_field_attrs( + int id: @struct_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_defaults( + int id: @struct_field ref, + int default: @expr ref +); + +#keyset[id] +struct_field_is_unsafe( + int id: @struct_field ref +); + +#keyset[id] +struct_field_names( + int id: @struct_field ref, + int name: @name ref +); + +#keyset[id] +struct_field_type_reprs( + int id: @struct_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +struct_field_visibilities( + int id: @struct_field ref, + int visibility: @visibility ref +); + +struct_pat_fields( + unique int id: @struct_pat_field +); + +#keyset[id, index] +struct_pat_field_attrs( + int id: @struct_pat_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_pat_field_identifiers( + int id: @struct_pat_field ref, + int identifier: @name_ref ref +); + +#keyset[id] +struct_pat_field_pats( + int id: @struct_pat_field ref, + int pat: @pat ref +); + +struct_pat_field_lists( + unique int id: @struct_pat_field_list +); + +#keyset[id, index] +struct_pat_field_list_fields( + int id: @struct_pat_field_list ref, + int index: int ref, + int field: @struct_pat_field ref +); + +#keyset[id] +struct_pat_field_list_rest_pats( + int id: @struct_pat_field_list ref, + int rest_pat: @rest_pat ref +); + +@token = + @comment +; + +token_trees( + unique int id: @token_tree +); + +tuple_fields( + unique int id: @tuple_field +); + +#keyset[id, index] +tuple_field_attrs( + int id: @tuple_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +tuple_field_type_reprs( + int id: @tuple_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +tuple_field_visibilities( + int id: @tuple_field ref, + int visibility: @visibility ref +); + +type_bounds( + unique int id: @type_bound +); + +#keyset[id] +type_bound_for_binders( + int id: @type_bound ref, + int for_binder: @for_binder ref +); + +#keyset[id] +type_bound_is_async( + int id: @type_bound ref +); + +#keyset[id] +type_bound_is_const( + int id: @type_bound ref +); + +#keyset[id] +type_bound_lifetimes( + int id: @type_bound ref, + int lifetime: @lifetime ref +); + +#keyset[id] +type_bound_type_reprs( + int id: @type_bound ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_bound_use_bound_generic_args( + int id: @type_bound ref, + int use_bound_generic_args: @use_bound_generic_args ref +); + +type_bound_lists( + unique int id: @type_bound_list +); + +#keyset[id, index] +type_bound_list_bounds( + int id: @type_bound_list ref, + int index: int ref, + int bound: @type_bound ref +); + +@type_repr = + @array_type_repr +| @dyn_trait_type_repr +| @fn_ptr_type_repr +| @for_type_repr +| @impl_trait_type_repr +| @infer_type_repr +| @macro_type_repr +| @never_type_repr +| @paren_type_repr +| @path_type_repr +| @ptr_type_repr +| @ref_type_repr +| @slice_type_repr +| @tuple_type_repr +; + +@use_bound_generic_arg = + @lifetime +| @name_ref +; + +use_bound_generic_args( + unique int id: @use_bound_generic_args +); + +#keyset[id, index] +use_bound_generic_args_use_bound_generic_args( + int id: @use_bound_generic_args ref, + int index: int ref, + int use_bound_generic_arg: @use_bound_generic_arg ref +); + +use_trees( + unique int id: @use_tree +); + +#keyset[id] +use_tree_is_glob( + int id: @use_tree ref +); + +#keyset[id] +use_tree_paths( + int id: @use_tree ref, + int path: @path ref +); + +#keyset[id] +use_tree_renames( + int id: @use_tree ref, + int rename: @rename ref +); + +#keyset[id] +use_tree_use_tree_lists( + int id: @use_tree ref, + int use_tree_list: @use_tree_list ref +); + +use_tree_lists( + unique int id: @use_tree_list +); + +#keyset[id, index] +use_tree_list_use_trees( + int id: @use_tree_list ref, + int index: int ref, + int use_tree: @use_tree ref +); + +variant_lists( + unique int id: @variant_list +); + +#keyset[id, index] +variant_list_variants( + int id: @variant_list ref, + int index: int ref, + int variant: @variant ref +); + +visibilities( + unique int id: @visibility +); + +#keyset[id] +visibility_paths( + int id: @visibility ref, + int path: @path ref +); + +where_clauses( + unique int id: @where_clause +); + +#keyset[id, index] +where_clause_predicates( + int id: @where_clause ref, + int index: int ref, + int predicate: @where_pred ref +); + +where_preds( + unique int id: @where_pred +); + +#keyset[id] +where_pred_for_binders( + int id: @where_pred ref, + int for_binder: @for_binder ref +); + +#keyset[id] +where_pred_lifetimes( + int id: @where_pred ref, + int lifetime: @lifetime ref +); + +#keyset[id] +where_pred_type_reprs( + int id: @where_pred ref, + int type_repr: @type_repr ref +); + +#keyset[id] +where_pred_type_bound_lists( + int id: @where_pred ref, + int type_bound_list: @type_bound_list ref +); + +array_expr_internals( + unique int id: @array_expr_internal +); + +#keyset[id, index] +array_expr_internal_attrs( + int id: @array_expr_internal ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +array_expr_internal_exprs( + int id: @array_expr_internal ref, + int index: int ref, + int expr: @expr ref +); + +#keyset[id] +array_expr_internal_is_semicolon( + int id: @array_expr_internal ref +); + +array_type_reprs( + unique int id: @array_type_repr +); + +#keyset[id] +array_type_repr_const_args( + int id: @array_type_repr ref, + int const_arg: @const_arg ref +); + +#keyset[id] +array_type_repr_element_type_reprs( + int id: @array_type_repr ref, + int element_type_repr: @type_repr ref +); + +asm_clobber_abis( + unique int id: @asm_clobber_abi +); + +asm_consts( + unique int id: @asm_const +); + +#keyset[id] +asm_const_exprs( + int id: @asm_const ref, + int expr: @expr ref +); + +#keyset[id] +asm_const_is_const( + int id: @asm_const ref +); + +asm_labels( + unique int id: @asm_label +); + +#keyset[id] +asm_label_block_exprs( + int id: @asm_label ref, + int block_expr: @block_expr ref +); + +asm_operand_nameds( + unique int id: @asm_operand_named +); + +#keyset[id] +asm_operand_named_asm_operands( + int id: @asm_operand_named ref, + int asm_operand: @asm_operand ref +); + +#keyset[id] +asm_operand_named_names( + int id: @asm_operand_named ref, + int name: @name ref +); + +asm_options_lists( + unique int id: @asm_options_list +); + +#keyset[id, index] +asm_options_list_asm_options( + int id: @asm_options_list ref, + int index: int ref, + int asm_option: @asm_option ref +); + +asm_reg_operands( + unique int id: @asm_reg_operand +); + +#keyset[id] +asm_reg_operand_asm_dir_specs( + int id: @asm_reg_operand ref, + int asm_dir_spec: @asm_dir_spec ref +); + +#keyset[id] +asm_reg_operand_asm_operand_exprs( + int id: @asm_reg_operand ref, + int asm_operand_expr: @asm_operand_expr ref +); + +#keyset[id] +asm_reg_operand_asm_reg_specs( + int id: @asm_reg_operand ref, + int asm_reg_spec: @asm_reg_spec ref +); + +asm_syms( + unique int id: @asm_sym +); + +#keyset[id] +asm_sym_paths( + int id: @asm_sym ref, + int path: @path ref +); + +assoc_type_args( + unique int id: @assoc_type_arg +); + +#keyset[id] +assoc_type_arg_const_args( + int id: @assoc_type_arg ref, + int const_arg: @const_arg ref +); + +#keyset[id] +assoc_type_arg_generic_arg_lists( + int id: @assoc_type_arg ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +assoc_type_arg_identifiers( + int id: @assoc_type_arg ref, + int identifier: @name_ref ref +); + +#keyset[id] +assoc_type_arg_param_lists( + int id: @assoc_type_arg ref, + int param_list: @param_list ref +); + +#keyset[id] +assoc_type_arg_ret_types( + int id: @assoc_type_arg ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +assoc_type_arg_return_type_syntaxes( + int id: @assoc_type_arg ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +assoc_type_arg_type_reprs( + int id: @assoc_type_arg ref, + int type_repr: @type_repr ref +); + +#keyset[id] +assoc_type_arg_type_bound_lists( + int id: @assoc_type_arg ref, + int type_bound_list: @type_bound_list ref +); + +await_exprs( + unique int id: @await_expr +); + +#keyset[id, index] +await_expr_attrs( + int id: @await_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +await_expr_exprs( + int id: @await_expr ref, + int expr: @expr ref +); + +become_exprs( + unique int id: @become_expr +); + +#keyset[id, index] +become_expr_attrs( + int id: @become_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +become_expr_exprs( + int id: @become_expr ref, + int expr: @expr ref +); + +binary_exprs( + unique int id: @binary_expr +); + +#keyset[id, index] +binary_expr_attrs( + int id: @binary_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +binary_expr_lhs( + int id: @binary_expr ref, + int lhs: @expr ref +); + +#keyset[id] +binary_expr_operator_names( + int id: @binary_expr ref, + string operator_name: string ref +); + +#keyset[id] +binary_expr_rhs( + int id: @binary_expr ref, + int rhs: @expr ref +); + +box_pats( + unique int id: @box_pat +); + +#keyset[id] +box_pat_pats( + int id: @box_pat ref, + int pat: @pat ref +); + +break_exprs( + unique int id: @break_expr +); + +#keyset[id, index] +break_expr_attrs( + int id: @break_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +break_expr_exprs( + int id: @break_expr ref, + int expr: @expr ref +); + +#keyset[id] +break_expr_lifetimes( + int id: @break_expr ref, + int lifetime: @lifetime ref +); + +call_exprs( + unique int id: @call_expr +); + +#keyset[id] +call_expr_arg_lists( + int id: @call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +call_expr_attrs( + int id: @call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +call_expr_functions( + int id: @call_expr ref, + int function: @expr ref +); + +cast_exprs( + unique int id: @cast_expr +); + +#keyset[id, index] +cast_expr_attrs( + int id: @cast_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +cast_expr_exprs( + int id: @cast_expr ref, + int expr: @expr ref +); + +#keyset[id] +cast_expr_type_reprs( + int id: @cast_expr ref, + int type_repr: @type_repr ref +); + +closure_exprs( + unique int id: @closure_expr +); + +#keyset[id] +closure_expr_closure_bodies( + int id: @closure_expr ref, + int closure_body: @expr ref +); + +#keyset[id] +closure_expr_for_binders( + int id: @closure_expr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +closure_expr_is_async( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_const( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_gen( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_move( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_static( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_ret_types( + int id: @closure_expr ref, + int ret_type: @ret_type_repr ref +); + +comments( + unique int id: @comment, + int parent: @ast_node ref, + string text: string ref +); + +const_args( + unique int id: @const_arg +); + +#keyset[id] +const_arg_exprs( + int id: @const_arg ref, + int expr: @expr ref +); + +const_block_pats( + unique int id: @const_block_pat +); + +#keyset[id] +const_block_pat_block_exprs( + int id: @const_block_pat ref, + int block_expr: @block_expr ref +); + +#keyset[id] +const_block_pat_is_const( + int id: @const_block_pat ref +); + +const_params( + unique int id: @const_param +); + +#keyset[id, index] +const_param_attrs( + int id: @const_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_param_default_vals( + int id: @const_param ref, + int default_val: @const_arg ref +); + +#keyset[id] +const_param_is_const( + int id: @const_param ref +); + +#keyset[id] +const_param_names( + int id: @const_param ref, + int name: @name ref +); + +#keyset[id] +const_param_type_reprs( + int id: @const_param ref, + int type_repr: @type_repr ref +); + +continue_exprs( + unique int id: @continue_expr +); + +#keyset[id, index] +continue_expr_attrs( + int id: @continue_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +continue_expr_lifetimes( + int id: @continue_expr ref, + int lifetime: @lifetime ref +); + +dyn_trait_type_reprs( + unique int id: @dyn_trait_type_repr +); + +#keyset[id] +dyn_trait_type_repr_type_bound_lists( + int id: @dyn_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +expr_stmts( + unique int id: @expr_stmt +); + +#keyset[id] +expr_stmt_exprs( + int id: @expr_stmt ref, + int expr: @expr ref +); + +field_exprs( + unique int id: @field_expr +); + +#keyset[id, index] +field_expr_attrs( + int id: @field_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +field_expr_containers( + int id: @field_expr ref, + int container: @expr ref +); + +#keyset[id] +field_expr_identifiers( + int id: @field_expr ref, + int identifier: @name_ref ref +); + +fn_ptr_type_reprs( + unique int id: @fn_ptr_type_repr +); + +#keyset[id] +fn_ptr_type_repr_abis( + int id: @fn_ptr_type_repr ref, + int abi: @abi ref +); + +#keyset[id] +fn_ptr_type_repr_is_async( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_const( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_unsafe( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_param_lists( + int id: @fn_ptr_type_repr ref, + int param_list: @param_list ref +); + +#keyset[id] +fn_ptr_type_repr_ret_types( + int id: @fn_ptr_type_repr ref, + int ret_type: @ret_type_repr ref +); + +for_type_reprs( + unique int id: @for_type_repr +); + +#keyset[id] +for_type_repr_for_binders( + int id: @for_type_repr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +for_type_repr_type_reprs( + int id: @for_type_repr ref, + int type_repr: @type_repr ref +); + +format_args_exprs( + unique int id: @format_args_expr +); + +#keyset[id, index] +format_args_expr_args( + int id: @format_args_expr ref, + int index: int ref, + int arg: @format_args_arg ref +); + +#keyset[id, index] +format_args_expr_attrs( + int id: @format_args_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +format_args_expr_templates( + int id: @format_args_expr ref, + int template: @expr ref +); + +ident_pats( + unique int id: @ident_pat +); + +#keyset[id, index] +ident_pat_attrs( + int id: @ident_pat ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ident_pat_is_mut( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_is_ref( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_names( + int id: @ident_pat ref, + int name: @name ref +); + +#keyset[id] +ident_pat_pats( + int id: @ident_pat ref, + int pat: @pat ref +); + +if_exprs( + unique int id: @if_expr +); + +#keyset[id, index] +if_expr_attrs( + int id: @if_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +if_expr_conditions( + int id: @if_expr ref, + int condition: @expr ref +); + +#keyset[id] +if_expr_elses( + int id: @if_expr ref, + int else: @expr ref +); + +#keyset[id] +if_expr_thens( + int id: @if_expr ref, + int then: @block_expr ref +); + +impl_trait_type_reprs( + unique int id: @impl_trait_type_repr +); + +#keyset[id] +impl_trait_type_repr_type_bound_lists( + int id: @impl_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +index_exprs( + unique int id: @index_expr +); + +#keyset[id, index] +index_expr_attrs( + int id: @index_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +index_expr_bases( + int id: @index_expr ref, + int base: @expr ref +); + +#keyset[id] +index_expr_indices( + int id: @index_expr ref, + int index: @expr ref +); + +infer_type_reprs( + unique int id: @infer_type_repr +); + +@item = + @asm_expr +| @assoc_item +| @extern_block +| @extern_crate +| @extern_item +| @impl +| @macro_def +| @macro_rules +| @module +| @trait +| @trait_alias +| @type_item +| @use +; + +#keyset[id] +item_attribute_macro_expansions( + int id: @item ref, + int attribute_macro_expansion: @macro_items ref +); + +@labelable_expr = + @block_expr +| @looping_expr +; + +#keyset[id] +labelable_expr_labels( + int id: @labelable_expr ref, + int label: @label ref +); + +let_exprs( + unique int id: @let_expr +); + +#keyset[id, index] +let_expr_attrs( + int id: @let_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_expr_scrutinees( + int id: @let_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +let_expr_pats( + int id: @let_expr ref, + int pat: @pat ref +); + +let_stmts( + unique int id: @let_stmt +); + +#keyset[id, index] +let_stmt_attrs( + int id: @let_stmt ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_stmt_initializers( + int id: @let_stmt ref, + int initializer: @expr ref +); + +#keyset[id] +let_stmt_let_elses( + int id: @let_stmt ref, + int let_else: @let_else ref +); + +#keyset[id] +let_stmt_pats( + int id: @let_stmt ref, + int pat: @pat ref +); + +#keyset[id] +let_stmt_type_reprs( + int id: @let_stmt ref, + int type_repr: @type_repr ref +); + +lifetimes( + unique int id: @lifetime +); + +#keyset[id] +lifetime_texts( + int id: @lifetime ref, + string text: string ref +); + +lifetime_args( + unique int id: @lifetime_arg +); + +#keyset[id] +lifetime_arg_lifetimes( + int id: @lifetime_arg ref, + int lifetime: @lifetime ref +); + +lifetime_params( + unique int id: @lifetime_param +); + +#keyset[id, index] +lifetime_param_attrs( + int id: @lifetime_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +lifetime_param_lifetimes( + int id: @lifetime_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +lifetime_param_type_bound_lists( + int id: @lifetime_param ref, + int type_bound_list: @type_bound_list ref +); + +literal_exprs( + unique int id: @literal_expr +); + +#keyset[id, index] +literal_expr_attrs( + int id: @literal_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +literal_expr_text_values( + int id: @literal_expr ref, + string text_value: string ref +); + +literal_pats( + unique int id: @literal_pat +); + +#keyset[id] +literal_pat_literals( + int id: @literal_pat ref, + int literal: @literal_expr ref +); + +macro_exprs( + unique int id: @macro_expr +); + +#keyset[id] +macro_expr_macro_calls( + int id: @macro_expr ref, + int macro_call: @macro_call ref +); + +macro_pats( + unique int id: @macro_pat +); + +#keyset[id] +macro_pat_macro_calls( + int id: @macro_pat ref, + int macro_call: @macro_call ref +); + +macro_type_reprs( + unique int id: @macro_type_repr +); + +#keyset[id] +macro_type_repr_macro_calls( + int id: @macro_type_repr ref, + int macro_call: @macro_call ref +); + +match_exprs( + unique int id: @match_expr +); + +#keyset[id, index] +match_expr_attrs( + int id: @match_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_expr_scrutinees( + int id: @match_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +match_expr_match_arm_lists( + int id: @match_expr ref, + int match_arm_list: @match_arm_list ref +); + +method_call_exprs( + unique int id: @method_call_expr +); + +#keyset[id] +method_call_expr_arg_lists( + int id: @method_call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +method_call_expr_attrs( + int id: @method_call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +method_call_expr_generic_arg_lists( + int id: @method_call_expr ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +method_call_expr_identifiers( + int id: @method_call_expr ref, + int identifier: @name_ref ref +); + +#keyset[id] +method_call_expr_receivers( + int id: @method_call_expr ref, + int receiver: @expr ref +); + +name_refs( + unique int id: @name_ref +); + +#keyset[id] +name_ref_texts( + int id: @name_ref ref, + string text: string ref +); + +never_type_reprs( + unique int id: @never_type_repr +); + +offset_of_exprs( + unique int id: @offset_of_expr +); + +#keyset[id, index] +offset_of_expr_attrs( + int id: @offset_of_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +offset_of_expr_fields( + int id: @offset_of_expr ref, + int index: int ref, + int field: @name_ref ref +); + +#keyset[id] +offset_of_expr_type_reprs( + int id: @offset_of_expr ref, + int type_repr: @type_repr ref +); + +or_pats( + unique int id: @or_pat +); + +#keyset[id, index] +or_pat_pats( + int id: @or_pat ref, + int index: int ref, + int pat: @pat ref +); + +params( + unique int id: @param +); + +#keyset[id] +param_pats( + int id: @param ref, + int pat: @pat ref +); + +paren_exprs( + unique int id: @paren_expr +); + +#keyset[id, index] +paren_expr_attrs( + int id: @paren_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +paren_expr_exprs( + int id: @paren_expr ref, + int expr: @expr ref +); + +paren_pats( + unique int id: @paren_pat +); + +#keyset[id] +paren_pat_pats( + int id: @paren_pat ref, + int pat: @pat ref +); + +paren_type_reprs( + unique int id: @paren_type_repr +); + +#keyset[id] +paren_type_repr_type_reprs( + int id: @paren_type_repr ref, + int type_repr: @type_repr ref +); + +@path_expr_base = + @path_expr +; + +path_pats( + unique int id: @path_pat +); + +path_type_reprs( + unique int id: @path_type_repr +); + +#keyset[id] +path_type_repr_paths( + int id: @path_type_repr ref, + int path: @path ref +); + +prefix_exprs( + unique int id: @prefix_expr +); + +#keyset[id, index] +prefix_expr_attrs( + int id: @prefix_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +prefix_expr_exprs( + int id: @prefix_expr ref, + int expr: @expr ref +); + +#keyset[id] +prefix_expr_operator_names( + int id: @prefix_expr ref, + string operator_name: string ref +); + +ptr_type_reprs( + unique int id: @ptr_type_repr +); + +#keyset[id] +ptr_type_repr_is_const( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_is_mut( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_type_reprs( + int id: @ptr_type_repr ref, + int type_repr: @type_repr ref +); + +range_exprs( + unique int id: @range_expr +); + +#keyset[id, index] +range_expr_attrs( + int id: @range_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +range_expr_ends( + int id: @range_expr ref, + int end: @expr ref +); + +#keyset[id] +range_expr_operator_names( + int id: @range_expr ref, + string operator_name: string ref +); + +#keyset[id] +range_expr_starts( + int id: @range_expr ref, + int start: @expr ref +); + +range_pats( + unique int id: @range_pat +); + +#keyset[id] +range_pat_ends( + int id: @range_pat ref, + int end: @pat ref +); + +#keyset[id] +range_pat_operator_names( + int id: @range_pat ref, + string operator_name: string ref +); + +#keyset[id] +range_pat_starts( + int id: @range_pat ref, + int start: @pat ref +); + +ref_exprs( + unique int id: @ref_expr +); + +#keyset[id, index] +ref_expr_attrs( + int id: @ref_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ref_expr_exprs( + int id: @ref_expr ref, + int expr: @expr ref +); + +#keyset[id] +ref_expr_is_const( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_mut( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_raw( + int id: @ref_expr ref +); + +ref_pats( + unique int id: @ref_pat +); + +#keyset[id] +ref_pat_is_mut( + int id: @ref_pat ref +); + +#keyset[id] +ref_pat_pats( + int id: @ref_pat ref, + int pat: @pat ref +); + +ref_type_reprs( + unique int id: @ref_type_repr +); + +#keyset[id] +ref_type_repr_is_mut( + int id: @ref_type_repr ref +); + +#keyset[id] +ref_type_repr_lifetimes( + int id: @ref_type_repr ref, + int lifetime: @lifetime ref +); + +#keyset[id] +ref_type_repr_type_reprs( + int id: @ref_type_repr ref, + int type_repr: @type_repr ref +); + +rest_pats( + unique int id: @rest_pat +); + +#keyset[id, index] +rest_pat_attrs( + int id: @rest_pat ref, + int index: int ref, + int attr: @attr ref +); + +return_exprs( + unique int id: @return_expr +); + +#keyset[id, index] +return_expr_attrs( + int id: @return_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +return_expr_exprs( + int id: @return_expr ref, + int expr: @expr ref +); + +self_params( + unique int id: @self_param +); + +#keyset[id] +self_param_is_ref( + int id: @self_param ref +); + +#keyset[id] +self_param_is_mut( + int id: @self_param ref +); + +#keyset[id] +self_param_lifetimes( + int id: @self_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +self_param_names( + int id: @self_param ref, + int name: @name ref +); + +slice_pats( + unique int id: @slice_pat +); + +#keyset[id, index] +slice_pat_pats( + int id: @slice_pat ref, + int index: int ref, + int pat: @pat ref +); + +slice_type_reprs( + unique int id: @slice_type_repr +); + +#keyset[id] +slice_type_repr_type_reprs( + int id: @slice_type_repr ref, + int type_repr: @type_repr ref +); + +struct_exprs( + unique int id: @struct_expr +); + +#keyset[id] +struct_expr_struct_expr_field_lists( + int id: @struct_expr ref, + int struct_expr_field_list: @struct_expr_field_list ref +); + +struct_field_lists( + unique int id: @struct_field_list +); + +#keyset[id, index] +struct_field_list_fields( + int id: @struct_field_list ref, + int index: int ref, + int field: @struct_field ref +); + +struct_pats( + unique int id: @struct_pat +); + +#keyset[id] +struct_pat_struct_pat_field_lists( + int id: @struct_pat ref, + int struct_pat_field_list: @struct_pat_field_list ref +); + +try_exprs( + unique int id: @try_expr +); + +#keyset[id, index] +try_expr_attrs( + int id: @try_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +try_expr_exprs( + int id: @try_expr ref, + int expr: @expr ref +); + +tuple_exprs( + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_attrs( + int id: @tuple_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +tuple_expr_fields( + int id: @tuple_expr ref, + int index: int ref, + int field: @expr ref +); + +tuple_field_lists( + unique int id: @tuple_field_list +); + +#keyset[id, index] +tuple_field_list_fields( + int id: @tuple_field_list ref, + int index: int ref, + int field: @tuple_field ref +); + +tuple_pats( + unique int id: @tuple_pat +); + +#keyset[id, index] +tuple_pat_fields( + int id: @tuple_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_struct_pats( + unique int id: @tuple_struct_pat +); + +#keyset[id, index] +tuple_struct_pat_fields( + int id: @tuple_struct_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_type_reprs( + unique int id: @tuple_type_repr +); + +#keyset[id, index] +tuple_type_repr_fields( + int id: @tuple_type_repr ref, + int index: int ref, + int field: @type_repr ref +); + +type_args( + unique int id: @type_arg +); + +#keyset[id] +type_arg_type_reprs( + int id: @type_arg ref, + int type_repr: @type_repr ref +); + +type_params( + unique int id: @type_param +); + +#keyset[id, index] +type_param_attrs( + int id: @type_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_param_default_types( + int id: @type_param ref, + int default_type: @type_repr ref +); + +#keyset[id] +type_param_names( + int id: @type_param ref, + int name: @name ref +); + +#keyset[id] +type_param_type_bound_lists( + int id: @type_param ref, + int type_bound_list: @type_bound_list ref +); + +underscore_exprs( + unique int id: @underscore_expr +); + +#keyset[id, index] +underscore_expr_attrs( + int id: @underscore_expr ref, + int index: int ref, + int attr: @attr ref +); + +variants( + unique int id: @variant +); + +#keyset[id, index] +variant_attrs( + int id: @variant ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +variant_discriminants( + int id: @variant ref, + int discriminant: @expr ref +); + +#keyset[id] +variant_field_lists( + int id: @variant ref, + int field_list: @field_list ref +); + +#keyset[id] +variant_names( + int id: @variant ref, + int name: @name ref +); + +#keyset[id] +variant_visibilities( + int id: @variant ref, + int visibility: @visibility ref +); + +wildcard_pats( + unique int id: @wildcard_pat +); + +yeet_exprs( + unique int id: @yeet_expr +); + +#keyset[id, index] +yeet_expr_attrs( + int id: @yeet_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yeet_expr_exprs( + int id: @yeet_expr ref, + int expr: @expr ref +); + +yield_exprs( + unique int id: @yield_expr +); + +#keyset[id, index] +yield_expr_attrs( + int id: @yield_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yield_expr_exprs( + int id: @yield_expr ref, + int expr: @expr ref +); + +asm_exprs( + unique int id: @asm_expr +); + +#keyset[id, index] +asm_expr_asm_pieces( + int id: @asm_expr ref, + int index: int ref, + int asm_piece: @asm_piece ref +); + +#keyset[id, index] +asm_expr_attrs( + int id: @asm_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +asm_expr_templates( + int id: @asm_expr ref, + int index: int ref, + int template: @expr ref +); + +@assoc_item = + @const +| @function +| @macro_call +| @type_alias +; + +block_exprs( + unique int id: @block_expr +); + +#keyset[id, index] +block_expr_attrs( + int id: @block_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +block_expr_is_async( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_const( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_gen( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_move( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_try( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_unsafe( + int id: @block_expr ref +); + +#keyset[id] +block_expr_stmt_lists( + int id: @block_expr ref, + int stmt_list: @stmt_list ref +); + +extern_blocks( + unique int id: @extern_block +); + +#keyset[id] +extern_block_abis( + int id: @extern_block ref, + int abi: @abi ref +); + +#keyset[id, index] +extern_block_attrs( + int id: @extern_block ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_block_extern_item_lists( + int id: @extern_block ref, + int extern_item_list: @extern_item_list ref +); + +#keyset[id] +extern_block_is_unsafe( + int id: @extern_block ref +); + +extern_crates( + unique int id: @extern_crate +); + +#keyset[id, index] +extern_crate_attrs( + int id: @extern_crate ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_crate_identifiers( + int id: @extern_crate ref, + int identifier: @name_ref ref +); + +#keyset[id] +extern_crate_renames( + int id: @extern_crate ref, + int rename: @rename ref +); + +#keyset[id] +extern_crate_visibilities( + int id: @extern_crate ref, + int visibility: @visibility ref +); + +@extern_item = + @function +| @macro_call +| @static +| @type_alias +; + +impls( + unique int id: @impl +); + +#keyset[id] +impl_assoc_item_lists( + int id: @impl ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +impl_attrs( + int id: @impl ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +impl_generic_param_lists( + int id: @impl ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +impl_is_const( + int id: @impl ref +); + +#keyset[id] +impl_is_default( + int id: @impl ref +); + +#keyset[id] +impl_is_unsafe( + int id: @impl ref +); + +#keyset[id] +impl_self_ties( + int id: @impl ref, + int self_ty: @type_repr ref +); + +#keyset[id] +impl_trait_ties( + int id: @impl ref, + int trait_ty: @type_repr ref +); + +#keyset[id] +impl_visibilities( + int id: @impl ref, + int visibility: @visibility ref +); + +#keyset[id] +impl_where_clauses( + int id: @impl ref, + int where_clause: @where_clause ref +); + +@looping_expr = + @for_expr +| @loop_expr +| @while_expr +; + +#keyset[id] +looping_expr_loop_bodies( + int id: @looping_expr ref, + int loop_body: @block_expr ref +); + +macro_defs( + unique int id: @macro_def +); + +#keyset[id] +macro_def_args( + int id: @macro_def ref, + int args: @token_tree ref +); + +#keyset[id, index] +macro_def_attrs( + int id: @macro_def ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_def_bodies( + int id: @macro_def ref, + int body: @token_tree ref +); + +#keyset[id] +macro_def_names( + int id: @macro_def ref, + int name: @name ref +); + +#keyset[id] +macro_def_visibilities( + int id: @macro_def ref, + int visibility: @visibility ref +); + +macro_rules( + unique int id: @macro_rules +); + +#keyset[id, index] +macro_rules_attrs( + int id: @macro_rules ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_rules_names( + int id: @macro_rules ref, + int name: @name ref +); + +#keyset[id] +macro_rules_token_trees( + int id: @macro_rules ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_rules_visibilities( + int id: @macro_rules ref, + int visibility: @visibility ref +); + +modules( + unique int id: @module +); + +#keyset[id, index] +module_attrs( + int id: @module ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +module_item_lists( + int id: @module ref, + int item_list: @item_list ref +); + +#keyset[id] +module_names( + int id: @module ref, + int name: @name ref +); + +#keyset[id] +module_visibilities( + int id: @module ref, + int visibility: @visibility ref +); + +path_exprs( + unique int id: @path_expr +); + +#keyset[id, index] +path_expr_attrs( + int id: @path_expr ref, + int index: int ref, + int attr: @attr ref +); + +traits( + unique int id: @trait +); + +#keyset[id] +trait_assoc_item_lists( + int id: @trait ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +trait_attrs( + int id: @trait ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_generic_param_lists( + int id: @trait ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_is_auto( + int id: @trait ref +); + +#keyset[id] +trait_is_unsafe( + int id: @trait ref +); + +#keyset[id] +trait_names( + int id: @trait ref, + int name: @name ref +); + +#keyset[id] +trait_type_bound_lists( + int id: @trait ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_visibilities( + int id: @trait ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_where_clauses( + int id: @trait ref, + int where_clause: @where_clause ref +); + +trait_aliases( + unique int id: @trait_alias +); + +#keyset[id, index] +trait_alias_attrs( + int id: @trait_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_alias_generic_param_lists( + int id: @trait_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_alias_names( + int id: @trait_alias ref, + int name: @name ref +); + +#keyset[id] +trait_alias_type_bound_lists( + int id: @trait_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_alias_visibilities( + int id: @trait_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_alias_where_clauses( + int id: @trait_alias ref, + int where_clause: @where_clause ref +); + +@type_item = + @enum +| @struct +| @union +; + +#keyset[id, index] +type_item_derive_macro_expansions( + int id: @type_item ref, + int index: int ref, + int derive_macro_expansion: @macro_items ref +); + +#keyset[id, index] +type_item_attrs( + int id: @type_item ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_item_generic_param_lists( + int id: @type_item ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_item_names( + int id: @type_item ref, + int name: @name ref +); + +#keyset[id] +type_item_visibilities( + int id: @type_item ref, + int visibility: @visibility ref +); + +#keyset[id] +type_item_where_clauses( + int id: @type_item ref, + int where_clause: @where_clause ref +); + +uses( + unique int id: @use +); + +#keyset[id, index] +use_attrs( + int id: @use ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +use_use_trees( + int id: @use ref, + int use_tree: @use_tree ref +); + +#keyset[id] +use_visibilities( + int id: @use ref, + int visibility: @visibility ref +); + +consts( + unique int id: @const +); + +#keyset[id, index] +const_attrs( + int id: @const ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_bodies( + int id: @const ref, + int body: @expr ref +); + +#keyset[id] +const_generic_param_lists( + int id: @const ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +const_is_const( + int id: @const ref +); + +#keyset[id] +const_is_default( + int id: @const ref +); + +#keyset[id] +const_names( + int id: @const ref, + int name: @name ref +); + +#keyset[id] +const_type_reprs( + int id: @const ref, + int type_repr: @type_repr ref +); + +#keyset[id] +const_visibilities( + int id: @const ref, + int visibility: @visibility ref +); + +#keyset[id] +const_where_clauses( + int id: @const ref, + int where_clause: @where_clause ref +); + +#keyset[id] +const_has_implementation( + int id: @const ref +); + +enums( + unique int id: @enum +); + +#keyset[id] +enum_variant_lists( + int id: @enum ref, + int variant_list: @variant_list ref +); + +for_exprs( + unique int id: @for_expr +); + +#keyset[id, index] +for_expr_attrs( + int id: @for_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +for_expr_iterables( + int id: @for_expr ref, + int iterable: @expr ref +); + +#keyset[id] +for_expr_pats( + int id: @for_expr ref, + int pat: @pat ref +); + +functions( + unique int id: @function +); + +#keyset[id] +function_abis( + int id: @function ref, + int abi: @abi ref +); + +#keyset[id] +function_function_bodies( + int id: @function ref, + int function_body: @block_expr ref +); + +#keyset[id] +function_generic_param_lists( + int id: @function ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +function_is_async( + int id: @function ref +); + +#keyset[id] +function_is_const( + int id: @function ref +); + +#keyset[id] +function_is_default( + int id: @function ref +); + +#keyset[id] +function_is_gen( + int id: @function ref +); + +#keyset[id] +function_is_unsafe( + int id: @function ref +); + +#keyset[id] +function_names( + int id: @function ref, + int name: @name ref +); + +#keyset[id] +function_ret_types( + int id: @function ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +function_visibilities( + int id: @function ref, + int visibility: @visibility ref +); + +#keyset[id] +function_where_clauses( + int id: @function ref, + int where_clause: @where_clause ref +); + +#keyset[id] +function_has_implementation( + int id: @function ref +); + +loop_exprs( + unique int id: @loop_expr +); + +#keyset[id, index] +loop_expr_attrs( + int id: @loop_expr ref, + int index: int ref, + int attr: @attr ref +); + +macro_calls( + unique int id: @macro_call +); + +#keyset[id, index] +macro_call_attrs( + int id: @macro_call ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_call_paths( + int id: @macro_call ref, + int path: @path ref +); + +#keyset[id] +macro_call_token_trees( + int id: @macro_call ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_call_macro_call_expansions( + int id: @macro_call ref, + int macro_call_expansion: @ast_node ref +); + +statics( + unique int id: @static +); + +#keyset[id, index] +static_attrs( + int id: @static ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +static_bodies( + int id: @static ref, + int body: @expr ref +); + +#keyset[id] +static_is_mut( + int id: @static ref +); + +#keyset[id] +static_is_static( + int id: @static ref +); + +#keyset[id] +static_is_unsafe( + int id: @static ref +); + +#keyset[id] +static_names( + int id: @static ref, + int name: @name ref +); + +#keyset[id] +static_type_reprs( + int id: @static ref, + int type_repr: @type_repr ref +); + +#keyset[id] +static_visibilities( + int id: @static ref, + int visibility: @visibility ref +); + +structs( + unique int id: @struct +); + +#keyset[id] +struct_field_lists_( + int id: @struct ref, + int field_list: @field_list ref +); + +type_aliases( + unique int id: @type_alias +); + +#keyset[id, index] +type_alias_attrs( + int id: @type_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_alias_generic_param_lists( + int id: @type_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_alias_is_default( + int id: @type_alias ref +); + +#keyset[id] +type_alias_names( + int id: @type_alias ref, + int name: @name ref +); + +#keyset[id] +type_alias_type_reprs( + int id: @type_alias ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_alias_type_bound_lists( + int id: @type_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +type_alias_visibilities( + int id: @type_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +type_alias_where_clauses( + int id: @type_alias ref, + int where_clause: @where_clause ref +); + +unions( + unique int id: @union +); + +#keyset[id] +union_struct_field_lists( + int id: @union ref, + int struct_field_list: @struct_field_list ref +); + +while_exprs( + unique int id: @while_expr +); + +#keyset[id, index] +while_expr_attrs( + int id: @while_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +while_expr_conditions( + int id: @while_expr ref, + int condition: @expr ref +); diff --git a/rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/rust.dbscheme b/rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/rust.dbscheme new file mode 100644 index 00000000000..66a48986364 --- /dev/null +++ b/rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/rust.dbscheme @@ -0,0 +1,3556 @@ +// generated by codegen, do not edit + +// from ../shared/tree-sitter-extractor/src/generator/prefix.dbscheme +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ + +/** + * The CLI will automatically emit applicable tuples for this table, + * such as `databaseMetadata("isOverlay", "true")` when building an + * overlay database. + */ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Overlay support -*/ + +/** + * The CLI will automatically emit tuples for each new/modified/deleted file + * when building an overlay database. + */ +overlayChangedFiles( + string path: string ref +); + + +// from prefix.dbscheme +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_default ref +); + + +// from schema + +@element = + @extractor_step +| @locatable +| @named_crate +| @unextracted +; + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int duration_ms: int ref +); + +#keyset[id] +extractor_step_files( + int id: @extractor_step ref, + int file: @file ref +); + +@locatable = + @ast_node +| @crate +; + +named_crates( + unique int id: @named_crate, + string name: string ref, + int crate: @crate ref +); + +@unextracted = + @missing +| @unimplemented +; + +@ast_node = + @abi +| @addressable +| @arg_list +| @asm_dir_spec +| @asm_operand +| @asm_operand_expr +| @asm_option +| @asm_piece +| @asm_reg_spec +| @assoc_item_list +| @attr +| @callable +| @expr +| @extern_item_list +| @field_list +| @for_binder +| @format_args_arg +| @generic_arg +| @generic_arg_list +| @generic_param +| @generic_param_list +| @item_list +| @label +| @let_else +| @macro_items +| @match_arm +| @match_arm_list +| @match_guard +| @meta +| @name +| @param_base +| @param_list +| @parenthesized_arg_list +| @pat +| @path +| @path_ast_node +| @path_segment +| @rename +| @ret_type_repr +| @return_type_syntax +| @source_file +| @stmt +| @stmt_list +| @struct_expr_field +| @struct_expr_field_list +| @struct_field +| @struct_pat_field +| @struct_pat_field_list +| @token +| @token_tree +| @tuple_field +| @type_bound +| @type_bound_list +| @type_repr +| @use_bound_generic_arg +| @use_bound_generic_args +| @use_tree +| @use_tree_list +| @variant_list +| @visibility +| @where_clause +| @where_pred +; + +crates( + unique int id: @crate +); + +#keyset[id] +crate_names( + int id: @crate ref, + string name: string ref +); + +#keyset[id] +crate_versions( + int id: @crate ref, + string version: string ref +); + +#keyset[id, index] +crate_cfg_options( + int id: @crate ref, + int index: int ref, + string cfg_option: string ref +); + +#keyset[id, index] +crate_named_dependencies( + int id: @crate ref, + int index: int ref, + int named_dependency: @named_crate ref +); + +missings( + unique int id: @missing +); + +unimplementeds( + unique int id: @unimplemented +); + +abis( + unique int id: @abi +); + +#keyset[id] +abi_abi_strings( + int id: @abi ref, + string abi_string: string ref +); + +@addressable = + @item +| @variant +; + +arg_lists( + unique int id: @arg_list +); + +#keyset[id, index] +arg_list_args( + int id: @arg_list ref, + int index: int ref, + int arg: @expr ref +); + +asm_dir_specs( + unique int id: @asm_dir_spec +); + +@asm_operand = + @asm_const +| @asm_label +| @asm_reg_operand +| @asm_sym +; + +asm_operand_exprs( + unique int id: @asm_operand_expr +); + +#keyset[id] +asm_operand_expr_in_exprs( + int id: @asm_operand_expr ref, + int in_expr: @expr ref +); + +#keyset[id] +asm_operand_expr_out_exprs( + int id: @asm_operand_expr ref, + int out_expr: @expr ref +); + +asm_options( + unique int id: @asm_option +); + +#keyset[id] +asm_option_is_raw( + int id: @asm_option ref +); + +@asm_piece = + @asm_clobber_abi +| @asm_operand_named +| @asm_options_list +; + +asm_reg_specs( + unique int id: @asm_reg_spec +); + +#keyset[id] +asm_reg_spec_identifiers( + int id: @asm_reg_spec ref, + int identifier: @name_ref ref +); + +assoc_item_lists( + unique int id: @assoc_item_list +); + +#keyset[id, index] +assoc_item_list_assoc_items( + int id: @assoc_item_list ref, + int index: int ref, + int assoc_item: @assoc_item ref +); + +#keyset[id, index] +assoc_item_list_attrs( + int id: @assoc_item_list ref, + int index: int ref, + int attr: @attr ref +); + +attrs( + unique int id: @attr +); + +#keyset[id] +attr_meta( + int id: @attr ref, + int meta: @meta ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_param_lists( + int id: @callable ref, + int param_list: @param_list ref +); + +#keyset[id, index] +callable_attrs( + int id: @callable ref, + int index: int ref, + int attr: @attr ref +); + +@expr = + @array_expr_internal +| @asm_expr +| @await_expr +| @become_expr +| @binary_expr +| @break_expr +| @call_expr +| @cast_expr +| @closure_expr +| @continue_expr +| @field_expr +| @format_args_expr +| @if_expr +| @index_expr +| @labelable_expr +| @let_expr +| @literal_expr +| @macro_expr +| @match_expr +| @method_call_expr +| @offset_of_expr +| @paren_expr +| @path_expr_base +| @prefix_expr +| @range_expr +| @ref_expr +| @return_expr +| @struct_expr +| @try_expr +| @tuple_expr +| @underscore_expr +| @yeet_expr +| @yield_expr +; + +extern_item_lists( + unique int id: @extern_item_list +); + +#keyset[id, index] +extern_item_list_attrs( + int id: @extern_item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +extern_item_list_extern_items( + int id: @extern_item_list ref, + int index: int ref, + int extern_item: @extern_item ref +); + +@field_list = + @struct_field_list +| @tuple_field_list +; + +for_binders( + unique int id: @for_binder +); + +#keyset[id] +for_binder_generic_param_lists( + int id: @for_binder ref, + int generic_param_list: @generic_param_list ref +); + +format_args_args( + unique int id: @format_args_arg +); + +#keyset[id] +format_args_arg_exprs( + int id: @format_args_arg ref, + int expr: @expr ref +); + +#keyset[id] +format_args_arg_names( + int id: @format_args_arg ref, + int name: @name ref +); + +@generic_arg = + @assoc_type_arg +| @const_arg +| @lifetime_arg +| @type_arg +; + +generic_arg_lists( + unique int id: @generic_arg_list +); + +#keyset[id, index] +generic_arg_list_generic_args( + int id: @generic_arg_list ref, + int index: int ref, + int generic_arg: @generic_arg ref +); + +@generic_param = + @const_param +| @lifetime_param +| @type_param +; + +generic_param_lists( + unique int id: @generic_param_list +); + +#keyset[id, index] +generic_param_list_generic_params( + int id: @generic_param_list ref, + int index: int ref, + int generic_param: @generic_param ref +); + +item_lists( + unique int id: @item_list +); + +#keyset[id, index] +item_list_attrs( + int id: @item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +item_list_items( + int id: @item_list ref, + int index: int ref, + int item: @item ref +); + +labels( + unique int id: @label +); + +#keyset[id] +label_lifetimes( + int id: @label ref, + int lifetime: @lifetime ref +); + +let_elses( + unique int id: @let_else +); + +#keyset[id] +let_else_block_exprs( + int id: @let_else ref, + int block_expr: @block_expr ref +); + +macro_items( + unique int id: @macro_items +); + +#keyset[id, index] +macro_items_items( + int id: @macro_items ref, + int index: int ref, + int item: @item ref +); + +match_arms( + unique int id: @match_arm +); + +#keyset[id, index] +match_arm_attrs( + int id: @match_arm ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_arm_exprs( + int id: @match_arm ref, + int expr: @expr ref +); + +#keyset[id] +match_arm_guards( + int id: @match_arm ref, + int guard: @match_guard ref +); + +#keyset[id] +match_arm_pats( + int id: @match_arm ref, + int pat: @pat ref +); + +match_arm_lists( + unique int id: @match_arm_list +); + +#keyset[id, index] +match_arm_list_arms( + int id: @match_arm_list ref, + int index: int ref, + int arm: @match_arm ref +); + +#keyset[id, index] +match_arm_list_attrs( + int id: @match_arm_list ref, + int index: int ref, + int attr: @attr ref +); + +match_guards( + unique int id: @match_guard +); + +#keyset[id] +match_guard_conditions( + int id: @match_guard ref, + int condition: @expr ref +); + +meta( + unique int id: @meta +); + +#keyset[id] +meta_exprs( + int id: @meta ref, + int expr: @expr ref +); + +#keyset[id] +meta_is_unsafe( + int id: @meta ref +); + +#keyset[id] +meta_paths( + int id: @meta ref, + int path: @path ref +); + +#keyset[id] +meta_token_trees( + int id: @meta ref, + int token_tree: @token_tree ref +); + +names( + unique int id: @name +); + +#keyset[id] +name_texts( + int id: @name ref, + string text: string ref +); + +@param_base = + @param +| @self_param +; + +#keyset[id, index] +param_base_attrs( + int id: @param_base ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +param_base_type_reprs( + int id: @param_base ref, + int type_repr: @type_repr ref +); + +param_lists( + unique int id: @param_list +); + +#keyset[id, index] +param_list_params( + int id: @param_list ref, + int index: int ref, + int param: @param ref +); + +#keyset[id] +param_list_self_params( + int id: @param_list ref, + int self_param: @self_param ref +); + +parenthesized_arg_lists( + unique int id: @parenthesized_arg_list +); + +#keyset[id, index] +parenthesized_arg_list_type_args( + int id: @parenthesized_arg_list ref, + int index: int ref, + int type_arg: @type_arg ref +); + +@pat = + @box_pat +| @const_block_pat +| @ident_pat +| @literal_pat +| @macro_pat +| @or_pat +| @paren_pat +| @path_pat +| @range_pat +| @ref_pat +| @rest_pat +| @slice_pat +| @struct_pat +| @tuple_pat +| @tuple_struct_pat +| @wildcard_pat +; + +paths( + unique int id: @path +); + +#keyset[id] +path_qualifiers( + int id: @path ref, + int qualifier: @path ref +); + +#keyset[id] +path_segments_( + int id: @path ref, + int segment: @path_segment ref +); + +@path_ast_node = + @path_expr +| @path_pat +| @struct_expr +| @struct_pat +| @tuple_struct_pat +; + +#keyset[id] +path_ast_node_paths( + int id: @path_ast_node ref, + int path: @path ref +); + +path_segments( + unique int id: @path_segment +); + +#keyset[id] +path_segment_generic_arg_lists( + int id: @path_segment ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +path_segment_identifiers( + int id: @path_segment ref, + int identifier: @name_ref ref +); + +#keyset[id] +path_segment_parenthesized_arg_lists( + int id: @path_segment ref, + int parenthesized_arg_list: @parenthesized_arg_list ref +); + +#keyset[id] +path_segment_ret_types( + int id: @path_segment ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +path_segment_return_type_syntaxes( + int id: @path_segment ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +path_segment_type_reprs( + int id: @path_segment ref, + int type_repr: @type_repr ref +); + +#keyset[id] +path_segment_trait_type_reprs( + int id: @path_segment ref, + int trait_type_repr: @path_type_repr ref +); + +renames( + unique int id: @rename +); + +#keyset[id] +rename_names( + int id: @rename ref, + int name: @name ref +); + +ret_type_reprs( + unique int id: @ret_type_repr +); + +#keyset[id] +ret_type_repr_type_reprs( + int id: @ret_type_repr ref, + int type_repr: @type_repr ref +); + +return_type_syntaxes( + unique int id: @return_type_syntax +); + +source_files( + unique int id: @source_file +); + +#keyset[id, index] +source_file_attrs( + int id: @source_file ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +source_file_items( + int id: @source_file ref, + int index: int ref, + int item: @item ref +); + +@stmt = + @expr_stmt +| @item +| @let_stmt +; + +stmt_lists( + unique int id: @stmt_list +); + +#keyset[id, index] +stmt_list_attrs( + int id: @stmt_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +stmt_list_statements( + int id: @stmt_list ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +stmt_list_tail_exprs( + int id: @stmt_list ref, + int tail_expr: @expr ref +); + +struct_expr_fields( + unique int id: @struct_expr_field +); + +#keyset[id, index] +struct_expr_field_attrs( + int id: @struct_expr_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_expr_field_exprs( + int id: @struct_expr_field ref, + int expr: @expr ref +); + +#keyset[id] +struct_expr_field_identifiers( + int id: @struct_expr_field ref, + int identifier: @name_ref ref +); + +struct_expr_field_lists( + unique int id: @struct_expr_field_list +); + +#keyset[id, index] +struct_expr_field_list_attrs( + int id: @struct_expr_field_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +struct_expr_field_list_fields( + int id: @struct_expr_field_list ref, + int index: int ref, + int field: @struct_expr_field ref +); + +#keyset[id] +struct_expr_field_list_spreads( + int id: @struct_expr_field_list ref, + int spread: @expr ref +); + +struct_fields( + unique int id: @struct_field +); + +#keyset[id, index] +struct_field_attrs( + int id: @struct_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_defaults( + int id: @struct_field ref, + int default: @expr ref +); + +#keyset[id] +struct_field_is_unsafe( + int id: @struct_field ref +); + +#keyset[id] +struct_field_names( + int id: @struct_field ref, + int name: @name ref +); + +#keyset[id] +struct_field_type_reprs( + int id: @struct_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +struct_field_visibilities( + int id: @struct_field ref, + int visibility: @visibility ref +); + +struct_pat_fields( + unique int id: @struct_pat_field +); + +#keyset[id, index] +struct_pat_field_attrs( + int id: @struct_pat_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_pat_field_identifiers( + int id: @struct_pat_field ref, + int identifier: @name_ref ref +); + +#keyset[id] +struct_pat_field_pats( + int id: @struct_pat_field ref, + int pat: @pat ref +); + +struct_pat_field_lists( + unique int id: @struct_pat_field_list +); + +#keyset[id, index] +struct_pat_field_list_fields( + int id: @struct_pat_field_list ref, + int index: int ref, + int field: @struct_pat_field ref +); + +#keyset[id] +struct_pat_field_list_rest_pats( + int id: @struct_pat_field_list ref, + int rest_pat: @rest_pat ref +); + +@token = + @comment +; + +token_trees( + unique int id: @token_tree +); + +tuple_fields( + unique int id: @tuple_field +); + +#keyset[id, index] +tuple_field_attrs( + int id: @tuple_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +tuple_field_type_reprs( + int id: @tuple_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +tuple_field_visibilities( + int id: @tuple_field ref, + int visibility: @visibility ref +); + +type_bounds( + unique int id: @type_bound +); + +#keyset[id] +type_bound_for_binders( + int id: @type_bound ref, + int for_binder: @for_binder ref +); + +#keyset[id] +type_bound_is_async( + int id: @type_bound ref +); + +#keyset[id] +type_bound_is_const( + int id: @type_bound ref +); + +#keyset[id] +type_bound_lifetimes( + int id: @type_bound ref, + int lifetime: @lifetime ref +); + +#keyset[id] +type_bound_type_reprs( + int id: @type_bound ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_bound_use_bound_generic_args( + int id: @type_bound ref, + int use_bound_generic_args: @use_bound_generic_args ref +); + +type_bound_lists( + unique int id: @type_bound_list +); + +#keyset[id, index] +type_bound_list_bounds( + int id: @type_bound_list ref, + int index: int ref, + int bound: @type_bound ref +); + +@type_repr = + @array_type_repr +| @dyn_trait_type_repr +| @fn_ptr_type_repr +| @for_type_repr +| @impl_trait_type_repr +| @infer_type_repr +| @macro_type_repr +| @never_type_repr +| @paren_type_repr +| @path_type_repr +| @ptr_type_repr +| @ref_type_repr +| @slice_type_repr +| @tuple_type_repr +; + +@use_bound_generic_arg = + @lifetime +| @name_ref +; + +use_bound_generic_args( + unique int id: @use_bound_generic_args +); + +#keyset[id, index] +use_bound_generic_args_use_bound_generic_args( + int id: @use_bound_generic_args ref, + int index: int ref, + int use_bound_generic_arg: @use_bound_generic_arg ref +); + +use_trees( + unique int id: @use_tree +); + +#keyset[id] +use_tree_is_glob( + int id: @use_tree ref +); + +#keyset[id] +use_tree_paths( + int id: @use_tree ref, + int path: @path ref +); + +#keyset[id] +use_tree_renames( + int id: @use_tree ref, + int rename: @rename ref +); + +#keyset[id] +use_tree_use_tree_lists( + int id: @use_tree ref, + int use_tree_list: @use_tree_list ref +); + +use_tree_lists( + unique int id: @use_tree_list +); + +#keyset[id, index] +use_tree_list_use_trees( + int id: @use_tree_list ref, + int index: int ref, + int use_tree: @use_tree ref +); + +variant_lists( + unique int id: @variant_list +); + +#keyset[id, index] +variant_list_variants( + int id: @variant_list ref, + int index: int ref, + int variant: @variant ref +); + +visibilities( + unique int id: @visibility +); + +#keyset[id] +visibility_paths( + int id: @visibility ref, + int path: @path ref +); + +where_clauses( + unique int id: @where_clause +); + +#keyset[id, index] +where_clause_predicates( + int id: @where_clause ref, + int index: int ref, + int predicate: @where_pred ref +); + +where_preds( + unique int id: @where_pred +); + +#keyset[id] +where_pred_for_binders( + int id: @where_pred ref, + int for_binder: @for_binder ref +); + +#keyset[id] +where_pred_lifetimes( + int id: @where_pred ref, + int lifetime: @lifetime ref +); + +#keyset[id] +where_pred_type_reprs( + int id: @where_pred ref, + int type_repr: @type_repr ref +); + +#keyset[id] +where_pred_type_bound_lists( + int id: @where_pred ref, + int type_bound_list: @type_bound_list ref +); + +array_expr_internals( + unique int id: @array_expr_internal +); + +#keyset[id, index] +array_expr_internal_attrs( + int id: @array_expr_internal ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +array_expr_internal_exprs( + int id: @array_expr_internal ref, + int index: int ref, + int expr: @expr ref +); + +#keyset[id] +array_expr_internal_is_semicolon( + int id: @array_expr_internal ref +); + +array_type_reprs( + unique int id: @array_type_repr +); + +#keyset[id] +array_type_repr_const_args( + int id: @array_type_repr ref, + int const_arg: @const_arg ref +); + +#keyset[id] +array_type_repr_element_type_reprs( + int id: @array_type_repr ref, + int element_type_repr: @type_repr ref +); + +asm_clobber_abis( + unique int id: @asm_clobber_abi +); + +asm_consts( + unique int id: @asm_const +); + +#keyset[id] +asm_const_exprs( + int id: @asm_const ref, + int expr: @expr ref +); + +#keyset[id] +asm_const_is_const( + int id: @asm_const ref +); + +asm_labels( + unique int id: @asm_label +); + +#keyset[id] +asm_label_block_exprs( + int id: @asm_label ref, + int block_expr: @block_expr ref +); + +asm_operand_nameds( + unique int id: @asm_operand_named +); + +#keyset[id] +asm_operand_named_asm_operands( + int id: @asm_operand_named ref, + int asm_operand: @asm_operand ref +); + +#keyset[id] +asm_operand_named_names( + int id: @asm_operand_named ref, + int name: @name ref +); + +asm_options_lists( + unique int id: @asm_options_list +); + +#keyset[id, index] +asm_options_list_asm_options( + int id: @asm_options_list ref, + int index: int ref, + int asm_option: @asm_option ref +); + +asm_reg_operands( + unique int id: @asm_reg_operand +); + +#keyset[id] +asm_reg_operand_asm_dir_specs( + int id: @asm_reg_operand ref, + int asm_dir_spec: @asm_dir_spec ref +); + +#keyset[id] +asm_reg_operand_asm_operand_exprs( + int id: @asm_reg_operand ref, + int asm_operand_expr: @asm_operand_expr ref +); + +#keyset[id] +asm_reg_operand_asm_reg_specs( + int id: @asm_reg_operand ref, + int asm_reg_spec: @asm_reg_spec ref +); + +asm_syms( + unique int id: @asm_sym +); + +#keyset[id] +asm_sym_paths( + int id: @asm_sym ref, + int path: @path ref +); + +assoc_type_args( + unique int id: @assoc_type_arg +); + +#keyset[id] +assoc_type_arg_const_args( + int id: @assoc_type_arg ref, + int const_arg: @const_arg ref +); + +#keyset[id] +assoc_type_arg_generic_arg_lists( + int id: @assoc_type_arg ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +assoc_type_arg_identifiers( + int id: @assoc_type_arg ref, + int identifier: @name_ref ref +); + +#keyset[id] +assoc_type_arg_param_lists( + int id: @assoc_type_arg ref, + int param_list: @param_list ref +); + +#keyset[id] +assoc_type_arg_ret_types( + int id: @assoc_type_arg ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +assoc_type_arg_return_type_syntaxes( + int id: @assoc_type_arg ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +assoc_type_arg_type_reprs( + int id: @assoc_type_arg ref, + int type_repr: @type_repr ref +); + +#keyset[id] +assoc_type_arg_type_bound_lists( + int id: @assoc_type_arg ref, + int type_bound_list: @type_bound_list ref +); + +await_exprs( + unique int id: @await_expr +); + +#keyset[id, index] +await_expr_attrs( + int id: @await_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +await_expr_exprs( + int id: @await_expr ref, + int expr: @expr ref +); + +become_exprs( + unique int id: @become_expr +); + +#keyset[id, index] +become_expr_attrs( + int id: @become_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +become_expr_exprs( + int id: @become_expr ref, + int expr: @expr ref +); + +binary_exprs( + unique int id: @binary_expr +); + +#keyset[id, index] +binary_expr_attrs( + int id: @binary_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +binary_expr_lhs( + int id: @binary_expr ref, + int lhs: @expr ref +); + +#keyset[id] +binary_expr_operator_names( + int id: @binary_expr ref, + string operator_name: string ref +); + +#keyset[id] +binary_expr_rhs( + int id: @binary_expr ref, + int rhs: @expr ref +); + +box_pats( + unique int id: @box_pat +); + +#keyset[id] +box_pat_pats( + int id: @box_pat ref, + int pat: @pat ref +); + +break_exprs( + unique int id: @break_expr +); + +#keyset[id, index] +break_expr_attrs( + int id: @break_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +break_expr_exprs( + int id: @break_expr ref, + int expr: @expr ref +); + +#keyset[id] +break_expr_lifetimes( + int id: @break_expr ref, + int lifetime: @lifetime ref +); + +call_exprs( + unique int id: @call_expr +); + +#keyset[id] +call_expr_arg_lists( + int id: @call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +call_expr_attrs( + int id: @call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +call_expr_functions( + int id: @call_expr ref, + int function: @expr ref +); + +cast_exprs( + unique int id: @cast_expr +); + +#keyset[id, index] +cast_expr_attrs( + int id: @cast_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +cast_expr_exprs( + int id: @cast_expr ref, + int expr: @expr ref +); + +#keyset[id] +cast_expr_type_reprs( + int id: @cast_expr ref, + int type_repr: @type_repr ref +); + +closure_exprs( + unique int id: @closure_expr +); + +#keyset[id] +closure_expr_closure_bodies( + int id: @closure_expr ref, + int closure_body: @expr ref +); + +#keyset[id] +closure_expr_for_binders( + int id: @closure_expr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +closure_expr_is_async( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_const( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_gen( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_move( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_static( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_ret_types( + int id: @closure_expr ref, + int ret_type: @ret_type_repr ref +); + +comments( + unique int id: @comment, + int parent: @ast_node ref, + string text: string ref +); + +const_args( + unique int id: @const_arg +); + +#keyset[id] +const_arg_exprs( + int id: @const_arg ref, + int expr: @expr ref +); + +const_block_pats( + unique int id: @const_block_pat +); + +#keyset[id] +const_block_pat_block_exprs( + int id: @const_block_pat ref, + int block_expr: @block_expr ref +); + +#keyset[id] +const_block_pat_is_const( + int id: @const_block_pat ref +); + +const_params( + unique int id: @const_param +); + +#keyset[id, index] +const_param_attrs( + int id: @const_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_param_default_vals( + int id: @const_param ref, + int default_val: @const_arg ref +); + +#keyset[id] +const_param_is_const( + int id: @const_param ref +); + +#keyset[id] +const_param_names( + int id: @const_param ref, + int name: @name ref +); + +#keyset[id] +const_param_type_reprs( + int id: @const_param ref, + int type_repr: @type_repr ref +); + +continue_exprs( + unique int id: @continue_expr +); + +#keyset[id, index] +continue_expr_attrs( + int id: @continue_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +continue_expr_lifetimes( + int id: @continue_expr ref, + int lifetime: @lifetime ref +); + +dyn_trait_type_reprs( + unique int id: @dyn_trait_type_repr +); + +#keyset[id] +dyn_trait_type_repr_type_bound_lists( + int id: @dyn_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +expr_stmts( + unique int id: @expr_stmt +); + +#keyset[id] +expr_stmt_exprs( + int id: @expr_stmt ref, + int expr: @expr ref +); + +field_exprs( + unique int id: @field_expr +); + +#keyset[id, index] +field_expr_attrs( + int id: @field_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +field_expr_containers( + int id: @field_expr ref, + int container: @expr ref +); + +#keyset[id] +field_expr_identifiers( + int id: @field_expr ref, + int identifier: @name_ref ref +); + +fn_ptr_type_reprs( + unique int id: @fn_ptr_type_repr +); + +#keyset[id] +fn_ptr_type_repr_abis( + int id: @fn_ptr_type_repr ref, + int abi: @abi ref +); + +#keyset[id] +fn_ptr_type_repr_is_async( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_const( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_unsafe( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_param_lists( + int id: @fn_ptr_type_repr ref, + int param_list: @param_list ref +); + +#keyset[id] +fn_ptr_type_repr_ret_types( + int id: @fn_ptr_type_repr ref, + int ret_type: @ret_type_repr ref +); + +for_type_reprs( + unique int id: @for_type_repr +); + +#keyset[id] +for_type_repr_for_binders( + int id: @for_type_repr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +for_type_repr_type_reprs( + int id: @for_type_repr ref, + int type_repr: @type_repr ref +); + +format_args_exprs( + unique int id: @format_args_expr +); + +#keyset[id, index] +format_args_expr_args( + int id: @format_args_expr ref, + int index: int ref, + int arg: @format_args_arg ref +); + +#keyset[id, index] +format_args_expr_attrs( + int id: @format_args_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +format_args_expr_templates( + int id: @format_args_expr ref, + int template: @expr ref +); + +ident_pats( + unique int id: @ident_pat +); + +#keyset[id, index] +ident_pat_attrs( + int id: @ident_pat ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ident_pat_is_mut( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_is_ref( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_names( + int id: @ident_pat ref, + int name: @name ref +); + +#keyset[id] +ident_pat_pats( + int id: @ident_pat ref, + int pat: @pat ref +); + +if_exprs( + unique int id: @if_expr +); + +#keyset[id, index] +if_expr_attrs( + int id: @if_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +if_expr_conditions( + int id: @if_expr ref, + int condition: @expr ref +); + +#keyset[id] +if_expr_elses( + int id: @if_expr ref, + int else: @expr ref +); + +#keyset[id] +if_expr_thens( + int id: @if_expr ref, + int then: @block_expr ref +); + +impl_trait_type_reprs( + unique int id: @impl_trait_type_repr +); + +#keyset[id] +impl_trait_type_repr_type_bound_lists( + int id: @impl_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +index_exprs( + unique int id: @index_expr +); + +#keyset[id, index] +index_expr_attrs( + int id: @index_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +index_expr_bases( + int id: @index_expr ref, + int base: @expr ref +); + +#keyset[id] +index_expr_indices( + int id: @index_expr ref, + int index: @expr ref +); + +infer_type_reprs( + unique int id: @infer_type_repr +); + +@item = + @asm_expr +| @assoc_item +| @extern_block +| @extern_crate +| @extern_item +| @impl +| @macro_def +| @macro_rules +| @module +| @trait +| @trait_alias +| @type_item +| @use +; + +#keyset[id] +item_attribute_macro_expansions( + int id: @item ref, + int attribute_macro_expansion: @macro_items ref +); + +@labelable_expr = + @block_expr +| @looping_expr +; + +#keyset[id] +labelable_expr_labels( + int id: @labelable_expr ref, + int label: @label ref +); + +let_exprs( + unique int id: @let_expr +); + +#keyset[id, index] +let_expr_attrs( + int id: @let_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_expr_scrutinees( + int id: @let_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +let_expr_pats( + int id: @let_expr ref, + int pat: @pat ref +); + +let_stmts( + unique int id: @let_stmt +); + +#keyset[id, index] +let_stmt_attrs( + int id: @let_stmt ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_stmt_initializers( + int id: @let_stmt ref, + int initializer: @expr ref +); + +#keyset[id] +let_stmt_let_elses( + int id: @let_stmt ref, + int let_else: @let_else ref +); + +#keyset[id] +let_stmt_pats( + int id: @let_stmt ref, + int pat: @pat ref +); + +#keyset[id] +let_stmt_type_reprs( + int id: @let_stmt ref, + int type_repr: @type_repr ref +); + +lifetimes( + unique int id: @lifetime +); + +#keyset[id] +lifetime_texts( + int id: @lifetime ref, + string text: string ref +); + +lifetime_args( + unique int id: @lifetime_arg +); + +#keyset[id] +lifetime_arg_lifetimes( + int id: @lifetime_arg ref, + int lifetime: @lifetime ref +); + +lifetime_params( + unique int id: @lifetime_param +); + +#keyset[id, index] +lifetime_param_attrs( + int id: @lifetime_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +lifetime_param_lifetimes( + int id: @lifetime_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +lifetime_param_type_bound_lists( + int id: @lifetime_param ref, + int type_bound_list: @type_bound_list ref +); + +literal_exprs( + unique int id: @literal_expr +); + +#keyset[id, index] +literal_expr_attrs( + int id: @literal_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +literal_expr_text_values( + int id: @literal_expr ref, + string text_value: string ref +); + +literal_pats( + unique int id: @literal_pat +); + +#keyset[id] +literal_pat_literals( + int id: @literal_pat ref, + int literal: @literal_expr ref +); + +macro_exprs( + unique int id: @macro_expr +); + +#keyset[id] +macro_expr_macro_calls( + int id: @macro_expr ref, + int macro_call: @macro_call ref +); + +macro_pats( + unique int id: @macro_pat +); + +#keyset[id] +macro_pat_macro_calls( + int id: @macro_pat ref, + int macro_call: @macro_call ref +); + +macro_type_reprs( + unique int id: @macro_type_repr +); + +#keyset[id] +macro_type_repr_macro_calls( + int id: @macro_type_repr ref, + int macro_call: @macro_call ref +); + +match_exprs( + unique int id: @match_expr +); + +#keyset[id, index] +match_expr_attrs( + int id: @match_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_expr_scrutinees( + int id: @match_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +match_expr_match_arm_lists( + int id: @match_expr ref, + int match_arm_list: @match_arm_list ref +); + +method_call_exprs( + unique int id: @method_call_expr +); + +#keyset[id] +method_call_expr_arg_lists( + int id: @method_call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +method_call_expr_attrs( + int id: @method_call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +method_call_expr_generic_arg_lists( + int id: @method_call_expr ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +method_call_expr_identifiers( + int id: @method_call_expr ref, + int identifier: @name_ref ref +); + +#keyset[id] +method_call_expr_receivers( + int id: @method_call_expr ref, + int receiver: @expr ref +); + +name_refs( + unique int id: @name_ref +); + +#keyset[id] +name_ref_texts( + int id: @name_ref ref, + string text: string ref +); + +never_type_reprs( + unique int id: @never_type_repr +); + +offset_of_exprs( + unique int id: @offset_of_expr +); + +#keyset[id, index] +offset_of_expr_attrs( + int id: @offset_of_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +offset_of_expr_fields( + int id: @offset_of_expr ref, + int index: int ref, + int field: @name_ref ref +); + +#keyset[id] +offset_of_expr_type_reprs( + int id: @offset_of_expr ref, + int type_repr: @type_repr ref +); + +or_pats( + unique int id: @or_pat +); + +#keyset[id, index] +or_pat_pats( + int id: @or_pat ref, + int index: int ref, + int pat: @pat ref +); + +params( + unique int id: @param +); + +#keyset[id] +param_pats( + int id: @param ref, + int pat: @pat ref +); + +paren_exprs( + unique int id: @paren_expr +); + +#keyset[id, index] +paren_expr_attrs( + int id: @paren_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +paren_expr_exprs( + int id: @paren_expr ref, + int expr: @expr ref +); + +paren_pats( + unique int id: @paren_pat +); + +#keyset[id] +paren_pat_pats( + int id: @paren_pat ref, + int pat: @pat ref +); + +paren_type_reprs( + unique int id: @paren_type_repr +); + +#keyset[id] +paren_type_repr_type_reprs( + int id: @paren_type_repr ref, + int type_repr: @type_repr ref +); + +@path_expr_base = + @path_expr +; + +path_pats( + unique int id: @path_pat +); + +path_type_reprs( + unique int id: @path_type_repr +); + +#keyset[id] +path_type_repr_paths( + int id: @path_type_repr ref, + int path: @path ref +); + +prefix_exprs( + unique int id: @prefix_expr +); + +#keyset[id, index] +prefix_expr_attrs( + int id: @prefix_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +prefix_expr_exprs( + int id: @prefix_expr ref, + int expr: @expr ref +); + +#keyset[id] +prefix_expr_operator_names( + int id: @prefix_expr ref, + string operator_name: string ref +); + +ptr_type_reprs( + unique int id: @ptr_type_repr +); + +#keyset[id] +ptr_type_repr_is_const( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_is_mut( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_type_reprs( + int id: @ptr_type_repr ref, + int type_repr: @type_repr ref +); + +range_exprs( + unique int id: @range_expr +); + +#keyset[id, index] +range_expr_attrs( + int id: @range_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +range_expr_ends( + int id: @range_expr ref, + int end: @expr ref +); + +#keyset[id] +range_expr_operator_names( + int id: @range_expr ref, + string operator_name: string ref +); + +#keyset[id] +range_expr_starts( + int id: @range_expr ref, + int start: @expr ref +); + +range_pats( + unique int id: @range_pat +); + +#keyset[id] +range_pat_ends( + int id: @range_pat ref, + int end: @pat ref +); + +#keyset[id] +range_pat_operator_names( + int id: @range_pat ref, + string operator_name: string ref +); + +#keyset[id] +range_pat_starts( + int id: @range_pat ref, + int start: @pat ref +); + +ref_exprs( + unique int id: @ref_expr +); + +#keyset[id, index] +ref_expr_attrs( + int id: @ref_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ref_expr_exprs( + int id: @ref_expr ref, + int expr: @expr ref +); + +#keyset[id] +ref_expr_is_const( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_mut( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_raw( + int id: @ref_expr ref +); + +ref_pats( + unique int id: @ref_pat +); + +#keyset[id] +ref_pat_is_mut( + int id: @ref_pat ref +); + +#keyset[id] +ref_pat_pats( + int id: @ref_pat ref, + int pat: @pat ref +); + +ref_type_reprs( + unique int id: @ref_type_repr +); + +#keyset[id] +ref_type_repr_is_mut( + int id: @ref_type_repr ref +); + +#keyset[id] +ref_type_repr_lifetimes( + int id: @ref_type_repr ref, + int lifetime: @lifetime ref +); + +#keyset[id] +ref_type_repr_type_reprs( + int id: @ref_type_repr ref, + int type_repr: @type_repr ref +); + +rest_pats( + unique int id: @rest_pat +); + +#keyset[id, index] +rest_pat_attrs( + int id: @rest_pat ref, + int index: int ref, + int attr: @attr ref +); + +return_exprs( + unique int id: @return_expr +); + +#keyset[id, index] +return_expr_attrs( + int id: @return_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +return_expr_exprs( + int id: @return_expr ref, + int expr: @expr ref +); + +self_params( + unique int id: @self_param +); + +#keyset[id] +self_param_is_ref( + int id: @self_param ref +); + +#keyset[id] +self_param_is_mut( + int id: @self_param ref +); + +#keyset[id] +self_param_lifetimes( + int id: @self_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +self_param_names( + int id: @self_param ref, + int name: @name ref +); + +slice_pats( + unique int id: @slice_pat +); + +#keyset[id, index] +slice_pat_pats( + int id: @slice_pat ref, + int index: int ref, + int pat: @pat ref +); + +slice_type_reprs( + unique int id: @slice_type_repr +); + +#keyset[id] +slice_type_repr_type_reprs( + int id: @slice_type_repr ref, + int type_repr: @type_repr ref +); + +struct_exprs( + unique int id: @struct_expr +); + +#keyset[id] +struct_expr_struct_expr_field_lists( + int id: @struct_expr ref, + int struct_expr_field_list: @struct_expr_field_list ref +); + +struct_field_lists( + unique int id: @struct_field_list +); + +#keyset[id, index] +struct_field_list_fields( + int id: @struct_field_list ref, + int index: int ref, + int field: @struct_field ref +); + +struct_pats( + unique int id: @struct_pat +); + +#keyset[id] +struct_pat_struct_pat_field_lists( + int id: @struct_pat ref, + int struct_pat_field_list: @struct_pat_field_list ref +); + +try_exprs( + unique int id: @try_expr +); + +#keyset[id, index] +try_expr_attrs( + int id: @try_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +try_expr_exprs( + int id: @try_expr ref, + int expr: @expr ref +); + +tuple_exprs( + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_attrs( + int id: @tuple_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +tuple_expr_fields( + int id: @tuple_expr ref, + int index: int ref, + int field: @expr ref +); + +tuple_field_lists( + unique int id: @tuple_field_list +); + +#keyset[id, index] +tuple_field_list_fields( + int id: @tuple_field_list ref, + int index: int ref, + int field: @tuple_field ref +); + +tuple_pats( + unique int id: @tuple_pat +); + +#keyset[id, index] +tuple_pat_fields( + int id: @tuple_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_struct_pats( + unique int id: @tuple_struct_pat +); + +#keyset[id, index] +tuple_struct_pat_fields( + int id: @tuple_struct_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_type_reprs( + unique int id: @tuple_type_repr +); + +#keyset[id, index] +tuple_type_repr_fields( + int id: @tuple_type_repr ref, + int index: int ref, + int field: @type_repr ref +); + +type_args( + unique int id: @type_arg +); + +#keyset[id] +type_arg_type_reprs( + int id: @type_arg ref, + int type_repr: @type_repr ref +); + +type_params( + unique int id: @type_param +); + +#keyset[id, index] +type_param_attrs( + int id: @type_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_param_default_types( + int id: @type_param ref, + int default_type: @type_repr ref +); + +#keyset[id] +type_param_names( + int id: @type_param ref, + int name: @name ref +); + +#keyset[id] +type_param_type_bound_lists( + int id: @type_param ref, + int type_bound_list: @type_bound_list ref +); + +underscore_exprs( + unique int id: @underscore_expr +); + +#keyset[id, index] +underscore_expr_attrs( + int id: @underscore_expr ref, + int index: int ref, + int attr: @attr ref +); + +variants( + unique int id: @variant +); + +#keyset[id, index] +variant_attrs( + int id: @variant ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +variant_discriminants( + int id: @variant ref, + int discriminant: @expr ref +); + +#keyset[id] +variant_field_lists( + int id: @variant ref, + int field_list: @field_list ref +); + +#keyset[id] +variant_names( + int id: @variant ref, + int name: @name ref +); + +#keyset[id] +variant_visibilities( + int id: @variant ref, + int visibility: @visibility ref +); + +wildcard_pats( + unique int id: @wildcard_pat +); + +yeet_exprs( + unique int id: @yeet_expr +); + +#keyset[id, index] +yeet_expr_attrs( + int id: @yeet_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yeet_expr_exprs( + int id: @yeet_expr ref, + int expr: @expr ref +); + +yield_exprs( + unique int id: @yield_expr +); + +#keyset[id, index] +yield_expr_attrs( + int id: @yield_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yield_expr_exprs( + int id: @yield_expr ref, + int expr: @expr ref +); + +asm_exprs( + unique int id: @asm_expr +); + +#keyset[id, index] +asm_expr_asm_pieces( + int id: @asm_expr ref, + int index: int ref, + int asm_piece: @asm_piece ref +); + +#keyset[id, index] +asm_expr_attrs( + int id: @asm_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +asm_expr_templates( + int id: @asm_expr ref, + int index: int ref, + int template: @expr ref +); + +@assoc_item = + @const +| @function +| @macro_call +| @type_alias +; + +block_exprs( + unique int id: @block_expr +); + +#keyset[id, index] +block_expr_attrs( + int id: @block_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +block_expr_is_async( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_const( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_gen( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_move( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_try( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_unsafe( + int id: @block_expr ref +); + +#keyset[id] +block_expr_stmt_lists( + int id: @block_expr ref, + int stmt_list: @stmt_list ref +); + +extern_blocks( + unique int id: @extern_block +); + +#keyset[id] +extern_block_abis( + int id: @extern_block ref, + int abi: @abi ref +); + +#keyset[id, index] +extern_block_attrs( + int id: @extern_block ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_block_extern_item_lists( + int id: @extern_block ref, + int extern_item_list: @extern_item_list ref +); + +#keyset[id] +extern_block_is_unsafe( + int id: @extern_block ref +); + +extern_crates( + unique int id: @extern_crate +); + +#keyset[id, index] +extern_crate_attrs( + int id: @extern_crate ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_crate_identifiers( + int id: @extern_crate ref, + int identifier: @name_ref ref +); + +#keyset[id] +extern_crate_renames( + int id: @extern_crate ref, + int rename: @rename ref +); + +#keyset[id] +extern_crate_visibilities( + int id: @extern_crate ref, + int visibility: @visibility ref +); + +@extern_item = + @function +| @macro_call +| @static +| @type_alias +; + +impls( + unique int id: @impl +); + +#keyset[id] +impl_assoc_item_lists( + int id: @impl ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +impl_attrs( + int id: @impl ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +impl_generic_param_lists( + int id: @impl ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +impl_is_const( + int id: @impl ref +); + +#keyset[id] +impl_is_default( + int id: @impl ref +); + +#keyset[id] +impl_is_unsafe( + int id: @impl ref +); + +#keyset[id] +impl_self_ties( + int id: @impl ref, + int self_ty: @type_repr ref +); + +#keyset[id] +impl_traits( + int id: @impl ref, + int trait: @type_repr ref +); + +#keyset[id] +impl_visibilities( + int id: @impl ref, + int visibility: @visibility ref +); + +#keyset[id] +impl_where_clauses( + int id: @impl ref, + int where_clause: @where_clause ref +); + +@looping_expr = + @for_expr +| @loop_expr +| @while_expr +; + +#keyset[id] +looping_expr_loop_bodies( + int id: @looping_expr ref, + int loop_body: @block_expr ref +); + +macro_defs( + unique int id: @macro_def +); + +#keyset[id] +macro_def_args( + int id: @macro_def ref, + int args: @token_tree ref +); + +#keyset[id, index] +macro_def_attrs( + int id: @macro_def ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_def_bodies( + int id: @macro_def ref, + int body: @token_tree ref +); + +#keyset[id] +macro_def_names( + int id: @macro_def ref, + int name: @name ref +); + +#keyset[id] +macro_def_visibilities( + int id: @macro_def ref, + int visibility: @visibility ref +); + +macro_rules( + unique int id: @macro_rules +); + +#keyset[id, index] +macro_rules_attrs( + int id: @macro_rules ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_rules_names( + int id: @macro_rules ref, + int name: @name ref +); + +#keyset[id] +macro_rules_token_trees( + int id: @macro_rules ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_rules_visibilities( + int id: @macro_rules ref, + int visibility: @visibility ref +); + +modules( + unique int id: @module +); + +#keyset[id, index] +module_attrs( + int id: @module ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +module_item_lists( + int id: @module ref, + int item_list: @item_list ref +); + +#keyset[id] +module_names( + int id: @module ref, + int name: @name ref +); + +#keyset[id] +module_visibilities( + int id: @module ref, + int visibility: @visibility ref +); + +path_exprs( + unique int id: @path_expr +); + +#keyset[id, index] +path_expr_attrs( + int id: @path_expr ref, + int index: int ref, + int attr: @attr ref +); + +traits( + unique int id: @trait +); + +#keyset[id] +trait_assoc_item_lists( + int id: @trait ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +trait_attrs( + int id: @trait ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_generic_param_lists( + int id: @trait ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_is_auto( + int id: @trait ref +); + +#keyset[id] +trait_is_unsafe( + int id: @trait ref +); + +#keyset[id] +trait_names( + int id: @trait ref, + int name: @name ref +); + +#keyset[id] +trait_type_bound_lists( + int id: @trait ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_visibilities( + int id: @trait ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_where_clauses( + int id: @trait ref, + int where_clause: @where_clause ref +); + +trait_aliases( + unique int id: @trait_alias +); + +#keyset[id, index] +trait_alias_attrs( + int id: @trait_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_alias_generic_param_lists( + int id: @trait_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_alias_names( + int id: @trait_alias ref, + int name: @name ref +); + +#keyset[id] +trait_alias_type_bound_lists( + int id: @trait_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_alias_visibilities( + int id: @trait_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_alias_where_clauses( + int id: @trait_alias ref, + int where_clause: @where_clause ref +); + +@type_item = + @enum +| @struct +| @union +; + +#keyset[id, index] +type_item_derive_macro_expansions( + int id: @type_item ref, + int index: int ref, + int derive_macro_expansion: @macro_items ref +); + +#keyset[id, index] +type_item_attrs( + int id: @type_item ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_item_generic_param_lists( + int id: @type_item ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_item_names( + int id: @type_item ref, + int name: @name ref +); + +#keyset[id] +type_item_visibilities( + int id: @type_item ref, + int visibility: @visibility ref +); + +#keyset[id] +type_item_where_clauses( + int id: @type_item ref, + int where_clause: @where_clause ref +); + +uses( + unique int id: @use +); + +#keyset[id, index] +use_attrs( + int id: @use ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +use_use_trees( + int id: @use ref, + int use_tree: @use_tree ref +); + +#keyset[id] +use_visibilities( + int id: @use ref, + int visibility: @visibility ref +); + +consts( + unique int id: @const +); + +#keyset[id, index] +const_attrs( + int id: @const ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_bodies( + int id: @const ref, + int body: @expr ref +); + +#keyset[id] +const_generic_param_lists( + int id: @const ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +const_is_const( + int id: @const ref +); + +#keyset[id] +const_is_default( + int id: @const ref +); + +#keyset[id] +const_names( + int id: @const ref, + int name: @name ref +); + +#keyset[id] +const_type_reprs( + int id: @const ref, + int type_repr: @type_repr ref +); + +#keyset[id] +const_visibilities( + int id: @const ref, + int visibility: @visibility ref +); + +#keyset[id] +const_where_clauses( + int id: @const ref, + int where_clause: @where_clause ref +); + +#keyset[id] +const_has_implementation( + int id: @const ref +); + +enums( + unique int id: @enum +); + +#keyset[id] +enum_variant_lists( + int id: @enum ref, + int variant_list: @variant_list ref +); + +for_exprs( + unique int id: @for_expr +); + +#keyset[id, index] +for_expr_attrs( + int id: @for_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +for_expr_iterables( + int id: @for_expr ref, + int iterable: @expr ref +); + +#keyset[id] +for_expr_pats( + int id: @for_expr ref, + int pat: @pat ref +); + +functions( + unique int id: @function +); + +#keyset[id] +function_abis( + int id: @function ref, + int abi: @abi ref +); + +#keyset[id] +function_function_bodies( + int id: @function ref, + int function_body: @block_expr ref +); + +#keyset[id] +function_generic_param_lists( + int id: @function ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +function_is_async( + int id: @function ref +); + +#keyset[id] +function_is_const( + int id: @function ref +); + +#keyset[id] +function_is_default( + int id: @function ref +); + +#keyset[id] +function_is_gen( + int id: @function ref +); + +#keyset[id] +function_is_unsafe( + int id: @function ref +); + +#keyset[id] +function_names( + int id: @function ref, + int name: @name ref +); + +#keyset[id] +function_ret_types( + int id: @function ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +function_visibilities( + int id: @function ref, + int visibility: @visibility ref +); + +#keyset[id] +function_where_clauses( + int id: @function ref, + int where_clause: @where_clause ref +); + +#keyset[id] +function_has_implementation( + int id: @function ref +); + +loop_exprs( + unique int id: @loop_expr +); + +#keyset[id, index] +loop_expr_attrs( + int id: @loop_expr ref, + int index: int ref, + int attr: @attr ref +); + +macro_calls( + unique int id: @macro_call +); + +#keyset[id, index] +macro_call_attrs( + int id: @macro_call ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_call_paths( + int id: @macro_call ref, + int path: @path ref +); + +#keyset[id] +macro_call_token_trees( + int id: @macro_call ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_call_macro_call_expansions( + int id: @macro_call ref, + int macro_call_expansion: @ast_node ref +); + +statics( + unique int id: @static +); + +#keyset[id, index] +static_attrs( + int id: @static ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +static_bodies( + int id: @static ref, + int body: @expr ref +); + +#keyset[id] +static_is_mut( + int id: @static ref +); + +#keyset[id] +static_is_static( + int id: @static ref +); + +#keyset[id] +static_is_unsafe( + int id: @static ref +); + +#keyset[id] +static_names( + int id: @static ref, + int name: @name ref +); + +#keyset[id] +static_type_reprs( + int id: @static ref, + int type_repr: @type_repr ref +); + +#keyset[id] +static_visibilities( + int id: @static ref, + int visibility: @visibility ref +); + +structs( + unique int id: @struct +); + +#keyset[id] +struct_field_lists_( + int id: @struct ref, + int field_list: @field_list ref +); + +type_aliases( + unique int id: @type_alias +); + +#keyset[id, index] +type_alias_attrs( + int id: @type_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_alias_generic_param_lists( + int id: @type_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_alias_is_default( + int id: @type_alias ref +); + +#keyset[id] +type_alias_names( + int id: @type_alias ref, + int name: @name ref +); + +#keyset[id] +type_alias_type_reprs( + int id: @type_alias ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_alias_type_bound_lists( + int id: @type_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +type_alias_visibilities( + int id: @type_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +type_alias_where_clauses( + int id: @type_alias ref, + int where_clause: @where_clause ref +); + +unions( + unique int id: @union +); + +#keyset[id] +union_struct_field_lists( + int id: @union ref, + int struct_field_list: @struct_field_list ref +); + +while_exprs( + unique int id: @while_expr +); + +#keyset[id, index] +while_expr_attrs( + int id: @while_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +while_expr_conditions( + int id: @while_expr ref, + int condition: @expr ref +); diff --git a/rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/upgrade.properties b/rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/upgrade.properties new file mode 100644 index 00000000000..af2a9345570 --- /dev/null +++ b/rust/downgrades/77e9a70be4b0cf5ecb1d4c1d841b2d970715a912/upgrade.properties @@ -0,0 +1,5 @@ +description: Renamed `impl_trait_ties` to `impl_traits` +compatibility: full + +impl_traits.rel: reorder impl_trait_ties(@impl id, @type_repr trait_ty) id trait_ty +impl_trait_ties.rel: delete \ No newline at end of file diff --git a/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/old.dbscheme b/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/old.dbscheme new file mode 100644 index 00000000000..66a48986364 --- /dev/null +++ b/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/old.dbscheme @@ -0,0 +1,3556 @@ +// generated by codegen, do not edit + +// from ../shared/tree-sitter-extractor/src/generator/prefix.dbscheme +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ + +/** + * The CLI will automatically emit applicable tuples for this table, + * such as `databaseMetadata("isOverlay", "true")` when building an + * overlay database. + */ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Overlay support -*/ + +/** + * The CLI will automatically emit tuples for each new/modified/deleted file + * when building an overlay database. + */ +overlayChangedFiles( + string path: string ref +); + + +// from prefix.dbscheme +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_default ref +); + + +// from schema + +@element = + @extractor_step +| @locatable +| @named_crate +| @unextracted +; + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int duration_ms: int ref +); + +#keyset[id] +extractor_step_files( + int id: @extractor_step ref, + int file: @file ref +); + +@locatable = + @ast_node +| @crate +; + +named_crates( + unique int id: @named_crate, + string name: string ref, + int crate: @crate ref +); + +@unextracted = + @missing +| @unimplemented +; + +@ast_node = + @abi +| @addressable +| @arg_list +| @asm_dir_spec +| @asm_operand +| @asm_operand_expr +| @asm_option +| @asm_piece +| @asm_reg_spec +| @assoc_item_list +| @attr +| @callable +| @expr +| @extern_item_list +| @field_list +| @for_binder +| @format_args_arg +| @generic_arg +| @generic_arg_list +| @generic_param +| @generic_param_list +| @item_list +| @label +| @let_else +| @macro_items +| @match_arm +| @match_arm_list +| @match_guard +| @meta +| @name +| @param_base +| @param_list +| @parenthesized_arg_list +| @pat +| @path +| @path_ast_node +| @path_segment +| @rename +| @ret_type_repr +| @return_type_syntax +| @source_file +| @stmt +| @stmt_list +| @struct_expr_field +| @struct_expr_field_list +| @struct_field +| @struct_pat_field +| @struct_pat_field_list +| @token +| @token_tree +| @tuple_field +| @type_bound +| @type_bound_list +| @type_repr +| @use_bound_generic_arg +| @use_bound_generic_args +| @use_tree +| @use_tree_list +| @variant_list +| @visibility +| @where_clause +| @where_pred +; + +crates( + unique int id: @crate +); + +#keyset[id] +crate_names( + int id: @crate ref, + string name: string ref +); + +#keyset[id] +crate_versions( + int id: @crate ref, + string version: string ref +); + +#keyset[id, index] +crate_cfg_options( + int id: @crate ref, + int index: int ref, + string cfg_option: string ref +); + +#keyset[id, index] +crate_named_dependencies( + int id: @crate ref, + int index: int ref, + int named_dependency: @named_crate ref +); + +missings( + unique int id: @missing +); + +unimplementeds( + unique int id: @unimplemented +); + +abis( + unique int id: @abi +); + +#keyset[id] +abi_abi_strings( + int id: @abi ref, + string abi_string: string ref +); + +@addressable = + @item +| @variant +; + +arg_lists( + unique int id: @arg_list +); + +#keyset[id, index] +arg_list_args( + int id: @arg_list ref, + int index: int ref, + int arg: @expr ref +); + +asm_dir_specs( + unique int id: @asm_dir_spec +); + +@asm_operand = + @asm_const +| @asm_label +| @asm_reg_operand +| @asm_sym +; + +asm_operand_exprs( + unique int id: @asm_operand_expr +); + +#keyset[id] +asm_operand_expr_in_exprs( + int id: @asm_operand_expr ref, + int in_expr: @expr ref +); + +#keyset[id] +asm_operand_expr_out_exprs( + int id: @asm_operand_expr ref, + int out_expr: @expr ref +); + +asm_options( + unique int id: @asm_option +); + +#keyset[id] +asm_option_is_raw( + int id: @asm_option ref +); + +@asm_piece = + @asm_clobber_abi +| @asm_operand_named +| @asm_options_list +; + +asm_reg_specs( + unique int id: @asm_reg_spec +); + +#keyset[id] +asm_reg_spec_identifiers( + int id: @asm_reg_spec ref, + int identifier: @name_ref ref +); + +assoc_item_lists( + unique int id: @assoc_item_list +); + +#keyset[id, index] +assoc_item_list_assoc_items( + int id: @assoc_item_list ref, + int index: int ref, + int assoc_item: @assoc_item ref +); + +#keyset[id, index] +assoc_item_list_attrs( + int id: @assoc_item_list ref, + int index: int ref, + int attr: @attr ref +); + +attrs( + unique int id: @attr +); + +#keyset[id] +attr_meta( + int id: @attr ref, + int meta: @meta ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_param_lists( + int id: @callable ref, + int param_list: @param_list ref +); + +#keyset[id, index] +callable_attrs( + int id: @callable ref, + int index: int ref, + int attr: @attr ref +); + +@expr = + @array_expr_internal +| @asm_expr +| @await_expr +| @become_expr +| @binary_expr +| @break_expr +| @call_expr +| @cast_expr +| @closure_expr +| @continue_expr +| @field_expr +| @format_args_expr +| @if_expr +| @index_expr +| @labelable_expr +| @let_expr +| @literal_expr +| @macro_expr +| @match_expr +| @method_call_expr +| @offset_of_expr +| @paren_expr +| @path_expr_base +| @prefix_expr +| @range_expr +| @ref_expr +| @return_expr +| @struct_expr +| @try_expr +| @tuple_expr +| @underscore_expr +| @yeet_expr +| @yield_expr +; + +extern_item_lists( + unique int id: @extern_item_list +); + +#keyset[id, index] +extern_item_list_attrs( + int id: @extern_item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +extern_item_list_extern_items( + int id: @extern_item_list ref, + int index: int ref, + int extern_item: @extern_item ref +); + +@field_list = + @struct_field_list +| @tuple_field_list +; + +for_binders( + unique int id: @for_binder +); + +#keyset[id] +for_binder_generic_param_lists( + int id: @for_binder ref, + int generic_param_list: @generic_param_list ref +); + +format_args_args( + unique int id: @format_args_arg +); + +#keyset[id] +format_args_arg_exprs( + int id: @format_args_arg ref, + int expr: @expr ref +); + +#keyset[id] +format_args_arg_names( + int id: @format_args_arg ref, + int name: @name ref +); + +@generic_arg = + @assoc_type_arg +| @const_arg +| @lifetime_arg +| @type_arg +; + +generic_arg_lists( + unique int id: @generic_arg_list +); + +#keyset[id, index] +generic_arg_list_generic_args( + int id: @generic_arg_list ref, + int index: int ref, + int generic_arg: @generic_arg ref +); + +@generic_param = + @const_param +| @lifetime_param +| @type_param +; + +generic_param_lists( + unique int id: @generic_param_list +); + +#keyset[id, index] +generic_param_list_generic_params( + int id: @generic_param_list ref, + int index: int ref, + int generic_param: @generic_param ref +); + +item_lists( + unique int id: @item_list +); + +#keyset[id, index] +item_list_attrs( + int id: @item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +item_list_items( + int id: @item_list ref, + int index: int ref, + int item: @item ref +); + +labels( + unique int id: @label +); + +#keyset[id] +label_lifetimes( + int id: @label ref, + int lifetime: @lifetime ref +); + +let_elses( + unique int id: @let_else +); + +#keyset[id] +let_else_block_exprs( + int id: @let_else ref, + int block_expr: @block_expr ref +); + +macro_items( + unique int id: @macro_items +); + +#keyset[id, index] +macro_items_items( + int id: @macro_items ref, + int index: int ref, + int item: @item ref +); + +match_arms( + unique int id: @match_arm +); + +#keyset[id, index] +match_arm_attrs( + int id: @match_arm ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_arm_exprs( + int id: @match_arm ref, + int expr: @expr ref +); + +#keyset[id] +match_arm_guards( + int id: @match_arm ref, + int guard: @match_guard ref +); + +#keyset[id] +match_arm_pats( + int id: @match_arm ref, + int pat: @pat ref +); + +match_arm_lists( + unique int id: @match_arm_list +); + +#keyset[id, index] +match_arm_list_arms( + int id: @match_arm_list ref, + int index: int ref, + int arm: @match_arm ref +); + +#keyset[id, index] +match_arm_list_attrs( + int id: @match_arm_list ref, + int index: int ref, + int attr: @attr ref +); + +match_guards( + unique int id: @match_guard +); + +#keyset[id] +match_guard_conditions( + int id: @match_guard ref, + int condition: @expr ref +); + +meta( + unique int id: @meta +); + +#keyset[id] +meta_exprs( + int id: @meta ref, + int expr: @expr ref +); + +#keyset[id] +meta_is_unsafe( + int id: @meta ref +); + +#keyset[id] +meta_paths( + int id: @meta ref, + int path: @path ref +); + +#keyset[id] +meta_token_trees( + int id: @meta ref, + int token_tree: @token_tree ref +); + +names( + unique int id: @name +); + +#keyset[id] +name_texts( + int id: @name ref, + string text: string ref +); + +@param_base = + @param +| @self_param +; + +#keyset[id, index] +param_base_attrs( + int id: @param_base ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +param_base_type_reprs( + int id: @param_base ref, + int type_repr: @type_repr ref +); + +param_lists( + unique int id: @param_list +); + +#keyset[id, index] +param_list_params( + int id: @param_list ref, + int index: int ref, + int param: @param ref +); + +#keyset[id] +param_list_self_params( + int id: @param_list ref, + int self_param: @self_param ref +); + +parenthesized_arg_lists( + unique int id: @parenthesized_arg_list +); + +#keyset[id, index] +parenthesized_arg_list_type_args( + int id: @parenthesized_arg_list ref, + int index: int ref, + int type_arg: @type_arg ref +); + +@pat = + @box_pat +| @const_block_pat +| @ident_pat +| @literal_pat +| @macro_pat +| @or_pat +| @paren_pat +| @path_pat +| @range_pat +| @ref_pat +| @rest_pat +| @slice_pat +| @struct_pat +| @tuple_pat +| @tuple_struct_pat +| @wildcard_pat +; + +paths( + unique int id: @path +); + +#keyset[id] +path_qualifiers( + int id: @path ref, + int qualifier: @path ref +); + +#keyset[id] +path_segments_( + int id: @path ref, + int segment: @path_segment ref +); + +@path_ast_node = + @path_expr +| @path_pat +| @struct_expr +| @struct_pat +| @tuple_struct_pat +; + +#keyset[id] +path_ast_node_paths( + int id: @path_ast_node ref, + int path: @path ref +); + +path_segments( + unique int id: @path_segment +); + +#keyset[id] +path_segment_generic_arg_lists( + int id: @path_segment ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +path_segment_identifiers( + int id: @path_segment ref, + int identifier: @name_ref ref +); + +#keyset[id] +path_segment_parenthesized_arg_lists( + int id: @path_segment ref, + int parenthesized_arg_list: @parenthesized_arg_list ref +); + +#keyset[id] +path_segment_ret_types( + int id: @path_segment ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +path_segment_return_type_syntaxes( + int id: @path_segment ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +path_segment_type_reprs( + int id: @path_segment ref, + int type_repr: @type_repr ref +); + +#keyset[id] +path_segment_trait_type_reprs( + int id: @path_segment ref, + int trait_type_repr: @path_type_repr ref +); + +renames( + unique int id: @rename +); + +#keyset[id] +rename_names( + int id: @rename ref, + int name: @name ref +); + +ret_type_reprs( + unique int id: @ret_type_repr +); + +#keyset[id] +ret_type_repr_type_reprs( + int id: @ret_type_repr ref, + int type_repr: @type_repr ref +); + +return_type_syntaxes( + unique int id: @return_type_syntax +); + +source_files( + unique int id: @source_file +); + +#keyset[id, index] +source_file_attrs( + int id: @source_file ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +source_file_items( + int id: @source_file ref, + int index: int ref, + int item: @item ref +); + +@stmt = + @expr_stmt +| @item +| @let_stmt +; + +stmt_lists( + unique int id: @stmt_list +); + +#keyset[id, index] +stmt_list_attrs( + int id: @stmt_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +stmt_list_statements( + int id: @stmt_list ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +stmt_list_tail_exprs( + int id: @stmt_list ref, + int tail_expr: @expr ref +); + +struct_expr_fields( + unique int id: @struct_expr_field +); + +#keyset[id, index] +struct_expr_field_attrs( + int id: @struct_expr_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_expr_field_exprs( + int id: @struct_expr_field ref, + int expr: @expr ref +); + +#keyset[id] +struct_expr_field_identifiers( + int id: @struct_expr_field ref, + int identifier: @name_ref ref +); + +struct_expr_field_lists( + unique int id: @struct_expr_field_list +); + +#keyset[id, index] +struct_expr_field_list_attrs( + int id: @struct_expr_field_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +struct_expr_field_list_fields( + int id: @struct_expr_field_list ref, + int index: int ref, + int field: @struct_expr_field ref +); + +#keyset[id] +struct_expr_field_list_spreads( + int id: @struct_expr_field_list ref, + int spread: @expr ref +); + +struct_fields( + unique int id: @struct_field +); + +#keyset[id, index] +struct_field_attrs( + int id: @struct_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_defaults( + int id: @struct_field ref, + int default: @expr ref +); + +#keyset[id] +struct_field_is_unsafe( + int id: @struct_field ref +); + +#keyset[id] +struct_field_names( + int id: @struct_field ref, + int name: @name ref +); + +#keyset[id] +struct_field_type_reprs( + int id: @struct_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +struct_field_visibilities( + int id: @struct_field ref, + int visibility: @visibility ref +); + +struct_pat_fields( + unique int id: @struct_pat_field +); + +#keyset[id, index] +struct_pat_field_attrs( + int id: @struct_pat_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_pat_field_identifiers( + int id: @struct_pat_field ref, + int identifier: @name_ref ref +); + +#keyset[id] +struct_pat_field_pats( + int id: @struct_pat_field ref, + int pat: @pat ref +); + +struct_pat_field_lists( + unique int id: @struct_pat_field_list +); + +#keyset[id, index] +struct_pat_field_list_fields( + int id: @struct_pat_field_list ref, + int index: int ref, + int field: @struct_pat_field ref +); + +#keyset[id] +struct_pat_field_list_rest_pats( + int id: @struct_pat_field_list ref, + int rest_pat: @rest_pat ref +); + +@token = + @comment +; + +token_trees( + unique int id: @token_tree +); + +tuple_fields( + unique int id: @tuple_field +); + +#keyset[id, index] +tuple_field_attrs( + int id: @tuple_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +tuple_field_type_reprs( + int id: @tuple_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +tuple_field_visibilities( + int id: @tuple_field ref, + int visibility: @visibility ref +); + +type_bounds( + unique int id: @type_bound +); + +#keyset[id] +type_bound_for_binders( + int id: @type_bound ref, + int for_binder: @for_binder ref +); + +#keyset[id] +type_bound_is_async( + int id: @type_bound ref +); + +#keyset[id] +type_bound_is_const( + int id: @type_bound ref +); + +#keyset[id] +type_bound_lifetimes( + int id: @type_bound ref, + int lifetime: @lifetime ref +); + +#keyset[id] +type_bound_type_reprs( + int id: @type_bound ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_bound_use_bound_generic_args( + int id: @type_bound ref, + int use_bound_generic_args: @use_bound_generic_args ref +); + +type_bound_lists( + unique int id: @type_bound_list +); + +#keyset[id, index] +type_bound_list_bounds( + int id: @type_bound_list ref, + int index: int ref, + int bound: @type_bound ref +); + +@type_repr = + @array_type_repr +| @dyn_trait_type_repr +| @fn_ptr_type_repr +| @for_type_repr +| @impl_trait_type_repr +| @infer_type_repr +| @macro_type_repr +| @never_type_repr +| @paren_type_repr +| @path_type_repr +| @ptr_type_repr +| @ref_type_repr +| @slice_type_repr +| @tuple_type_repr +; + +@use_bound_generic_arg = + @lifetime +| @name_ref +; + +use_bound_generic_args( + unique int id: @use_bound_generic_args +); + +#keyset[id, index] +use_bound_generic_args_use_bound_generic_args( + int id: @use_bound_generic_args ref, + int index: int ref, + int use_bound_generic_arg: @use_bound_generic_arg ref +); + +use_trees( + unique int id: @use_tree +); + +#keyset[id] +use_tree_is_glob( + int id: @use_tree ref +); + +#keyset[id] +use_tree_paths( + int id: @use_tree ref, + int path: @path ref +); + +#keyset[id] +use_tree_renames( + int id: @use_tree ref, + int rename: @rename ref +); + +#keyset[id] +use_tree_use_tree_lists( + int id: @use_tree ref, + int use_tree_list: @use_tree_list ref +); + +use_tree_lists( + unique int id: @use_tree_list +); + +#keyset[id, index] +use_tree_list_use_trees( + int id: @use_tree_list ref, + int index: int ref, + int use_tree: @use_tree ref +); + +variant_lists( + unique int id: @variant_list +); + +#keyset[id, index] +variant_list_variants( + int id: @variant_list ref, + int index: int ref, + int variant: @variant ref +); + +visibilities( + unique int id: @visibility +); + +#keyset[id] +visibility_paths( + int id: @visibility ref, + int path: @path ref +); + +where_clauses( + unique int id: @where_clause +); + +#keyset[id, index] +where_clause_predicates( + int id: @where_clause ref, + int index: int ref, + int predicate: @where_pred ref +); + +where_preds( + unique int id: @where_pred +); + +#keyset[id] +where_pred_for_binders( + int id: @where_pred ref, + int for_binder: @for_binder ref +); + +#keyset[id] +where_pred_lifetimes( + int id: @where_pred ref, + int lifetime: @lifetime ref +); + +#keyset[id] +where_pred_type_reprs( + int id: @where_pred ref, + int type_repr: @type_repr ref +); + +#keyset[id] +where_pred_type_bound_lists( + int id: @where_pred ref, + int type_bound_list: @type_bound_list ref +); + +array_expr_internals( + unique int id: @array_expr_internal +); + +#keyset[id, index] +array_expr_internal_attrs( + int id: @array_expr_internal ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +array_expr_internal_exprs( + int id: @array_expr_internal ref, + int index: int ref, + int expr: @expr ref +); + +#keyset[id] +array_expr_internal_is_semicolon( + int id: @array_expr_internal ref +); + +array_type_reprs( + unique int id: @array_type_repr +); + +#keyset[id] +array_type_repr_const_args( + int id: @array_type_repr ref, + int const_arg: @const_arg ref +); + +#keyset[id] +array_type_repr_element_type_reprs( + int id: @array_type_repr ref, + int element_type_repr: @type_repr ref +); + +asm_clobber_abis( + unique int id: @asm_clobber_abi +); + +asm_consts( + unique int id: @asm_const +); + +#keyset[id] +asm_const_exprs( + int id: @asm_const ref, + int expr: @expr ref +); + +#keyset[id] +asm_const_is_const( + int id: @asm_const ref +); + +asm_labels( + unique int id: @asm_label +); + +#keyset[id] +asm_label_block_exprs( + int id: @asm_label ref, + int block_expr: @block_expr ref +); + +asm_operand_nameds( + unique int id: @asm_operand_named +); + +#keyset[id] +asm_operand_named_asm_operands( + int id: @asm_operand_named ref, + int asm_operand: @asm_operand ref +); + +#keyset[id] +asm_operand_named_names( + int id: @asm_operand_named ref, + int name: @name ref +); + +asm_options_lists( + unique int id: @asm_options_list +); + +#keyset[id, index] +asm_options_list_asm_options( + int id: @asm_options_list ref, + int index: int ref, + int asm_option: @asm_option ref +); + +asm_reg_operands( + unique int id: @asm_reg_operand +); + +#keyset[id] +asm_reg_operand_asm_dir_specs( + int id: @asm_reg_operand ref, + int asm_dir_spec: @asm_dir_spec ref +); + +#keyset[id] +asm_reg_operand_asm_operand_exprs( + int id: @asm_reg_operand ref, + int asm_operand_expr: @asm_operand_expr ref +); + +#keyset[id] +asm_reg_operand_asm_reg_specs( + int id: @asm_reg_operand ref, + int asm_reg_spec: @asm_reg_spec ref +); + +asm_syms( + unique int id: @asm_sym +); + +#keyset[id] +asm_sym_paths( + int id: @asm_sym ref, + int path: @path ref +); + +assoc_type_args( + unique int id: @assoc_type_arg +); + +#keyset[id] +assoc_type_arg_const_args( + int id: @assoc_type_arg ref, + int const_arg: @const_arg ref +); + +#keyset[id] +assoc_type_arg_generic_arg_lists( + int id: @assoc_type_arg ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +assoc_type_arg_identifiers( + int id: @assoc_type_arg ref, + int identifier: @name_ref ref +); + +#keyset[id] +assoc_type_arg_param_lists( + int id: @assoc_type_arg ref, + int param_list: @param_list ref +); + +#keyset[id] +assoc_type_arg_ret_types( + int id: @assoc_type_arg ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +assoc_type_arg_return_type_syntaxes( + int id: @assoc_type_arg ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +assoc_type_arg_type_reprs( + int id: @assoc_type_arg ref, + int type_repr: @type_repr ref +); + +#keyset[id] +assoc_type_arg_type_bound_lists( + int id: @assoc_type_arg ref, + int type_bound_list: @type_bound_list ref +); + +await_exprs( + unique int id: @await_expr +); + +#keyset[id, index] +await_expr_attrs( + int id: @await_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +await_expr_exprs( + int id: @await_expr ref, + int expr: @expr ref +); + +become_exprs( + unique int id: @become_expr +); + +#keyset[id, index] +become_expr_attrs( + int id: @become_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +become_expr_exprs( + int id: @become_expr ref, + int expr: @expr ref +); + +binary_exprs( + unique int id: @binary_expr +); + +#keyset[id, index] +binary_expr_attrs( + int id: @binary_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +binary_expr_lhs( + int id: @binary_expr ref, + int lhs: @expr ref +); + +#keyset[id] +binary_expr_operator_names( + int id: @binary_expr ref, + string operator_name: string ref +); + +#keyset[id] +binary_expr_rhs( + int id: @binary_expr ref, + int rhs: @expr ref +); + +box_pats( + unique int id: @box_pat +); + +#keyset[id] +box_pat_pats( + int id: @box_pat ref, + int pat: @pat ref +); + +break_exprs( + unique int id: @break_expr +); + +#keyset[id, index] +break_expr_attrs( + int id: @break_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +break_expr_exprs( + int id: @break_expr ref, + int expr: @expr ref +); + +#keyset[id] +break_expr_lifetimes( + int id: @break_expr ref, + int lifetime: @lifetime ref +); + +call_exprs( + unique int id: @call_expr +); + +#keyset[id] +call_expr_arg_lists( + int id: @call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +call_expr_attrs( + int id: @call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +call_expr_functions( + int id: @call_expr ref, + int function: @expr ref +); + +cast_exprs( + unique int id: @cast_expr +); + +#keyset[id, index] +cast_expr_attrs( + int id: @cast_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +cast_expr_exprs( + int id: @cast_expr ref, + int expr: @expr ref +); + +#keyset[id] +cast_expr_type_reprs( + int id: @cast_expr ref, + int type_repr: @type_repr ref +); + +closure_exprs( + unique int id: @closure_expr +); + +#keyset[id] +closure_expr_closure_bodies( + int id: @closure_expr ref, + int closure_body: @expr ref +); + +#keyset[id] +closure_expr_for_binders( + int id: @closure_expr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +closure_expr_is_async( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_const( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_gen( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_move( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_static( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_ret_types( + int id: @closure_expr ref, + int ret_type: @ret_type_repr ref +); + +comments( + unique int id: @comment, + int parent: @ast_node ref, + string text: string ref +); + +const_args( + unique int id: @const_arg +); + +#keyset[id] +const_arg_exprs( + int id: @const_arg ref, + int expr: @expr ref +); + +const_block_pats( + unique int id: @const_block_pat +); + +#keyset[id] +const_block_pat_block_exprs( + int id: @const_block_pat ref, + int block_expr: @block_expr ref +); + +#keyset[id] +const_block_pat_is_const( + int id: @const_block_pat ref +); + +const_params( + unique int id: @const_param +); + +#keyset[id, index] +const_param_attrs( + int id: @const_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_param_default_vals( + int id: @const_param ref, + int default_val: @const_arg ref +); + +#keyset[id] +const_param_is_const( + int id: @const_param ref +); + +#keyset[id] +const_param_names( + int id: @const_param ref, + int name: @name ref +); + +#keyset[id] +const_param_type_reprs( + int id: @const_param ref, + int type_repr: @type_repr ref +); + +continue_exprs( + unique int id: @continue_expr +); + +#keyset[id, index] +continue_expr_attrs( + int id: @continue_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +continue_expr_lifetimes( + int id: @continue_expr ref, + int lifetime: @lifetime ref +); + +dyn_trait_type_reprs( + unique int id: @dyn_trait_type_repr +); + +#keyset[id] +dyn_trait_type_repr_type_bound_lists( + int id: @dyn_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +expr_stmts( + unique int id: @expr_stmt +); + +#keyset[id] +expr_stmt_exprs( + int id: @expr_stmt ref, + int expr: @expr ref +); + +field_exprs( + unique int id: @field_expr +); + +#keyset[id, index] +field_expr_attrs( + int id: @field_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +field_expr_containers( + int id: @field_expr ref, + int container: @expr ref +); + +#keyset[id] +field_expr_identifiers( + int id: @field_expr ref, + int identifier: @name_ref ref +); + +fn_ptr_type_reprs( + unique int id: @fn_ptr_type_repr +); + +#keyset[id] +fn_ptr_type_repr_abis( + int id: @fn_ptr_type_repr ref, + int abi: @abi ref +); + +#keyset[id] +fn_ptr_type_repr_is_async( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_const( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_unsafe( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_param_lists( + int id: @fn_ptr_type_repr ref, + int param_list: @param_list ref +); + +#keyset[id] +fn_ptr_type_repr_ret_types( + int id: @fn_ptr_type_repr ref, + int ret_type: @ret_type_repr ref +); + +for_type_reprs( + unique int id: @for_type_repr +); + +#keyset[id] +for_type_repr_for_binders( + int id: @for_type_repr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +for_type_repr_type_reprs( + int id: @for_type_repr ref, + int type_repr: @type_repr ref +); + +format_args_exprs( + unique int id: @format_args_expr +); + +#keyset[id, index] +format_args_expr_args( + int id: @format_args_expr ref, + int index: int ref, + int arg: @format_args_arg ref +); + +#keyset[id, index] +format_args_expr_attrs( + int id: @format_args_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +format_args_expr_templates( + int id: @format_args_expr ref, + int template: @expr ref +); + +ident_pats( + unique int id: @ident_pat +); + +#keyset[id, index] +ident_pat_attrs( + int id: @ident_pat ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ident_pat_is_mut( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_is_ref( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_names( + int id: @ident_pat ref, + int name: @name ref +); + +#keyset[id] +ident_pat_pats( + int id: @ident_pat ref, + int pat: @pat ref +); + +if_exprs( + unique int id: @if_expr +); + +#keyset[id, index] +if_expr_attrs( + int id: @if_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +if_expr_conditions( + int id: @if_expr ref, + int condition: @expr ref +); + +#keyset[id] +if_expr_elses( + int id: @if_expr ref, + int else: @expr ref +); + +#keyset[id] +if_expr_thens( + int id: @if_expr ref, + int then: @block_expr ref +); + +impl_trait_type_reprs( + unique int id: @impl_trait_type_repr +); + +#keyset[id] +impl_trait_type_repr_type_bound_lists( + int id: @impl_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +index_exprs( + unique int id: @index_expr +); + +#keyset[id, index] +index_expr_attrs( + int id: @index_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +index_expr_bases( + int id: @index_expr ref, + int base: @expr ref +); + +#keyset[id] +index_expr_indices( + int id: @index_expr ref, + int index: @expr ref +); + +infer_type_reprs( + unique int id: @infer_type_repr +); + +@item = + @asm_expr +| @assoc_item +| @extern_block +| @extern_crate +| @extern_item +| @impl +| @macro_def +| @macro_rules +| @module +| @trait +| @trait_alias +| @type_item +| @use +; + +#keyset[id] +item_attribute_macro_expansions( + int id: @item ref, + int attribute_macro_expansion: @macro_items ref +); + +@labelable_expr = + @block_expr +| @looping_expr +; + +#keyset[id] +labelable_expr_labels( + int id: @labelable_expr ref, + int label: @label ref +); + +let_exprs( + unique int id: @let_expr +); + +#keyset[id, index] +let_expr_attrs( + int id: @let_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_expr_scrutinees( + int id: @let_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +let_expr_pats( + int id: @let_expr ref, + int pat: @pat ref +); + +let_stmts( + unique int id: @let_stmt +); + +#keyset[id, index] +let_stmt_attrs( + int id: @let_stmt ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_stmt_initializers( + int id: @let_stmt ref, + int initializer: @expr ref +); + +#keyset[id] +let_stmt_let_elses( + int id: @let_stmt ref, + int let_else: @let_else ref +); + +#keyset[id] +let_stmt_pats( + int id: @let_stmt ref, + int pat: @pat ref +); + +#keyset[id] +let_stmt_type_reprs( + int id: @let_stmt ref, + int type_repr: @type_repr ref +); + +lifetimes( + unique int id: @lifetime +); + +#keyset[id] +lifetime_texts( + int id: @lifetime ref, + string text: string ref +); + +lifetime_args( + unique int id: @lifetime_arg +); + +#keyset[id] +lifetime_arg_lifetimes( + int id: @lifetime_arg ref, + int lifetime: @lifetime ref +); + +lifetime_params( + unique int id: @lifetime_param +); + +#keyset[id, index] +lifetime_param_attrs( + int id: @lifetime_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +lifetime_param_lifetimes( + int id: @lifetime_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +lifetime_param_type_bound_lists( + int id: @lifetime_param ref, + int type_bound_list: @type_bound_list ref +); + +literal_exprs( + unique int id: @literal_expr +); + +#keyset[id, index] +literal_expr_attrs( + int id: @literal_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +literal_expr_text_values( + int id: @literal_expr ref, + string text_value: string ref +); + +literal_pats( + unique int id: @literal_pat +); + +#keyset[id] +literal_pat_literals( + int id: @literal_pat ref, + int literal: @literal_expr ref +); + +macro_exprs( + unique int id: @macro_expr +); + +#keyset[id] +macro_expr_macro_calls( + int id: @macro_expr ref, + int macro_call: @macro_call ref +); + +macro_pats( + unique int id: @macro_pat +); + +#keyset[id] +macro_pat_macro_calls( + int id: @macro_pat ref, + int macro_call: @macro_call ref +); + +macro_type_reprs( + unique int id: @macro_type_repr +); + +#keyset[id] +macro_type_repr_macro_calls( + int id: @macro_type_repr ref, + int macro_call: @macro_call ref +); + +match_exprs( + unique int id: @match_expr +); + +#keyset[id, index] +match_expr_attrs( + int id: @match_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_expr_scrutinees( + int id: @match_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +match_expr_match_arm_lists( + int id: @match_expr ref, + int match_arm_list: @match_arm_list ref +); + +method_call_exprs( + unique int id: @method_call_expr +); + +#keyset[id] +method_call_expr_arg_lists( + int id: @method_call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +method_call_expr_attrs( + int id: @method_call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +method_call_expr_generic_arg_lists( + int id: @method_call_expr ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +method_call_expr_identifiers( + int id: @method_call_expr ref, + int identifier: @name_ref ref +); + +#keyset[id] +method_call_expr_receivers( + int id: @method_call_expr ref, + int receiver: @expr ref +); + +name_refs( + unique int id: @name_ref +); + +#keyset[id] +name_ref_texts( + int id: @name_ref ref, + string text: string ref +); + +never_type_reprs( + unique int id: @never_type_repr +); + +offset_of_exprs( + unique int id: @offset_of_expr +); + +#keyset[id, index] +offset_of_expr_attrs( + int id: @offset_of_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +offset_of_expr_fields( + int id: @offset_of_expr ref, + int index: int ref, + int field: @name_ref ref +); + +#keyset[id] +offset_of_expr_type_reprs( + int id: @offset_of_expr ref, + int type_repr: @type_repr ref +); + +or_pats( + unique int id: @or_pat +); + +#keyset[id, index] +or_pat_pats( + int id: @or_pat ref, + int index: int ref, + int pat: @pat ref +); + +params( + unique int id: @param +); + +#keyset[id] +param_pats( + int id: @param ref, + int pat: @pat ref +); + +paren_exprs( + unique int id: @paren_expr +); + +#keyset[id, index] +paren_expr_attrs( + int id: @paren_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +paren_expr_exprs( + int id: @paren_expr ref, + int expr: @expr ref +); + +paren_pats( + unique int id: @paren_pat +); + +#keyset[id] +paren_pat_pats( + int id: @paren_pat ref, + int pat: @pat ref +); + +paren_type_reprs( + unique int id: @paren_type_repr +); + +#keyset[id] +paren_type_repr_type_reprs( + int id: @paren_type_repr ref, + int type_repr: @type_repr ref +); + +@path_expr_base = + @path_expr +; + +path_pats( + unique int id: @path_pat +); + +path_type_reprs( + unique int id: @path_type_repr +); + +#keyset[id] +path_type_repr_paths( + int id: @path_type_repr ref, + int path: @path ref +); + +prefix_exprs( + unique int id: @prefix_expr +); + +#keyset[id, index] +prefix_expr_attrs( + int id: @prefix_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +prefix_expr_exprs( + int id: @prefix_expr ref, + int expr: @expr ref +); + +#keyset[id] +prefix_expr_operator_names( + int id: @prefix_expr ref, + string operator_name: string ref +); + +ptr_type_reprs( + unique int id: @ptr_type_repr +); + +#keyset[id] +ptr_type_repr_is_const( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_is_mut( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_type_reprs( + int id: @ptr_type_repr ref, + int type_repr: @type_repr ref +); + +range_exprs( + unique int id: @range_expr +); + +#keyset[id, index] +range_expr_attrs( + int id: @range_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +range_expr_ends( + int id: @range_expr ref, + int end: @expr ref +); + +#keyset[id] +range_expr_operator_names( + int id: @range_expr ref, + string operator_name: string ref +); + +#keyset[id] +range_expr_starts( + int id: @range_expr ref, + int start: @expr ref +); + +range_pats( + unique int id: @range_pat +); + +#keyset[id] +range_pat_ends( + int id: @range_pat ref, + int end: @pat ref +); + +#keyset[id] +range_pat_operator_names( + int id: @range_pat ref, + string operator_name: string ref +); + +#keyset[id] +range_pat_starts( + int id: @range_pat ref, + int start: @pat ref +); + +ref_exprs( + unique int id: @ref_expr +); + +#keyset[id, index] +ref_expr_attrs( + int id: @ref_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ref_expr_exprs( + int id: @ref_expr ref, + int expr: @expr ref +); + +#keyset[id] +ref_expr_is_const( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_mut( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_raw( + int id: @ref_expr ref +); + +ref_pats( + unique int id: @ref_pat +); + +#keyset[id] +ref_pat_is_mut( + int id: @ref_pat ref +); + +#keyset[id] +ref_pat_pats( + int id: @ref_pat ref, + int pat: @pat ref +); + +ref_type_reprs( + unique int id: @ref_type_repr +); + +#keyset[id] +ref_type_repr_is_mut( + int id: @ref_type_repr ref +); + +#keyset[id] +ref_type_repr_lifetimes( + int id: @ref_type_repr ref, + int lifetime: @lifetime ref +); + +#keyset[id] +ref_type_repr_type_reprs( + int id: @ref_type_repr ref, + int type_repr: @type_repr ref +); + +rest_pats( + unique int id: @rest_pat +); + +#keyset[id, index] +rest_pat_attrs( + int id: @rest_pat ref, + int index: int ref, + int attr: @attr ref +); + +return_exprs( + unique int id: @return_expr +); + +#keyset[id, index] +return_expr_attrs( + int id: @return_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +return_expr_exprs( + int id: @return_expr ref, + int expr: @expr ref +); + +self_params( + unique int id: @self_param +); + +#keyset[id] +self_param_is_ref( + int id: @self_param ref +); + +#keyset[id] +self_param_is_mut( + int id: @self_param ref +); + +#keyset[id] +self_param_lifetimes( + int id: @self_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +self_param_names( + int id: @self_param ref, + int name: @name ref +); + +slice_pats( + unique int id: @slice_pat +); + +#keyset[id, index] +slice_pat_pats( + int id: @slice_pat ref, + int index: int ref, + int pat: @pat ref +); + +slice_type_reprs( + unique int id: @slice_type_repr +); + +#keyset[id] +slice_type_repr_type_reprs( + int id: @slice_type_repr ref, + int type_repr: @type_repr ref +); + +struct_exprs( + unique int id: @struct_expr +); + +#keyset[id] +struct_expr_struct_expr_field_lists( + int id: @struct_expr ref, + int struct_expr_field_list: @struct_expr_field_list ref +); + +struct_field_lists( + unique int id: @struct_field_list +); + +#keyset[id, index] +struct_field_list_fields( + int id: @struct_field_list ref, + int index: int ref, + int field: @struct_field ref +); + +struct_pats( + unique int id: @struct_pat +); + +#keyset[id] +struct_pat_struct_pat_field_lists( + int id: @struct_pat ref, + int struct_pat_field_list: @struct_pat_field_list ref +); + +try_exprs( + unique int id: @try_expr +); + +#keyset[id, index] +try_expr_attrs( + int id: @try_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +try_expr_exprs( + int id: @try_expr ref, + int expr: @expr ref +); + +tuple_exprs( + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_attrs( + int id: @tuple_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +tuple_expr_fields( + int id: @tuple_expr ref, + int index: int ref, + int field: @expr ref +); + +tuple_field_lists( + unique int id: @tuple_field_list +); + +#keyset[id, index] +tuple_field_list_fields( + int id: @tuple_field_list ref, + int index: int ref, + int field: @tuple_field ref +); + +tuple_pats( + unique int id: @tuple_pat +); + +#keyset[id, index] +tuple_pat_fields( + int id: @tuple_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_struct_pats( + unique int id: @tuple_struct_pat +); + +#keyset[id, index] +tuple_struct_pat_fields( + int id: @tuple_struct_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_type_reprs( + unique int id: @tuple_type_repr +); + +#keyset[id, index] +tuple_type_repr_fields( + int id: @tuple_type_repr ref, + int index: int ref, + int field: @type_repr ref +); + +type_args( + unique int id: @type_arg +); + +#keyset[id] +type_arg_type_reprs( + int id: @type_arg ref, + int type_repr: @type_repr ref +); + +type_params( + unique int id: @type_param +); + +#keyset[id, index] +type_param_attrs( + int id: @type_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_param_default_types( + int id: @type_param ref, + int default_type: @type_repr ref +); + +#keyset[id] +type_param_names( + int id: @type_param ref, + int name: @name ref +); + +#keyset[id] +type_param_type_bound_lists( + int id: @type_param ref, + int type_bound_list: @type_bound_list ref +); + +underscore_exprs( + unique int id: @underscore_expr +); + +#keyset[id, index] +underscore_expr_attrs( + int id: @underscore_expr ref, + int index: int ref, + int attr: @attr ref +); + +variants( + unique int id: @variant +); + +#keyset[id, index] +variant_attrs( + int id: @variant ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +variant_discriminants( + int id: @variant ref, + int discriminant: @expr ref +); + +#keyset[id] +variant_field_lists( + int id: @variant ref, + int field_list: @field_list ref +); + +#keyset[id] +variant_names( + int id: @variant ref, + int name: @name ref +); + +#keyset[id] +variant_visibilities( + int id: @variant ref, + int visibility: @visibility ref +); + +wildcard_pats( + unique int id: @wildcard_pat +); + +yeet_exprs( + unique int id: @yeet_expr +); + +#keyset[id, index] +yeet_expr_attrs( + int id: @yeet_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yeet_expr_exprs( + int id: @yeet_expr ref, + int expr: @expr ref +); + +yield_exprs( + unique int id: @yield_expr +); + +#keyset[id, index] +yield_expr_attrs( + int id: @yield_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yield_expr_exprs( + int id: @yield_expr ref, + int expr: @expr ref +); + +asm_exprs( + unique int id: @asm_expr +); + +#keyset[id, index] +asm_expr_asm_pieces( + int id: @asm_expr ref, + int index: int ref, + int asm_piece: @asm_piece ref +); + +#keyset[id, index] +asm_expr_attrs( + int id: @asm_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +asm_expr_templates( + int id: @asm_expr ref, + int index: int ref, + int template: @expr ref +); + +@assoc_item = + @const +| @function +| @macro_call +| @type_alias +; + +block_exprs( + unique int id: @block_expr +); + +#keyset[id, index] +block_expr_attrs( + int id: @block_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +block_expr_is_async( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_const( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_gen( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_move( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_try( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_unsafe( + int id: @block_expr ref +); + +#keyset[id] +block_expr_stmt_lists( + int id: @block_expr ref, + int stmt_list: @stmt_list ref +); + +extern_blocks( + unique int id: @extern_block +); + +#keyset[id] +extern_block_abis( + int id: @extern_block ref, + int abi: @abi ref +); + +#keyset[id, index] +extern_block_attrs( + int id: @extern_block ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_block_extern_item_lists( + int id: @extern_block ref, + int extern_item_list: @extern_item_list ref +); + +#keyset[id] +extern_block_is_unsafe( + int id: @extern_block ref +); + +extern_crates( + unique int id: @extern_crate +); + +#keyset[id, index] +extern_crate_attrs( + int id: @extern_crate ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_crate_identifiers( + int id: @extern_crate ref, + int identifier: @name_ref ref +); + +#keyset[id] +extern_crate_renames( + int id: @extern_crate ref, + int rename: @rename ref +); + +#keyset[id] +extern_crate_visibilities( + int id: @extern_crate ref, + int visibility: @visibility ref +); + +@extern_item = + @function +| @macro_call +| @static +| @type_alias +; + +impls( + unique int id: @impl +); + +#keyset[id] +impl_assoc_item_lists( + int id: @impl ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +impl_attrs( + int id: @impl ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +impl_generic_param_lists( + int id: @impl ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +impl_is_const( + int id: @impl ref +); + +#keyset[id] +impl_is_default( + int id: @impl ref +); + +#keyset[id] +impl_is_unsafe( + int id: @impl ref +); + +#keyset[id] +impl_self_ties( + int id: @impl ref, + int self_ty: @type_repr ref +); + +#keyset[id] +impl_traits( + int id: @impl ref, + int trait: @type_repr ref +); + +#keyset[id] +impl_visibilities( + int id: @impl ref, + int visibility: @visibility ref +); + +#keyset[id] +impl_where_clauses( + int id: @impl ref, + int where_clause: @where_clause ref +); + +@looping_expr = + @for_expr +| @loop_expr +| @while_expr +; + +#keyset[id] +looping_expr_loop_bodies( + int id: @looping_expr ref, + int loop_body: @block_expr ref +); + +macro_defs( + unique int id: @macro_def +); + +#keyset[id] +macro_def_args( + int id: @macro_def ref, + int args: @token_tree ref +); + +#keyset[id, index] +macro_def_attrs( + int id: @macro_def ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_def_bodies( + int id: @macro_def ref, + int body: @token_tree ref +); + +#keyset[id] +macro_def_names( + int id: @macro_def ref, + int name: @name ref +); + +#keyset[id] +macro_def_visibilities( + int id: @macro_def ref, + int visibility: @visibility ref +); + +macro_rules( + unique int id: @macro_rules +); + +#keyset[id, index] +macro_rules_attrs( + int id: @macro_rules ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_rules_names( + int id: @macro_rules ref, + int name: @name ref +); + +#keyset[id] +macro_rules_token_trees( + int id: @macro_rules ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_rules_visibilities( + int id: @macro_rules ref, + int visibility: @visibility ref +); + +modules( + unique int id: @module +); + +#keyset[id, index] +module_attrs( + int id: @module ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +module_item_lists( + int id: @module ref, + int item_list: @item_list ref +); + +#keyset[id] +module_names( + int id: @module ref, + int name: @name ref +); + +#keyset[id] +module_visibilities( + int id: @module ref, + int visibility: @visibility ref +); + +path_exprs( + unique int id: @path_expr +); + +#keyset[id, index] +path_expr_attrs( + int id: @path_expr ref, + int index: int ref, + int attr: @attr ref +); + +traits( + unique int id: @trait +); + +#keyset[id] +trait_assoc_item_lists( + int id: @trait ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +trait_attrs( + int id: @trait ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_generic_param_lists( + int id: @trait ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_is_auto( + int id: @trait ref +); + +#keyset[id] +trait_is_unsafe( + int id: @trait ref +); + +#keyset[id] +trait_names( + int id: @trait ref, + int name: @name ref +); + +#keyset[id] +trait_type_bound_lists( + int id: @trait ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_visibilities( + int id: @trait ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_where_clauses( + int id: @trait ref, + int where_clause: @where_clause ref +); + +trait_aliases( + unique int id: @trait_alias +); + +#keyset[id, index] +trait_alias_attrs( + int id: @trait_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_alias_generic_param_lists( + int id: @trait_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_alias_names( + int id: @trait_alias ref, + int name: @name ref +); + +#keyset[id] +trait_alias_type_bound_lists( + int id: @trait_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_alias_visibilities( + int id: @trait_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_alias_where_clauses( + int id: @trait_alias ref, + int where_clause: @where_clause ref +); + +@type_item = + @enum +| @struct +| @union +; + +#keyset[id, index] +type_item_derive_macro_expansions( + int id: @type_item ref, + int index: int ref, + int derive_macro_expansion: @macro_items ref +); + +#keyset[id, index] +type_item_attrs( + int id: @type_item ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_item_generic_param_lists( + int id: @type_item ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_item_names( + int id: @type_item ref, + int name: @name ref +); + +#keyset[id] +type_item_visibilities( + int id: @type_item ref, + int visibility: @visibility ref +); + +#keyset[id] +type_item_where_clauses( + int id: @type_item ref, + int where_clause: @where_clause ref +); + +uses( + unique int id: @use +); + +#keyset[id, index] +use_attrs( + int id: @use ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +use_use_trees( + int id: @use ref, + int use_tree: @use_tree ref +); + +#keyset[id] +use_visibilities( + int id: @use ref, + int visibility: @visibility ref +); + +consts( + unique int id: @const +); + +#keyset[id, index] +const_attrs( + int id: @const ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_bodies( + int id: @const ref, + int body: @expr ref +); + +#keyset[id] +const_generic_param_lists( + int id: @const ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +const_is_const( + int id: @const ref +); + +#keyset[id] +const_is_default( + int id: @const ref +); + +#keyset[id] +const_names( + int id: @const ref, + int name: @name ref +); + +#keyset[id] +const_type_reprs( + int id: @const ref, + int type_repr: @type_repr ref +); + +#keyset[id] +const_visibilities( + int id: @const ref, + int visibility: @visibility ref +); + +#keyset[id] +const_where_clauses( + int id: @const ref, + int where_clause: @where_clause ref +); + +#keyset[id] +const_has_implementation( + int id: @const ref +); + +enums( + unique int id: @enum +); + +#keyset[id] +enum_variant_lists( + int id: @enum ref, + int variant_list: @variant_list ref +); + +for_exprs( + unique int id: @for_expr +); + +#keyset[id, index] +for_expr_attrs( + int id: @for_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +for_expr_iterables( + int id: @for_expr ref, + int iterable: @expr ref +); + +#keyset[id] +for_expr_pats( + int id: @for_expr ref, + int pat: @pat ref +); + +functions( + unique int id: @function +); + +#keyset[id] +function_abis( + int id: @function ref, + int abi: @abi ref +); + +#keyset[id] +function_function_bodies( + int id: @function ref, + int function_body: @block_expr ref +); + +#keyset[id] +function_generic_param_lists( + int id: @function ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +function_is_async( + int id: @function ref +); + +#keyset[id] +function_is_const( + int id: @function ref +); + +#keyset[id] +function_is_default( + int id: @function ref +); + +#keyset[id] +function_is_gen( + int id: @function ref +); + +#keyset[id] +function_is_unsafe( + int id: @function ref +); + +#keyset[id] +function_names( + int id: @function ref, + int name: @name ref +); + +#keyset[id] +function_ret_types( + int id: @function ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +function_visibilities( + int id: @function ref, + int visibility: @visibility ref +); + +#keyset[id] +function_where_clauses( + int id: @function ref, + int where_clause: @where_clause ref +); + +#keyset[id] +function_has_implementation( + int id: @function ref +); + +loop_exprs( + unique int id: @loop_expr +); + +#keyset[id, index] +loop_expr_attrs( + int id: @loop_expr ref, + int index: int ref, + int attr: @attr ref +); + +macro_calls( + unique int id: @macro_call +); + +#keyset[id, index] +macro_call_attrs( + int id: @macro_call ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_call_paths( + int id: @macro_call ref, + int path: @path ref +); + +#keyset[id] +macro_call_token_trees( + int id: @macro_call ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_call_macro_call_expansions( + int id: @macro_call ref, + int macro_call_expansion: @ast_node ref +); + +statics( + unique int id: @static +); + +#keyset[id, index] +static_attrs( + int id: @static ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +static_bodies( + int id: @static ref, + int body: @expr ref +); + +#keyset[id] +static_is_mut( + int id: @static ref +); + +#keyset[id] +static_is_static( + int id: @static ref +); + +#keyset[id] +static_is_unsafe( + int id: @static ref +); + +#keyset[id] +static_names( + int id: @static ref, + int name: @name ref +); + +#keyset[id] +static_type_reprs( + int id: @static ref, + int type_repr: @type_repr ref +); + +#keyset[id] +static_visibilities( + int id: @static ref, + int visibility: @visibility ref +); + +structs( + unique int id: @struct +); + +#keyset[id] +struct_field_lists_( + int id: @struct ref, + int field_list: @field_list ref +); + +type_aliases( + unique int id: @type_alias +); + +#keyset[id, index] +type_alias_attrs( + int id: @type_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_alias_generic_param_lists( + int id: @type_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_alias_is_default( + int id: @type_alias ref +); + +#keyset[id] +type_alias_names( + int id: @type_alias ref, + int name: @name ref +); + +#keyset[id] +type_alias_type_reprs( + int id: @type_alias ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_alias_type_bound_lists( + int id: @type_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +type_alias_visibilities( + int id: @type_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +type_alias_where_clauses( + int id: @type_alias ref, + int where_clause: @where_clause ref +); + +unions( + unique int id: @union +); + +#keyset[id] +union_struct_field_lists( + int id: @union ref, + int struct_field_list: @struct_field_list ref +); + +while_exprs( + unique int id: @while_expr +); + +#keyset[id, index] +while_expr_attrs( + int id: @while_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +while_expr_conditions( + int id: @while_expr ref, + int condition: @expr ref +); diff --git a/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/rust.dbscheme b/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/rust.dbscheme new file mode 100644 index 00000000000..77e9a70be4b --- /dev/null +++ b/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/rust.dbscheme @@ -0,0 +1,3556 @@ +// generated by codegen, do not edit + +// from ../shared/tree-sitter-extractor/src/generator/prefix.dbscheme +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ + +/** + * The CLI will automatically emit applicable tuples for this table, + * such as `databaseMetadata("isOverlay", "true")` when building an + * overlay database. + */ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Overlay support -*/ + +/** + * The CLI will automatically emit tuples for each new/modified/deleted file + * when building an overlay database. + */ +overlayChangedFiles( + string path: string ref +); + + +// from prefix.dbscheme +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_default ref +); + + +// from schema + +@element = + @extractor_step +| @locatable +| @named_crate +| @unextracted +; + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int duration_ms: int ref +); + +#keyset[id] +extractor_step_files( + int id: @extractor_step ref, + int file: @file ref +); + +@locatable = + @ast_node +| @crate +; + +named_crates( + unique int id: @named_crate, + string name: string ref, + int crate: @crate ref +); + +@unextracted = + @missing +| @unimplemented +; + +@ast_node = + @abi +| @addressable +| @arg_list +| @asm_dir_spec +| @asm_operand +| @asm_operand_expr +| @asm_option +| @asm_piece +| @asm_reg_spec +| @assoc_item_list +| @attr +| @callable +| @expr +| @extern_item_list +| @field_list +| @for_binder +| @format_args_arg +| @generic_arg +| @generic_arg_list +| @generic_param +| @generic_param_list +| @item_list +| @label +| @let_else +| @macro_items +| @match_arm +| @match_arm_list +| @match_guard +| @meta +| @name +| @param_base +| @param_list +| @parenthesized_arg_list +| @pat +| @path +| @path_ast_node +| @path_segment +| @rename +| @ret_type_repr +| @return_type_syntax +| @source_file +| @stmt +| @stmt_list +| @struct_expr_field +| @struct_expr_field_list +| @struct_field +| @struct_pat_field +| @struct_pat_field_list +| @token +| @token_tree +| @tuple_field +| @type_bound +| @type_bound_list +| @type_repr +| @use_bound_generic_arg +| @use_bound_generic_args +| @use_tree +| @use_tree_list +| @variant_list +| @visibility +| @where_clause +| @where_pred +; + +crates( + unique int id: @crate +); + +#keyset[id] +crate_names( + int id: @crate ref, + string name: string ref +); + +#keyset[id] +crate_versions( + int id: @crate ref, + string version: string ref +); + +#keyset[id, index] +crate_cfg_options( + int id: @crate ref, + int index: int ref, + string cfg_option: string ref +); + +#keyset[id, index] +crate_named_dependencies( + int id: @crate ref, + int index: int ref, + int named_dependency: @named_crate ref +); + +missings( + unique int id: @missing +); + +unimplementeds( + unique int id: @unimplemented +); + +abis( + unique int id: @abi +); + +#keyset[id] +abi_abi_strings( + int id: @abi ref, + string abi_string: string ref +); + +@addressable = + @item +| @variant +; + +arg_lists( + unique int id: @arg_list +); + +#keyset[id, index] +arg_list_args( + int id: @arg_list ref, + int index: int ref, + int arg: @expr ref +); + +asm_dir_specs( + unique int id: @asm_dir_spec +); + +@asm_operand = + @asm_const +| @asm_label +| @asm_reg_operand +| @asm_sym +; + +asm_operand_exprs( + unique int id: @asm_operand_expr +); + +#keyset[id] +asm_operand_expr_in_exprs( + int id: @asm_operand_expr ref, + int in_expr: @expr ref +); + +#keyset[id] +asm_operand_expr_out_exprs( + int id: @asm_operand_expr ref, + int out_expr: @expr ref +); + +asm_options( + unique int id: @asm_option +); + +#keyset[id] +asm_option_is_raw( + int id: @asm_option ref +); + +@asm_piece = + @asm_clobber_abi +| @asm_operand_named +| @asm_options_list +; + +asm_reg_specs( + unique int id: @asm_reg_spec +); + +#keyset[id] +asm_reg_spec_identifiers( + int id: @asm_reg_spec ref, + int identifier: @name_ref ref +); + +assoc_item_lists( + unique int id: @assoc_item_list +); + +#keyset[id, index] +assoc_item_list_assoc_items( + int id: @assoc_item_list ref, + int index: int ref, + int assoc_item: @assoc_item ref +); + +#keyset[id, index] +assoc_item_list_attrs( + int id: @assoc_item_list ref, + int index: int ref, + int attr: @attr ref +); + +attrs( + unique int id: @attr +); + +#keyset[id] +attr_meta( + int id: @attr ref, + int meta: @meta ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_param_lists( + int id: @callable ref, + int param_list: @param_list ref +); + +#keyset[id, index] +callable_attrs( + int id: @callable ref, + int index: int ref, + int attr: @attr ref +); + +@expr = + @array_expr_internal +| @asm_expr +| @await_expr +| @become_expr +| @binary_expr +| @break_expr +| @call_expr +| @cast_expr +| @closure_expr +| @continue_expr +| @field_expr +| @format_args_expr +| @if_expr +| @index_expr +| @labelable_expr +| @let_expr +| @literal_expr +| @macro_expr +| @match_expr +| @method_call_expr +| @offset_of_expr +| @paren_expr +| @path_expr_base +| @prefix_expr +| @range_expr +| @ref_expr +| @return_expr +| @struct_expr +| @try_expr +| @tuple_expr +| @underscore_expr +| @yeet_expr +| @yield_expr +; + +extern_item_lists( + unique int id: @extern_item_list +); + +#keyset[id, index] +extern_item_list_attrs( + int id: @extern_item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +extern_item_list_extern_items( + int id: @extern_item_list ref, + int index: int ref, + int extern_item: @extern_item ref +); + +@field_list = + @struct_field_list +| @tuple_field_list +; + +for_binders( + unique int id: @for_binder +); + +#keyset[id] +for_binder_generic_param_lists( + int id: @for_binder ref, + int generic_param_list: @generic_param_list ref +); + +format_args_args( + unique int id: @format_args_arg +); + +#keyset[id] +format_args_arg_exprs( + int id: @format_args_arg ref, + int expr: @expr ref +); + +#keyset[id] +format_args_arg_names( + int id: @format_args_arg ref, + int name: @name ref +); + +@generic_arg = + @assoc_type_arg +| @const_arg +| @lifetime_arg +| @type_arg +; + +generic_arg_lists( + unique int id: @generic_arg_list +); + +#keyset[id, index] +generic_arg_list_generic_args( + int id: @generic_arg_list ref, + int index: int ref, + int generic_arg: @generic_arg ref +); + +@generic_param = + @const_param +| @lifetime_param +| @type_param +; + +generic_param_lists( + unique int id: @generic_param_list +); + +#keyset[id, index] +generic_param_list_generic_params( + int id: @generic_param_list ref, + int index: int ref, + int generic_param: @generic_param ref +); + +item_lists( + unique int id: @item_list +); + +#keyset[id, index] +item_list_attrs( + int id: @item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +item_list_items( + int id: @item_list ref, + int index: int ref, + int item: @item ref +); + +labels( + unique int id: @label +); + +#keyset[id] +label_lifetimes( + int id: @label ref, + int lifetime: @lifetime ref +); + +let_elses( + unique int id: @let_else +); + +#keyset[id] +let_else_block_exprs( + int id: @let_else ref, + int block_expr: @block_expr ref +); + +macro_items( + unique int id: @macro_items +); + +#keyset[id, index] +macro_items_items( + int id: @macro_items ref, + int index: int ref, + int item: @item ref +); + +match_arms( + unique int id: @match_arm +); + +#keyset[id, index] +match_arm_attrs( + int id: @match_arm ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_arm_exprs( + int id: @match_arm ref, + int expr: @expr ref +); + +#keyset[id] +match_arm_guards( + int id: @match_arm ref, + int guard: @match_guard ref +); + +#keyset[id] +match_arm_pats( + int id: @match_arm ref, + int pat: @pat ref +); + +match_arm_lists( + unique int id: @match_arm_list +); + +#keyset[id, index] +match_arm_list_arms( + int id: @match_arm_list ref, + int index: int ref, + int arm: @match_arm ref +); + +#keyset[id, index] +match_arm_list_attrs( + int id: @match_arm_list ref, + int index: int ref, + int attr: @attr ref +); + +match_guards( + unique int id: @match_guard +); + +#keyset[id] +match_guard_conditions( + int id: @match_guard ref, + int condition: @expr ref +); + +meta( + unique int id: @meta +); + +#keyset[id] +meta_exprs( + int id: @meta ref, + int expr: @expr ref +); + +#keyset[id] +meta_is_unsafe( + int id: @meta ref +); + +#keyset[id] +meta_paths( + int id: @meta ref, + int path: @path ref +); + +#keyset[id] +meta_token_trees( + int id: @meta ref, + int token_tree: @token_tree ref +); + +names( + unique int id: @name +); + +#keyset[id] +name_texts( + int id: @name ref, + string text: string ref +); + +@param_base = + @param +| @self_param +; + +#keyset[id, index] +param_base_attrs( + int id: @param_base ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +param_base_type_reprs( + int id: @param_base ref, + int type_repr: @type_repr ref +); + +param_lists( + unique int id: @param_list +); + +#keyset[id, index] +param_list_params( + int id: @param_list ref, + int index: int ref, + int param: @param ref +); + +#keyset[id] +param_list_self_params( + int id: @param_list ref, + int self_param: @self_param ref +); + +parenthesized_arg_lists( + unique int id: @parenthesized_arg_list +); + +#keyset[id, index] +parenthesized_arg_list_type_args( + int id: @parenthesized_arg_list ref, + int index: int ref, + int type_arg: @type_arg ref +); + +@pat = + @box_pat +| @const_block_pat +| @ident_pat +| @literal_pat +| @macro_pat +| @or_pat +| @paren_pat +| @path_pat +| @range_pat +| @ref_pat +| @rest_pat +| @slice_pat +| @struct_pat +| @tuple_pat +| @tuple_struct_pat +| @wildcard_pat +; + +paths( + unique int id: @path +); + +#keyset[id] +path_qualifiers( + int id: @path ref, + int qualifier: @path ref +); + +#keyset[id] +path_segments_( + int id: @path ref, + int segment: @path_segment ref +); + +@path_ast_node = + @path_expr +| @path_pat +| @struct_expr +| @struct_pat +| @tuple_struct_pat +; + +#keyset[id] +path_ast_node_paths( + int id: @path_ast_node ref, + int path: @path ref +); + +path_segments( + unique int id: @path_segment +); + +#keyset[id] +path_segment_generic_arg_lists( + int id: @path_segment ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +path_segment_identifiers( + int id: @path_segment ref, + int identifier: @name_ref ref +); + +#keyset[id] +path_segment_parenthesized_arg_lists( + int id: @path_segment ref, + int parenthesized_arg_list: @parenthesized_arg_list ref +); + +#keyset[id] +path_segment_ret_types( + int id: @path_segment ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +path_segment_return_type_syntaxes( + int id: @path_segment ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +path_segment_type_reprs( + int id: @path_segment ref, + int type_repr: @type_repr ref +); + +#keyset[id] +path_segment_trait_type_reprs( + int id: @path_segment ref, + int trait_type_repr: @path_type_repr ref +); + +renames( + unique int id: @rename +); + +#keyset[id] +rename_names( + int id: @rename ref, + int name: @name ref +); + +ret_type_reprs( + unique int id: @ret_type_repr +); + +#keyset[id] +ret_type_repr_type_reprs( + int id: @ret_type_repr ref, + int type_repr: @type_repr ref +); + +return_type_syntaxes( + unique int id: @return_type_syntax +); + +source_files( + unique int id: @source_file +); + +#keyset[id, index] +source_file_attrs( + int id: @source_file ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +source_file_items( + int id: @source_file ref, + int index: int ref, + int item: @item ref +); + +@stmt = + @expr_stmt +| @item +| @let_stmt +; + +stmt_lists( + unique int id: @stmt_list +); + +#keyset[id, index] +stmt_list_attrs( + int id: @stmt_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +stmt_list_statements( + int id: @stmt_list ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +stmt_list_tail_exprs( + int id: @stmt_list ref, + int tail_expr: @expr ref +); + +struct_expr_fields( + unique int id: @struct_expr_field +); + +#keyset[id, index] +struct_expr_field_attrs( + int id: @struct_expr_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_expr_field_exprs( + int id: @struct_expr_field ref, + int expr: @expr ref +); + +#keyset[id] +struct_expr_field_identifiers( + int id: @struct_expr_field ref, + int identifier: @name_ref ref +); + +struct_expr_field_lists( + unique int id: @struct_expr_field_list +); + +#keyset[id, index] +struct_expr_field_list_attrs( + int id: @struct_expr_field_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +struct_expr_field_list_fields( + int id: @struct_expr_field_list ref, + int index: int ref, + int field: @struct_expr_field ref +); + +#keyset[id] +struct_expr_field_list_spreads( + int id: @struct_expr_field_list ref, + int spread: @expr ref +); + +struct_fields( + unique int id: @struct_field +); + +#keyset[id, index] +struct_field_attrs( + int id: @struct_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_defaults( + int id: @struct_field ref, + int default: @expr ref +); + +#keyset[id] +struct_field_is_unsafe( + int id: @struct_field ref +); + +#keyset[id] +struct_field_names( + int id: @struct_field ref, + int name: @name ref +); + +#keyset[id] +struct_field_type_reprs( + int id: @struct_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +struct_field_visibilities( + int id: @struct_field ref, + int visibility: @visibility ref +); + +struct_pat_fields( + unique int id: @struct_pat_field +); + +#keyset[id, index] +struct_pat_field_attrs( + int id: @struct_pat_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_pat_field_identifiers( + int id: @struct_pat_field ref, + int identifier: @name_ref ref +); + +#keyset[id] +struct_pat_field_pats( + int id: @struct_pat_field ref, + int pat: @pat ref +); + +struct_pat_field_lists( + unique int id: @struct_pat_field_list +); + +#keyset[id, index] +struct_pat_field_list_fields( + int id: @struct_pat_field_list ref, + int index: int ref, + int field: @struct_pat_field ref +); + +#keyset[id] +struct_pat_field_list_rest_pats( + int id: @struct_pat_field_list ref, + int rest_pat: @rest_pat ref +); + +@token = + @comment +; + +token_trees( + unique int id: @token_tree +); + +tuple_fields( + unique int id: @tuple_field +); + +#keyset[id, index] +tuple_field_attrs( + int id: @tuple_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +tuple_field_type_reprs( + int id: @tuple_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +tuple_field_visibilities( + int id: @tuple_field ref, + int visibility: @visibility ref +); + +type_bounds( + unique int id: @type_bound +); + +#keyset[id] +type_bound_for_binders( + int id: @type_bound ref, + int for_binder: @for_binder ref +); + +#keyset[id] +type_bound_is_async( + int id: @type_bound ref +); + +#keyset[id] +type_bound_is_const( + int id: @type_bound ref +); + +#keyset[id] +type_bound_lifetimes( + int id: @type_bound ref, + int lifetime: @lifetime ref +); + +#keyset[id] +type_bound_type_reprs( + int id: @type_bound ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_bound_use_bound_generic_args( + int id: @type_bound ref, + int use_bound_generic_args: @use_bound_generic_args ref +); + +type_bound_lists( + unique int id: @type_bound_list +); + +#keyset[id, index] +type_bound_list_bounds( + int id: @type_bound_list ref, + int index: int ref, + int bound: @type_bound ref +); + +@type_repr = + @array_type_repr +| @dyn_trait_type_repr +| @fn_ptr_type_repr +| @for_type_repr +| @impl_trait_type_repr +| @infer_type_repr +| @macro_type_repr +| @never_type_repr +| @paren_type_repr +| @path_type_repr +| @ptr_type_repr +| @ref_type_repr +| @slice_type_repr +| @tuple_type_repr +; + +@use_bound_generic_arg = + @lifetime +| @name_ref +; + +use_bound_generic_args( + unique int id: @use_bound_generic_args +); + +#keyset[id, index] +use_bound_generic_args_use_bound_generic_args( + int id: @use_bound_generic_args ref, + int index: int ref, + int use_bound_generic_arg: @use_bound_generic_arg ref +); + +use_trees( + unique int id: @use_tree +); + +#keyset[id] +use_tree_is_glob( + int id: @use_tree ref +); + +#keyset[id] +use_tree_paths( + int id: @use_tree ref, + int path: @path ref +); + +#keyset[id] +use_tree_renames( + int id: @use_tree ref, + int rename: @rename ref +); + +#keyset[id] +use_tree_use_tree_lists( + int id: @use_tree ref, + int use_tree_list: @use_tree_list ref +); + +use_tree_lists( + unique int id: @use_tree_list +); + +#keyset[id, index] +use_tree_list_use_trees( + int id: @use_tree_list ref, + int index: int ref, + int use_tree: @use_tree ref +); + +variant_lists( + unique int id: @variant_list +); + +#keyset[id, index] +variant_list_variants( + int id: @variant_list ref, + int index: int ref, + int variant: @variant ref +); + +visibilities( + unique int id: @visibility +); + +#keyset[id] +visibility_paths( + int id: @visibility ref, + int path: @path ref +); + +where_clauses( + unique int id: @where_clause +); + +#keyset[id, index] +where_clause_predicates( + int id: @where_clause ref, + int index: int ref, + int predicate: @where_pred ref +); + +where_preds( + unique int id: @where_pred +); + +#keyset[id] +where_pred_for_binders( + int id: @where_pred ref, + int for_binder: @for_binder ref +); + +#keyset[id] +where_pred_lifetimes( + int id: @where_pred ref, + int lifetime: @lifetime ref +); + +#keyset[id] +where_pred_type_reprs( + int id: @where_pred ref, + int type_repr: @type_repr ref +); + +#keyset[id] +where_pred_type_bound_lists( + int id: @where_pred ref, + int type_bound_list: @type_bound_list ref +); + +array_expr_internals( + unique int id: @array_expr_internal +); + +#keyset[id, index] +array_expr_internal_attrs( + int id: @array_expr_internal ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +array_expr_internal_exprs( + int id: @array_expr_internal ref, + int index: int ref, + int expr: @expr ref +); + +#keyset[id] +array_expr_internal_is_semicolon( + int id: @array_expr_internal ref +); + +array_type_reprs( + unique int id: @array_type_repr +); + +#keyset[id] +array_type_repr_const_args( + int id: @array_type_repr ref, + int const_arg: @const_arg ref +); + +#keyset[id] +array_type_repr_element_type_reprs( + int id: @array_type_repr ref, + int element_type_repr: @type_repr ref +); + +asm_clobber_abis( + unique int id: @asm_clobber_abi +); + +asm_consts( + unique int id: @asm_const +); + +#keyset[id] +asm_const_exprs( + int id: @asm_const ref, + int expr: @expr ref +); + +#keyset[id] +asm_const_is_const( + int id: @asm_const ref +); + +asm_labels( + unique int id: @asm_label +); + +#keyset[id] +asm_label_block_exprs( + int id: @asm_label ref, + int block_expr: @block_expr ref +); + +asm_operand_nameds( + unique int id: @asm_operand_named +); + +#keyset[id] +asm_operand_named_asm_operands( + int id: @asm_operand_named ref, + int asm_operand: @asm_operand ref +); + +#keyset[id] +asm_operand_named_names( + int id: @asm_operand_named ref, + int name: @name ref +); + +asm_options_lists( + unique int id: @asm_options_list +); + +#keyset[id, index] +asm_options_list_asm_options( + int id: @asm_options_list ref, + int index: int ref, + int asm_option: @asm_option ref +); + +asm_reg_operands( + unique int id: @asm_reg_operand +); + +#keyset[id] +asm_reg_operand_asm_dir_specs( + int id: @asm_reg_operand ref, + int asm_dir_spec: @asm_dir_spec ref +); + +#keyset[id] +asm_reg_operand_asm_operand_exprs( + int id: @asm_reg_operand ref, + int asm_operand_expr: @asm_operand_expr ref +); + +#keyset[id] +asm_reg_operand_asm_reg_specs( + int id: @asm_reg_operand ref, + int asm_reg_spec: @asm_reg_spec ref +); + +asm_syms( + unique int id: @asm_sym +); + +#keyset[id] +asm_sym_paths( + int id: @asm_sym ref, + int path: @path ref +); + +assoc_type_args( + unique int id: @assoc_type_arg +); + +#keyset[id] +assoc_type_arg_const_args( + int id: @assoc_type_arg ref, + int const_arg: @const_arg ref +); + +#keyset[id] +assoc_type_arg_generic_arg_lists( + int id: @assoc_type_arg ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +assoc_type_arg_identifiers( + int id: @assoc_type_arg ref, + int identifier: @name_ref ref +); + +#keyset[id] +assoc_type_arg_param_lists( + int id: @assoc_type_arg ref, + int param_list: @param_list ref +); + +#keyset[id] +assoc_type_arg_ret_types( + int id: @assoc_type_arg ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +assoc_type_arg_return_type_syntaxes( + int id: @assoc_type_arg ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +assoc_type_arg_type_reprs( + int id: @assoc_type_arg ref, + int type_repr: @type_repr ref +); + +#keyset[id] +assoc_type_arg_type_bound_lists( + int id: @assoc_type_arg ref, + int type_bound_list: @type_bound_list ref +); + +await_exprs( + unique int id: @await_expr +); + +#keyset[id, index] +await_expr_attrs( + int id: @await_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +await_expr_exprs( + int id: @await_expr ref, + int expr: @expr ref +); + +become_exprs( + unique int id: @become_expr +); + +#keyset[id, index] +become_expr_attrs( + int id: @become_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +become_expr_exprs( + int id: @become_expr ref, + int expr: @expr ref +); + +binary_exprs( + unique int id: @binary_expr +); + +#keyset[id, index] +binary_expr_attrs( + int id: @binary_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +binary_expr_lhs( + int id: @binary_expr ref, + int lhs: @expr ref +); + +#keyset[id] +binary_expr_operator_names( + int id: @binary_expr ref, + string operator_name: string ref +); + +#keyset[id] +binary_expr_rhs( + int id: @binary_expr ref, + int rhs: @expr ref +); + +box_pats( + unique int id: @box_pat +); + +#keyset[id] +box_pat_pats( + int id: @box_pat ref, + int pat: @pat ref +); + +break_exprs( + unique int id: @break_expr +); + +#keyset[id, index] +break_expr_attrs( + int id: @break_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +break_expr_exprs( + int id: @break_expr ref, + int expr: @expr ref +); + +#keyset[id] +break_expr_lifetimes( + int id: @break_expr ref, + int lifetime: @lifetime ref +); + +call_exprs( + unique int id: @call_expr +); + +#keyset[id] +call_expr_arg_lists( + int id: @call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +call_expr_attrs( + int id: @call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +call_expr_functions( + int id: @call_expr ref, + int function: @expr ref +); + +cast_exprs( + unique int id: @cast_expr +); + +#keyset[id, index] +cast_expr_attrs( + int id: @cast_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +cast_expr_exprs( + int id: @cast_expr ref, + int expr: @expr ref +); + +#keyset[id] +cast_expr_type_reprs( + int id: @cast_expr ref, + int type_repr: @type_repr ref +); + +closure_exprs( + unique int id: @closure_expr +); + +#keyset[id] +closure_expr_closure_bodies( + int id: @closure_expr ref, + int closure_body: @expr ref +); + +#keyset[id] +closure_expr_for_binders( + int id: @closure_expr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +closure_expr_is_async( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_const( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_gen( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_move( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_static( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_ret_types( + int id: @closure_expr ref, + int ret_type: @ret_type_repr ref +); + +comments( + unique int id: @comment, + int parent: @ast_node ref, + string text: string ref +); + +const_args( + unique int id: @const_arg +); + +#keyset[id] +const_arg_exprs( + int id: @const_arg ref, + int expr: @expr ref +); + +const_block_pats( + unique int id: @const_block_pat +); + +#keyset[id] +const_block_pat_block_exprs( + int id: @const_block_pat ref, + int block_expr: @block_expr ref +); + +#keyset[id] +const_block_pat_is_const( + int id: @const_block_pat ref +); + +const_params( + unique int id: @const_param +); + +#keyset[id, index] +const_param_attrs( + int id: @const_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_param_default_vals( + int id: @const_param ref, + int default_val: @const_arg ref +); + +#keyset[id] +const_param_is_const( + int id: @const_param ref +); + +#keyset[id] +const_param_names( + int id: @const_param ref, + int name: @name ref +); + +#keyset[id] +const_param_type_reprs( + int id: @const_param ref, + int type_repr: @type_repr ref +); + +continue_exprs( + unique int id: @continue_expr +); + +#keyset[id, index] +continue_expr_attrs( + int id: @continue_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +continue_expr_lifetimes( + int id: @continue_expr ref, + int lifetime: @lifetime ref +); + +dyn_trait_type_reprs( + unique int id: @dyn_trait_type_repr +); + +#keyset[id] +dyn_trait_type_repr_type_bound_lists( + int id: @dyn_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +expr_stmts( + unique int id: @expr_stmt +); + +#keyset[id] +expr_stmt_exprs( + int id: @expr_stmt ref, + int expr: @expr ref +); + +field_exprs( + unique int id: @field_expr +); + +#keyset[id, index] +field_expr_attrs( + int id: @field_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +field_expr_containers( + int id: @field_expr ref, + int container: @expr ref +); + +#keyset[id] +field_expr_identifiers( + int id: @field_expr ref, + int identifier: @name_ref ref +); + +fn_ptr_type_reprs( + unique int id: @fn_ptr_type_repr +); + +#keyset[id] +fn_ptr_type_repr_abis( + int id: @fn_ptr_type_repr ref, + int abi: @abi ref +); + +#keyset[id] +fn_ptr_type_repr_is_async( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_const( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_unsafe( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_param_lists( + int id: @fn_ptr_type_repr ref, + int param_list: @param_list ref +); + +#keyset[id] +fn_ptr_type_repr_ret_types( + int id: @fn_ptr_type_repr ref, + int ret_type: @ret_type_repr ref +); + +for_type_reprs( + unique int id: @for_type_repr +); + +#keyset[id] +for_type_repr_for_binders( + int id: @for_type_repr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +for_type_repr_type_reprs( + int id: @for_type_repr ref, + int type_repr: @type_repr ref +); + +format_args_exprs( + unique int id: @format_args_expr +); + +#keyset[id, index] +format_args_expr_args( + int id: @format_args_expr ref, + int index: int ref, + int arg: @format_args_arg ref +); + +#keyset[id, index] +format_args_expr_attrs( + int id: @format_args_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +format_args_expr_templates( + int id: @format_args_expr ref, + int template: @expr ref +); + +ident_pats( + unique int id: @ident_pat +); + +#keyset[id, index] +ident_pat_attrs( + int id: @ident_pat ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ident_pat_is_mut( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_is_ref( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_names( + int id: @ident_pat ref, + int name: @name ref +); + +#keyset[id] +ident_pat_pats( + int id: @ident_pat ref, + int pat: @pat ref +); + +if_exprs( + unique int id: @if_expr +); + +#keyset[id, index] +if_expr_attrs( + int id: @if_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +if_expr_conditions( + int id: @if_expr ref, + int condition: @expr ref +); + +#keyset[id] +if_expr_elses( + int id: @if_expr ref, + int else: @expr ref +); + +#keyset[id] +if_expr_thens( + int id: @if_expr ref, + int then: @block_expr ref +); + +impl_trait_type_reprs( + unique int id: @impl_trait_type_repr +); + +#keyset[id] +impl_trait_type_repr_type_bound_lists( + int id: @impl_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +index_exprs( + unique int id: @index_expr +); + +#keyset[id, index] +index_expr_attrs( + int id: @index_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +index_expr_bases( + int id: @index_expr ref, + int base: @expr ref +); + +#keyset[id] +index_expr_indices( + int id: @index_expr ref, + int index: @expr ref +); + +infer_type_reprs( + unique int id: @infer_type_repr +); + +@item = + @asm_expr +| @assoc_item +| @extern_block +| @extern_crate +| @extern_item +| @impl +| @macro_def +| @macro_rules +| @module +| @trait +| @trait_alias +| @type_item +| @use +; + +#keyset[id] +item_attribute_macro_expansions( + int id: @item ref, + int attribute_macro_expansion: @macro_items ref +); + +@labelable_expr = + @block_expr +| @looping_expr +; + +#keyset[id] +labelable_expr_labels( + int id: @labelable_expr ref, + int label: @label ref +); + +let_exprs( + unique int id: @let_expr +); + +#keyset[id, index] +let_expr_attrs( + int id: @let_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_expr_scrutinees( + int id: @let_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +let_expr_pats( + int id: @let_expr ref, + int pat: @pat ref +); + +let_stmts( + unique int id: @let_stmt +); + +#keyset[id, index] +let_stmt_attrs( + int id: @let_stmt ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_stmt_initializers( + int id: @let_stmt ref, + int initializer: @expr ref +); + +#keyset[id] +let_stmt_let_elses( + int id: @let_stmt ref, + int let_else: @let_else ref +); + +#keyset[id] +let_stmt_pats( + int id: @let_stmt ref, + int pat: @pat ref +); + +#keyset[id] +let_stmt_type_reprs( + int id: @let_stmt ref, + int type_repr: @type_repr ref +); + +lifetimes( + unique int id: @lifetime +); + +#keyset[id] +lifetime_texts( + int id: @lifetime ref, + string text: string ref +); + +lifetime_args( + unique int id: @lifetime_arg +); + +#keyset[id] +lifetime_arg_lifetimes( + int id: @lifetime_arg ref, + int lifetime: @lifetime ref +); + +lifetime_params( + unique int id: @lifetime_param +); + +#keyset[id, index] +lifetime_param_attrs( + int id: @lifetime_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +lifetime_param_lifetimes( + int id: @lifetime_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +lifetime_param_type_bound_lists( + int id: @lifetime_param ref, + int type_bound_list: @type_bound_list ref +); + +literal_exprs( + unique int id: @literal_expr +); + +#keyset[id, index] +literal_expr_attrs( + int id: @literal_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +literal_expr_text_values( + int id: @literal_expr ref, + string text_value: string ref +); + +literal_pats( + unique int id: @literal_pat +); + +#keyset[id] +literal_pat_literals( + int id: @literal_pat ref, + int literal: @literal_expr ref +); + +macro_exprs( + unique int id: @macro_expr +); + +#keyset[id] +macro_expr_macro_calls( + int id: @macro_expr ref, + int macro_call: @macro_call ref +); + +macro_pats( + unique int id: @macro_pat +); + +#keyset[id] +macro_pat_macro_calls( + int id: @macro_pat ref, + int macro_call: @macro_call ref +); + +macro_type_reprs( + unique int id: @macro_type_repr +); + +#keyset[id] +macro_type_repr_macro_calls( + int id: @macro_type_repr ref, + int macro_call: @macro_call ref +); + +match_exprs( + unique int id: @match_expr +); + +#keyset[id, index] +match_expr_attrs( + int id: @match_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_expr_scrutinees( + int id: @match_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +match_expr_match_arm_lists( + int id: @match_expr ref, + int match_arm_list: @match_arm_list ref +); + +method_call_exprs( + unique int id: @method_call_expr +); + +#keyset[id] +method_call_expr_arg_lists( + int id: @method_call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +method_call_expr_attrs( + int id: @method_call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +method_call_expr_generic_arg_lists( + int id: @method_call_expr ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +method_call_expr_identifiers( + int id: @method_call_expr ref, + int identifier: @name_ref ref +); + +#keyset[id] +method_call_expr_receivers( + int id: @method_call_expr ref, + int receiver: @expr ref +); + +name_refs( + unique int id: @name_ref +); + +#keyset[id] +name_ref_texts( + int id: @name_ref ref, + string text: string ref +); + +never_type_reprs( + unique int id: @never_type_repr +); + +offset_of_exprs( + unique int id: @offset_of_expr +); + +#keyset[id, index] +offset_of_expr_attrs( + int id: @offset_of_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +offset_of_expr_fields( + int id: @offset_of_expr ref, + int index: int ref, + int field: @name_ref ref +); + +#keyset[id] +offset_of_expr_type_reprs( + int id: @offset_of_expr ref, + int type_repr: @type_repr ref +); + +or_pats( + unique int id: @or_pat +); + +#keyset[id, index] +or_pat_pats( + int id: @or_pat ref, + int index: int ref, + int pat: @pat ref +); + +params( + unique int id: @param +); + +#keyset[id] +param_pats( + int id: @param ref, + int pat: @pat ref +); + +paren_exprs( + unique int id: @paren_expr +); + +#keyset[id, index] +paren_expr_attrs( + int id: @paren_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +paren_expr_exprs( + int id: @paren_expr ref, + int expr: @expr ref +); + +paren_pats( + unique int id: @paren_pat +); + +#keyset[id] +paren_pat_pats( + int id: @paren_pat ref, + int pat: @pat ref +); + +paren_type_reprs( + unique int id: @paren_type_repr +); + +#keyset[id] +paren_type_repr_type_reprs( + int id: @paren_type_repr ref, + int type_repr: @type_repr ref +); + +@path_expr_base = + @path_expr +; + +path_pats( + unique int id: @path_pat +); + +path_type_reprs( + unique int id: @path_type_repr +); + +#keyset[id] +path_type_repr_paths( + int id: @path_type_repr ref, + int path: @path ref +); + +prefix_exprs( + unique int id: @prefix_expr +); + +#keyset[id, index] +prefix_expr_attrs( + int id: @prefix_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +prefix_expr_exprs( + int id: @prefix_expr ref, + int expr: @expr ref +); + +#keyset[id] +prefix_expr_operator_names( + int id: @prefix_expr ref, + string operator_name: string ref +); + +ptr_type_reprs( + unique int id: @ptr_type_repr +); + +#keyset[id] +ptr_type_repr_is_const( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_is_mut( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_type_reprs( + int id: @ptr_type_repr ref, + int type_repr: @type_repr ref +); + +range_exprs( + unique int id: @range_expr +); + +#keyset[id, index] +range_expr_attrs( + int id: @range_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +range_expr_ends( + int id: @range_expr ref, + int end: @expr ref +); + +#keyset[id] +range_expr_operator_names( + int id: @range_expr ref, + string operator_name: string ref +); + +#keyset[id] +range_expr_starts( + int id: @range_expr ref, + int start: @expr ref +); + +range_pats( + unique int id: @range_pat +); + +#keyset[id] +range_pat_ends( + int id: @range_pat ref, + int end: @pat ref +); + +#keyset[id] +range_pat_operator_names( + int id: @range_pat ref, + string operator_name: string ref +); + +#keyset[id] +range_pat_starts( + int id: @range_pat ref, + int start: @pat ref +); + +ref_exprs( + unique int id: @ref_expr +); + +#keyset[id, index] +ref_expr_attrs( + int id: @ref_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ref_expr_exprs( + int id: @ref_expr ref, + int expr: @expr ref +); + +#keyset[id] +ref_expr_is_const( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_mut( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_raw( + int id: @ref_expr ref +); + +ref_pats( + unique int id: @ref_pat +); + +#keyset[id] +ref_pat_is_mut( + int id: @ref_pat ref +); + +#keyset[id] +ref_pat_pats( + int id: @ref_pat ref, + int pat: @pat ref +); + +ref_type_reprs( + unique int id: @ref_type_repr +); + +#keyset[id] +ref_type_repr_is_mut( + int id: @ref_type_repr ref +); + +#keyset[id] +ref_type_repr_lifetimes( + int id: @ref_type_repr ref, + int lifetime: @lifetime ref +); + +#keyset[id] +ref_type_repr_type_reprs( + int id: @ref_type_repr ref, + int type_repr: @type_repr ref +); + +rest_pats( + unique int id: @rest_pat +); + +#keyset[id, index] +rest_pat_attrs( + int id: @rest_pat ref, + int index: int ref, + int attr: @attr ref +); + +return_exprs( + unique int id: @return_expr +); + +#keyset[id, index] +return_expr_attrs( + int id: @return_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +return_expr_exprs( + int id: @return_expr ref, + int expr: @expr ref +); + +self_params( + unique int id: @self_param +); + +#keyset[id] +self_param_is_ref( + int id: @self_param ref +); + +#keyset[id] +self_param_is_mut( + int id: @self_param ref +); + +#keyset[id] +self_param_lifetimes( + int id: @self_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +self_param_names( + int id: @self_param ref, + int name: @name ref +); + +slice_pats( + unique int id: @slice_pat +); + +#keyset[id, index] +slice_pat_pats( + int id: @slice_pat ref, + int index: int ref, + int pat: @pat ref +); + +slice_type_reprs( + unique int id: @slice_type_repr +); + +#keyset[id] +slice_type_repr_type_reprs( + int id: @slice_type_repr ref, + int type_repr: @type_repr ref +); + +struct_exprs( + unique int id: @struct_expr +); + +#keyset[id] +struct_expr_struct_expr_field_lists( + int id: @struct_expr ref, + int struct_expr_field_list: @struct_expr_field_list ref +); + +struct_field_lists( + unique int id: @struct_field_list +); + +#keyset[id, index] +struct_field_list_fields( + int id: @struct_field_list ref, + int index: int ref, + int field: @struct_field ref +); + +struct_pats( + unique int id: @struct_pat +); + +#keyset[id] +struct_pat_struct_pat_field_lists( + int id: @struct_pat ref, + int struct_pat_field_list: @struct_pat_field_list ref +); + +try_exprs( + unique int id: @try_expr +); + +#keyset[id, index] +try_expr_attrs( + int id: @try_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +try_expr_exprs( + int id: @try_expr ref, + int expr: @expr ref +); + +tuple_exprs( + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_attrs( + int id: @tuple_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +tuple_expr_fields( + int id: @tuple_expr ref, + int index: int ref, + int field: @expr ref +); + +tuple_field_lists( + unique int id: @tuple_field_list +); + +#keyset[id, index] +tuple_field_list_fields( + int id: @tuple_field_list ref, + int index: int ref, + int field: @tuple_field ref +); + +tuple_pats( + unique int id: @tuple_pat +); + +#keyset[id, index] +tuple_pat_fields( + int id: @tuple_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_struct_pats( + unique int id: @tuple_struct_pat +); + +#keyset[id, index] +tuple_struct_pat_fields( + int id: @tuple_struct_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_type_reprs( + unique int id: @tuple_type_repr +); + +#keyset[id, index] +tuple_type_repr_fields( + int id: @tuple_type_repr ref, + int index: int ref, + int field: @type_repr ref +); + +type_args( + unique int id: @type_arg +); + +#keyset[id] +type_arg_type_reprs( + int id: @type_arg ref, + int type_repr: @type_repr ref +); + +type_params( + unique int id: @type_param +); + +#keyset[id, index] +type_param_attrs( + int id: @type_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_param_default_types( + int id: @type_param ref, + int default_type: @type_repr ref +); + +#keyset[id] +type_param_names( + int id: @type_param ref, + int name: @name ref +); + +#keyset[id] +type_param_type_bound_lists( + int id: @type_param ref, + int type_bound_list: @type_bound_list ref +); + +underscore_exprs( + unique int id: @underscore_expr +); + +#keyset[id, index] +underscore_expr_attrs( + int id: @underscore_expr ref, + int index: int ref, + int attr: @attr ref +); + +variants( + unique int id: @variant +); + +#keyset[id, index] +variant_attrs( + int id: @variant ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +variant_discriminants( + int id: @variant ref, + int discriminant: @expr ref +); + +#keyset[id] +variant_field_lists( + int id: @variant ref, + int field_list: @field_list ref +); + +#keyset[id] +variant_names( + int id: @variant ref, + int name: @name ref +); + +#keyset[id] +variant_visibilities( + int id: @variant ref, + int visibility: @visibility ref +); + +wildcard_pats( + unique int id: @wildcard_pat +); + +yeet_exprs( + unique int id: @yeet_expr +); + +#keyset[id, index] +yeet_expr_attrs( + int id: @yeet_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yeet_expr_exprs( + int id: @yeet_expr ref, + int expr: @expr ref +); + +yield_exprs( + unique int id: @yield_expr +); + +#keyset[id, index] +yield_expr_attrs( + int id: @yield_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yield_expr_exprs( + int id: @yield_expr ref, + int expr: @expr ref +); + +asm_exprs( + unique int id: @asm_expr +); + +#keyset[id, index] +asm_expr_asm_pieces( + int id: @asm_expr ref, + int index: int ref, + int asm_piece: @asm_piece ref +); + +#keyset[id, index] +asm_expr_attrs( + int id: @asm_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +asm_expr_templates( + int id: @asm_expr ref, + int index: int ref, + int template: @expr ref +); + +@assoc_item = + @const +| @function +| @macro_call +| @type_alias +; + +block_exprs( + unique int id: @block_expr +); + +#keyset[id, index] +block_expr_attrs( + int id: @block_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +block_expr_is_async( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_const( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_gen( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_move( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_try( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_unsafe( + int id: @block_expr ref +); + +#keyset[id] +block_expr_stmt_lists( + int id: @block_expr ref, + int stmt_list: @stmt_list ref +); + +extern_blocks( + unique int id: @extern_block +); + +#keyset[id] +extern_block_abis( + int id: @extern_block ref, + int abi: @abi ref +); + +#keyset[id, index] +extern_block_attrs( + int id: @extern_block ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_block_extern_item_lists( + int id: @extern_block ref, + int extern_item_list: @extern_item_list ref +); + +#keyset[id] +extern_block_is_unsafe( + int id: @extern_block ref +); + +extern_crates( + unique int id: @extern_crate +); + +#keyset[id, index] +extern_crate_attrs( + int id: @extern_crate ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_crate_identifiers( + int id: @extern_crate ref, + int identifier: @name_ref ref +); + +#keyset[id] +extern_crate_renames( + int id: @extern_crate ref, + int rename: @rename ref +); + +#keyset[id] +extern_crate_visibilities( + int id: @extern_crate ref, + int visibility: @visibility ref +); + +@extern_item = + @function +| @macro_call +| @static +| @type_alias +; + +impls( + unique int id: @impl +); + +#keyset[id] +impl_assoc_item_lists( + int id: @impl ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +impl_attrs( + int id: @impl ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +impl_generic_param_lists( + int id: @impl ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +impl_is_const( + int id: @impl ref +); + +#keyset[id] +impl_is_default( + int id: @impl ref +); + +#keyset[id] +impl_is_unsafe( + int id: @impl ref +); + +#keyset[id] +impl_self_ties( + int id: @impl ref, + int self_ty: @type_repr ref +); + +#keyset[id] +impl_trait_ties( + int id: @impl ref, + int trait_ty: @type_repr ref +); + +#keyset[id] +impl_visibilities( + int id: @impl ref, + int visibility: @visibility ref +); + +#keyset[id] +impl_where_clauses( + int id: @impl ref, + int where_clause: @where_clause ref +); + +@looping_expr = + @for_expr +| @loop_expr +| @while_expr +; + +#keyset[id] +looping_expr_loop_bodies( + int id: @looping_expr ref, + int loop_body: @block_expr ref +); + +macro_defs( + unique int id: @macro_def +); + +#keyset[id] +macro_def_args( + int id: @macro_def ref, + int args: @token_tree ref +); + +#keyset[id, index] +macro_def_attrs( + int id: @macro_def ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_def_bodies( + int id: @macro_def ref, + int body: @token_tree ref +); + +#keyset[id] +macro_def_names( + int id: @macro_def ref, + int name: @name ref +); + +#keyset[id] +macro_def_visibilities( + int id: @macro_def ref, + int visibility: @visibility ref +); + +macro_rules( + unique int id: @macro_rules +); + +#keyset[id, index] +macro_rules_attrs( + int id: @macro_rules ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_rules_names( + int id: @macro_rules ref, + int name: @name ref +); + +#keyset[id] +macro_rules_token_trees( + int id: @macro_rules ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_rules_visibilities( + int id: @macro_rules ref, + int visibility: @visibility ref +); + +modules( + unique int id: @module +); + +#keyset[id, index] +module_attrs( + int id: @module ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +module_item_lists( + int id: @module ref, + int item_list: @item_list ref +); + +#keyset[id] +module_names( + int id: @module ref, + int name: @name ref +); + +#keyset[id] +module_visibilities( + int id: @module ref, + int visibility: @visibility ref +); + +path_exprs( + unique int id: @path_expr +); + +#keyset[id, index] +path_expr_attrs( + int id: @path_expr ref, + int index: int ref, + int attr: @attr ref +); + +traits( + unique int id: @trait +); + +#keyset[id] +trait_assoc_item_lists( + int id: @trait ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +trait_attrs( + int id: @trait ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_generic_param_lists( + int id: @trait ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_is_auto( + int id: @trait ref +); + +#keyset[id] +trait_is_unsafe( + int id: @trait ref +); + +#keyset[id] +trait_names( + int id: @trait ref, + int name: @name ref +); + +#keyset[id] +trait_type_bound_lists( + int id: @trait ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_visibilities( + int id: @trait ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_where_clauses( + int id: @trait ref, + int where_clause: @where_clause ref +); + +trait_aliases( + unique int id: @trait_alias +); + +#keyset[id, index] +trait_alias_attrs( + int id: @trait_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_alias_generic_param_lists( + int id: @trait_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_alias_names( + int id: @trait_alias ref, + int name: @name ref +); + +#keyset[id] +trait_alias_type_bound_lists( + int id: @trait_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_alias_visibilities( + int id: @trait_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_alias_where_clauses( + int id: @trait_alias ref, + int where_clause: @where_clause ref +); + +@type_item = + @enum +| @struct +| @union +; + +#keyset[id, index] +type_item_derive_macro_expansions( + int id: @type_item ref, + int index: int ref, + int derive_macro_expansion: @macro_items ref +); + +#keyset[id, index] +type_item_attrs( + int id: @type_item ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_item_generic_param_lists( + int id: @type_item ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_item_names( + int id: @type_item ref, + int name: @name ref +); + +#keyset[id] +type_item_visibilities( + int id: @type_item ref, + int visibility: @visibility ref +); + +#keyset[id] +type_item_where_clauses( + int id: @type_item ref, + int where_clause: @where_clause ref +); + +uses( + unique int id: @use +); + +#keyset[id, index] +use_attrs( + int id: @use ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +use_use_trees( + int id: @use ref, + int use_tree: @use_tree ref +); + +#keyset[id] +use_visibilities( + int id: @use ref, + int visibility: @visibility ref +); + +consts( + unique int id: @const +); + +#keyset[id, index] +const_attrs( + int id: @const ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_bodies( + int id: @const ref, + int body: @expr ref +); + +#keyset[id] +const_generic_param_lists( + int id: @const ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +const_is_const( + int id: @const ref +); + +#keyset[id] +const_is_default( + int id: @const ref +); + +#keyset[id] +const_names( + int id: @const ref, + int name: @name ref +); + +#keyset[id] +const_type_reprs( + int id: @const ref, + int type_repr: @type_repr ref +); + +#keyset[id] +const_visibilities( + int id: @const ref, + int visibility: @visibility ref +); + +#keyset[id] +const_where_clauses( + int id: @const ref, + int where_clause: @where_clause ref +); + +#keyset[id] +const_has_implementation( + int id: @const ref +); + +enums( + unique int id: @enum +); + +#keyset[id] +enum_variant_lists( + int id: @enum ref, + int variant_list: @variant_list ref +); + +for_exprs( + unique int id: @for_expr +); + +#keyset[id, index] +for_expr_attrs( + int id: @for_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +for_expr_iterables( + int id: @for_expr ref, + int iterable: @expr ref +); + +#keyset[id] +for_expr_pats( + int id: @for_expr ref, + int pat: @pat ref +); + +functions( + unique int id: @function +); + +#keyset[id] +function_abis( + int id: @function ref, + int abi: @abi ref +); + +#keyset[id] +function_function_bodies( + int id: @function ref, + int function_body: @block_expr ref +); + +#keyset[id] +function_generic_param_lists( + int id: @function ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +function_is_async( + int id: @function ref +); + +#keyset[id] +function_is_const( + int id: @function ref +); + +#keyset[id] +function_is_default( + int id: @function ref +); + +#keyset[id] +function_is_gen( + int id: @function ref +); + +#keyset[id] +function_is_unsafe( + int id: @function ref +); + +#keyset[id] +function_names( + int id: @function ref, + int name: @name ref +); + +#keyset[id] +function_ret_types( + int id: @function ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +function_visibilities( + int id: @function ref, + int visibility: @visibility ref +); + +#keyset[id] +function_where_clauses( + int id: @function ref, + int where_clause: @where_clause ref +); + +#keyset[id] +function_has_implementation( + int id: @function ref +); + +loop_exprs( + unique int id: @loop_expr +); + +#keyset[id, index] +loop_expr_attrs( + int id: @loop_expr ref, + int index: int ref, + int attr: @attr ref +); + +macro_calls( + unique int id: @macro_call +); + +#keyset[id, index] +macro_call_attrs( + int id: @macro_call ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_call_paths( + int id: @macro_call ref, + int path: @path ref +); + +#keyset[id] +macro_call_token_trees( + int id: @macro_call ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_call_macro_call_expansions( + int id: @macro_call ref, + int macro_call_expansion: @ast_node ref +); + +statics( + unique int id: @static +); + +#keyset[id, index] +static_attrs( + int id: @static ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +static_bodies( + int id: @static ref, + int body: @expr ref +); + +#keyset[id] +static_is_mut( + int id: @static ref +); + +#keyset[id] +static_is_static( + int id: @static ref +); + +#keyset[id] +static_is_unsafe( + int id: @static ref +); + +#keyset[id] +static_names( + int id: @static ref, + int name: @name ref +); + +#keyset[id] +static_type_reprs( + int id: @static ref, + int type_repr: @type_repr ref +); + +#keyset[id] +static_visibilities( + int id: @static ref, + int visibility: @visibility ref +); + +structs( + unique int id: @struct +); + +#keyset[id] +struct_field_lists_( + int id: @struct ref, + int field_list: @field_list ref +); + +type_aliases( + unique int id: @type_alias +); + +#keyset[id, index] +type_alias_attrs( + int id: @type_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_alias_generic_param_lists( + int id: @type_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_alias_is_default( + int id: @type_alias ref +); + +#keyset[id] +type_alias_names( + int id: @type_alias ref, + int name: @name ref +); + +#keyset[id] +type_alias_type_reprs( + int id: @type_alias ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_alias_type_bound_lists( + int id: @type_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +type_alias_visibilities( + int id: @type_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +type_alias_where_clauses( + int id: @type_alias ref, + int where_clause: @where_clause ref +); + +unions( + unique int id: @union +); + +#keyset[id] +union_struct_field_lists( + int id: @union ref, + int struct_field_list: @struct_field_list ref +); + +while_exprs( + unique int id: @while_expr +); + +#keyset[id, index] +while_expr_attrs( + int id: @while_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +while_expr_conditions( + int id: @while_expr ref, + int condition: @expr ref +); diff --git a/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/upgrade.properties b/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/upgrade.properties new file mode 100644 index 00000000000..002daf2af7c --- /dev/null +++ b/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/upgrade.properties @@ -0,0 +1,5 @@ +description: Renamed `impl_traits` to `impl_trait_ties` +compatibility: full + +impl_trait_ties.rel: reorder impl_traits(@impl id, @type_repr trait_ty) id trait_ty +impl_traits.rel: delete \ No newline at end of file From 62207f152cdf2f54fd426b8ae4fd6fd5571c4e8e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 1 Jun 2026 13:55:22 +0200 Subject: [PATCH 159/226] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll index 87c42ed7dad..4c039a6f957 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ImplImpl.qll @@ -55,7 +55,7 @@ module Impl { * impl MyTrait for MyType { ... } * ``` * - * the type being implemented is in both cases`MyType`. + * the type being implemented is in both cases `MyType`. */ TypeItem getSelf() { result = this.getSelfTy().(TypeMention).getType().(DataType).getTypeItem() From 56822f8ee186040e312f9acb507e16054c404d25 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 27 May 2026 22:18:42 +0200 Subject: [PATCH 160/226] Tree-sitter-extactor: More helpful panic message --- shared/tree-sitter-extractor/src/generator/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/shared/tree-sitter-extractor/src/generator/mod.rs b/shared/tree-sitter-extractor/src/generator/mod.rs index 8167dc2574e..da13322fe60 100644 --- a/shared/tree-sitter-extractor/src/generator/mod.rs +++ b/shared/tree-sitter-extractor/src/generator/mod.rs @@ -305,7 +305,18 @@ fn convert_nodes( // type. let members: Set<&str> = n_members .iter() - .map(|n| nodes.get(n).unwrap().dbscheme_name.as_str()) + .map(|n| { + nodes + .get(n) + .unwrap_or_else(|| { + panic!( + "union type '{}' references unknown member node type {:?}", + node.dbscheme_name, n + ) + }) + .dbscheme_name + .as_str() + }) .collect(); entries.push(dbscheme::Entry::Union(dbscheme::Union { name: &node.dbscheme_name, From ef9306d82ce11aa72059d48c6fa776227a2e0856 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 27 May 2026 22:18:42 +0200 Subject: [PATCH 161/226] Yeast: Allow rules that return an empty sequence --- shared/yeast-macros/src/parse.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index 608c332d47e..96e426bbf62 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -475,6 +475,11 @@ fn parse_direct_list(tokens: &mut Tokens, ctx: &Ident) -> Result Date: Wed, 27 May 2026 22:18:42 +0200 Subject: [PATCH 162/226] Yeast: Fix handling of captures with multiple results --- shared/yeast/src/captures.rs | 14 +++++++++----- shared/yeast/src/lib.rs | 21 +++++++++++---------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/shared/yeast/src/captures.rs b/shared/yeast/src/captures.rs index ef184cd9f69..404d402a501 100644 --- a/shared/yeast/src/captures.rs +++ b/shared/yeast/src/captures.rs @@ -63,16 +63,20 @@ impl Captures { } /// Apply a fallible function to every captured id (across all keys), - /// replacing each id with the result. Stops and returns the error on - /// the first failure. + /// replacing each id with the results. A function returning an empty + /// vector removes the capture; returning multiple ids splices them + /// into the capture's value list (suitable for `*`/`+` captures). + /// Stops and returns the error on the first failure. pub fn try_map_all_captures( &mut self, - mut f: impl FnMut(Id) -> Result, + mut f: impl FnMut(Id) -> Result, E>, ) -> Result<(), E> { for ids in self.captures.values_mut() { - for id in ids { - *id = f(*id)?; + let mut new_ids = Vec::with_capacity(ids.len()); + for &id in ids.iter() { + new_ids.extend(f(id)?); } + *ids = new_ids; } Ok(()) } diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index 8826c3d6c1e..0717d27e4b8 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -563,6 +563,15 @@ impl Node { NodeContent::DynamicString(s) => Some(s.to_string()), } } + + /// Read the child ids stored under a given field, or an empty slice if + /// no such field is present on this node. + pub fn field_children(&self, field_id: FieldId) -> &[Id] { + self.fields + .get(&field_id) + .map(|v| v.as_slice()) + .unwrap_or(&[]) + } } /// The contents of a node is either a range in the original source file, @@ -836,17 +845,9 @@ fn apply_one_shot_rules_inner( // pattern root): re-analyzing it would match the same rule // again indefinitely. if captured_id == id { - return Ok(captured_id); + return Ok(vec![captured_id]); } - let result = - apply_one_shot_rules_inner(index, ast, captured_id, fresh, rewrite_depth + 1)?; - if result.len() != 1 { - return Err(format!( - "OneShot: recursion on captured node produced {} results, expected exactly 1", - result.len() - )); - } - Ok(result[0]) + apply_one_shot_rules_inner(index, ast, captured_id, fresh, rewrite_depth + 1) })?; return Ok(rule.run_transform(ast, captures, id, fresh)); } From 1ecdc3614f090ae83c078983363e1c923381f118 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 27 May 2026 22:18:42 +0200 Subject: [PATCH 163/226] Yeast: Fix matching against extras like comments --- shared/yeast/src/query.rs | 14 +++++++++----- shared/yeast/tests/test.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/shared/yeast/src/query.rs b/shared/yeast/src/query.rs index 01e5e22ad73..bcf0f7facab 100644 --- a/shared/yeast/src/query.rs +++ b/shared/yeast/src/query.rs @@ -178,11 +178,15 @@ impl QueryListElem { let Some(child) = remaining_children.next() else { return Ok(false); }; - if skip_unnamed { - let node = ast.get_node(child).unwrap(); - if !node.is_named() { - continue; - } + let node = ast.get_node(child).unwrap(); + // Skip tree-sitter `extras` (e.g. comments) during + // positional matching: they are conceptually invisible + // between siblings, mirroring tree-sitter query semantics. + if node.is_extra() { + continue; + } + if skip_unnamed && !node.is_named() { + continue; } let snapshot = matches.clone(); if sub_query.do_match(ast, child, matches)? { diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index 7f4db154183..7645f3776f8 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -274,6 +274,44 @@ fn test_query_no_match() { assert!(!matched); } +#[test] +fn test_query_skips_extras_in_positional_match() { + // Regression test: positional wildcards `(_)` must not bind to + // tree-sitter `extras` (e.g. comments) during forward-scan; extras + // are conceptually invisible between siblings, matching tree-sitter + // query semantics. Without this, a later rule that translates a + // captured comment to nothing (a common idiom, e.g. + // `(comment) => ()` in Swift) leaves the capture's match-list empty + // and causes the transform to fail with "Variable X has 0 matches". + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("[1, # comment\n2]").unwrap(); + + // Navigate to the `array` node: program -> array. + let mut cursor = AstCursor::new(&ast); + cursor.goto_first_child(); + let array_id = cursor.node_id(); + assert_eq!(ast.get_node(array_id).unwrap().kind(), "array"); + + // Two positional wildcards should bind to the two integers, skipping + // the comment that sits between them. + let query = yeast::query!((array (_) @a (_) @b)); + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, array_id, &mut captures).unwrap(); + assert!(matched); + assert_eq!( + ast.get_node(captures.get_var("a").unwrap()) + .unwrap() + .kind(), + "integer" + ); + assert_eq!( + ast.get_node(captures.get_var("b").unwrap()) + .unwrap() + .kind(), + "integer" + ); +} + #[test] fn test_reachable_nodes_excludes_orphaned_rewrite_nodes() { let lang: tree_sitter::Language = tree_sitter_ruby::LANGUAGE.into(); From ac8eb50c269d6ff81add27771bb1725a25381cdd Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 May 2026 10:27:43 +0200 Subject: [PATCH 164/226] Yeast: Allow 'r#type' to escape the 'type' keyword in macro --- shared/yeast-macros/src/parse.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index 96e426bbf62..e623c708726 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -411,7 +411,7 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result Date: Thu, 28 May 2026 13:34:22 +0200 Subject: [PATCH 165/226] Fix parsing of corpus tests when --- delimiter is missing --- unified/extractor/tests/corpus_tests.rs | 82 ++++++++++++++----------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/unified/extractor/tests/corpus_tests.rs b/unified/extractor/tests/corpus_tests.rs index ac93dd586ec..0f1057a8e5b 100644 --- a/unified/extractor/tests/corpus_tests.rs +++ b/unified/extractor/tests/corpus_tests.rs @@ -26,6 +26,13 @@ fn is_header_rule(line: &str) -> bool { trimmed.len() >= 3 && trimmed.chars().all(|c| c == '=') } +fn is_next_case_header(lines: &[&str], i: usize) -> bool { + is_header_rule(lines[i]) + && i + 2 < lines.len() + && !lines[i + 1].trim().is_empty() + && is_header_rule(lines[i + 2]) +} + fn parse_corpus(content: &str) -> Vec { let lines: Vec<&str> = content.lines().collect(); let mut i = 0; @@ -58,48 +65,51 @@ fn parse_corpus(content: &str) -> Vec { let input_start = i; while i < lines.len() && lines[i].trim() != "---" { + if is_next_case_header(&lines, i) { + break; + } i += 1; } - assert!(i < lines.len(), "Missing --- separator for case {name}"); let input = lines[input_start..i].join("\n").trim_end().to_string(); - i += 1; - - // Raw tree-sitter parse section. New-format files have a second - // `---` separator between the raw tree and the mapped AST. Legacy - // files (with only one separator) have no raw section — in that - // case `raw` stays empty and update mode will populate it. - let raw_start = i; - let mut next_sep = i; - while next_sep < lines.len() && lines[next_sep].trim() != "---" { - if is_header_rule(lines[next_sep]) - && next_sep + 2 < lines.len() - && !lines[next_sep + 1].trim().is_empty() - && is_header_rule(lines[next_sep + 2]) - { - break; - } - next_sep += 1; - } - let raw = if next_sep < lines.len() && lines[next_sep].trim() == "---" { - let raw_text = lines[raw_start..next_sep].join("\n").trim().to_string(); - i = next_sep + 1; - raw_text + let raw; + let expected; + if i >= lines.len() || lines[i].trim() != "---" { + // No `---` separator before next case (or EOF). Treat the + // remaining sections as empty. + raw = String::new(); + expected = String::new(); } else { - String::new() - }; - - let expected_start = i; - while i < lines.len() { - if is_header_rule(lines[i]) - && i + 2 < lines.len() - && !lines[i + 1].trim().is_empty() - && is_header_rule(lines[i + 2]) - { - break; - } i += 1; + + // Raw tree-sitter parse section. New-format files have a second + // `---` separator between the raw tree and the mapped AST. Legacy + // files (with only one separator) have no raw section — in that + // case `raw` stays empty and update mode will populate it. + let raw_start = i; + let mut next_sep = i; + while next_sep < lines.len() && lines[next_sep].trim() != "---" { + if is_next_case_header(&lines, next_sep) { + break; + } + next_sep += 1; + } + raw = if next_sep < lines.len() && lines[next_sep].trim() == "---" { + let raw_text = lines[raw_start..next_sep].join("\n").trim().to_string(); + i = next_sep + 1; + raw_text + } else { + String::new() + }; + + let expected_start = i; + while i < lines.len() { + if is_next_case_header(&lines, i) { + break; + } + i += 1; + } + expected = lines[expected_start..i].join("\n").trim().to_string(); } - let expected = lines[expected_start..i].join("\n").trim().to_string(); cases.push(CorpusCase { name, From 21f216af8cc055f3640ef23ea14cb400672de24b Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 28 May 2026 15:17:26 +0200 Subject: [PATCH 166/226] yeast-macros: omit empty fields produced by .. splice When a {..expr} splice in an output template is empty (e.g. from an optional capture that did not match), drop the field entirely rather than emitting an empty named field. This lets a single rule with optional captures replace what used to be two near-identical rules. Also re-renders the corpus to drop the now-suppressed empty fields. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shared/yeast-macros/src/parse.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index e623c708726..eb3b161b295 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -437,7 +437,11 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result::into) .collect(); }); - field_args.push(quote! { (#field_str, #temp) }); + // An empty splice means the field is absent — skip it + // entirely rather than emitting an empty named field. + field_args.push(quote! { + if !#temp.is_empty() { __fields.push((#field_str, #temp)); } + }); continue; } } @@ -445,7 +449,7 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result Result)> = Vec::new(); + #(#field_args)* + #ctx.node(#kind_str, __fields) } }) } From 3f3bed62d3d9ad851981bcbb6b0bcb71113c22c3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 29 May 2026 17:23:02 +0200 Subject: [PATCH 167/226] yeast: type-check for missing required fields Add FieldCardinality to Schema to track required/multiple per field, populated from the ast_types.yml suffixes (bare = required single, ? = optional single, + = required multiple, * = optional multiple). dump_ast_with_type_errors now emits: <-- ERROR: missing required field 'name' for any node in the output AST whose declared schema requires a field that is absent from the actual node. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shared/yeast/src/dump.rs | 10 ++++++ shared/yeast/src/node_types_yaml.rs | 8 +++++ shared/yeast/src/schema.rs | 47 +++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/shared/yeast/src/dump.rs b/shared/yeast/src/dump.rs index 07ee134e058..d046c192053 100644 --- a/shared/yeast/src/dump.rs +++ b/shared/yeast/src/dump.rs @@ -273,6 +273,16 @@ fn dump_node( } } + // Check for required fields that are absent + if let Some((schema, _, _)) = type_check { + for (field_id, field_name) in schema.required_fields_for_kind(node.kind_name()) { + if !node.fields.contains_key(&field_id) { + let name = field_name.unwrap_or("child"); + writeln!(out, "{prefix} <-- ERROR: missing required field '{name}'").unwrap(); + } + } + } + // Unnamed children — skip unnamed tokens (keywords, punctuation) if let Some(children) = node.fields.get(&CHILD_FIELD) { let child_type_check = type_check.map(|(schema, _, _)| { diff --git a/shared/yeast/src/node_types_yaml.rs b/shared/yeast/src/node_types_yaml.rs index eb191076be4..797f14cba72 100644 --- a/shared/yeast/src/node_types_yaml.rs +++ b/shared/yeast/src/node_types_yaml.rs @@ -314,6 +314,14 @@ fn apply_yaml_to_schema( node_types.sort_by(|a, b| a.kind.cmp(&b.kind).then(a.named.cmp(&b.named))); node_types.dedup_by(|a, b| a.kind == b.kind && a.named == b.named); schema.set_field_types(parent_kind, field_id, node_types); + schema.set_field_cardinality( + parent_kind, + field_id, + crate::schema::FieldCardinality { + multiple: spec.multiple, + required: spec.required, + }, + ); } } } diff --git a/shared/yeast/src/schema.rs b/shared/yeast/src/schema.rs index c832a57b23a..bbd425f15a2 100644 --- a/shared/yeast/src/schema.rs +++ b/shared/yeast/src/schema.rs @@ -8,6 +8,15 @@ pub struct NodeType { pub named: bool, } +/// Multiplicity/optionality of a field declaration. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct FieldCardinality { + /// Whether the field may hold more than one child. + pub multiple: bool, + /// Whether at least one child must be present. + pub required: bool, +} + /// A schema defining node kinds and field names for the output AST. /// Built from a node-types.yml file, independent of any tree-sitter grammar. /// @@ -32,6 +41,7 @@ pub struct Schema { kind_names: BTreeMap, next_kind_id: KindId, field_types: BTreeMap<(String, FieldId), Vec>, + field_cardinalities: BTreeMap<(String, FieldId), FieldCardinality>, supertypes: BTreeMap>, } @@ -52,6 +62,7 @@ impl Schema { kind_names: BTreeMap::new(), next_kind_id: 1, // 0 is reserved field_types: BTreeMap::new(), + field_cardinalities: BTreeMap::new(), supertypes: BTreeMap::new(), } } @@ -196,6 +207,42 @@ impl Schema { .get(&(parent_kind.to_string(), field_id)) } + pub fn set_field_cardinality( + &mut self, + parent_kind: &str, + field_id: FieldId, + cardinality: FieldCardinality, + ) { + self.field_cardinalities + .insert((parent_kind.to_string(), field_id), cardinality); + } + + /// Returns the declared cardinality for a field, if known. + pub fn field_cardinality( + &self, + parent_kind: &str, + field_id: FieldId, + ) -> Option { + self.field_cardinalities + .get(&(parent_kind.to_string(), field_id)) + .copied() + } + + /// Returns an iterator over all `(field_id, field_name)` pairs that are + /// declared as required (`required: true`) for the given `parent_kind`. + pub fn required_fields_for_kind<'a>( + &'a self, + parent_kind: &'a str, + ) -> impl Iterator)> + 'a { + self.field_cardinalities + .iter() + .filter(move |((kind, _), card)| kind == parent_kind && card.required) + .map(move |((_, field_id), _)| { + let name = self.field_name_for_id(*field_id); + (*field_id, name) + }) + } + pub fn set_supertype_members(&mut self, supertype: &str, node_types: Vec) { self.supertypes.insert(supertype.to_string(), node_types); } From 71a363545a1e4e5829bdcab45389adc028a65720 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Mon, 1 Jun 2026 15:21:39 +0200 Subject: [PATCH 168/226] formatting --- .../lib/semmle/code/csharp/dataflow/Bound.qll | 22 +---- .../internal/rangeanalysis/BoundSpecific.qll | 20 ++-- .../lib/semmle/code/java/dataflow/Bound.qll | 22 +---- .../internal/rangeanalysis/BoundSpecific.qll | 2 +- .../codeql/rangeanalysis/Bound.qll | 95 ++++++++++--------- 5 files changed, 61 insertions(+), 100 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll index b37222c1daa..c08e2e1c0d4 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll @@ -11,24 +11,4 @@ private import codeql.rangeanalysis.Bound as SharedBound private module BoundImpl = SharedBound::Bound; -/** - * A bound that may be inferred for an expression plus/minus an integer delta. - */ -class Bound = BoundImpl::Bound; - -/** - * The bound that corresponds to the integer 0. This is used to represent all - * integer bounds as bounds are always accompanied by an added integer delta. - */ -class ZeroBound = BoundImpl::ZeroBound; - -/** - * A bound corresponding to the value of an SSA variable. - */ -class SsaBound = BoundImpl::SsaBound; - -/** - * A bound that corresponds to the value of a specific expression that might be - * interesting, but isn't otherwise represented by the value of an SSA variable. - */ -class ExprBound = BoundImpl::ExprBound; \ No newline at end of file +import BoundImpl diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll index 069f0034eed..9d36d6a81b5 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll @@ -10,23 +10,19 @@ private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU private import codeql.rangeanalysis.Bound as SharedBound /** Holds if `e` is a bound expression and it is not an SSA variable read. */ - - module BoundDefs implements SharedBound::BoundDefinitions { - class Type = CS::Type; + class Type = CS::Type; - class SsaVariable = SU::SsaVariable; - - class SsaSourceVariable = Ssa::SourceVariable; + class SsaVariable = SU::SsaVariable; - class Expr = CS::ControlFlowNodes::ExprNode; + class SsaSourceVariable = Ssa::SourceVariable; - class IntegralType = CS::IntegralType; + class Expr = CS::ControlFlowNodes::ExprNode; - class ConstantIntegerExpr = CU::ConstantIntegerExpr; + class IntegralType = CS::IntegralType; + + class ConstantIntegerExpr = CU::ConstantIntegerExpr; /** Holds if `e` is a bound expression and it is not an SSA variable read. */ - predicate interestingExprBound(Expr e) { - CU::systemArrayLengthAccess(e.getExpr()) - } + predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.getExpr()) } } diff --git a/java/ql/lib/semmle/code/java/dataflow/Bound.qll b/java/ql/lib/semmle/code/java/dataflow/Bound.qll index 0cfe3e9039d..f82afcd17e4 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Bound.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Bound.qll @@ -10,24 +10,4 @@ private import codeql.rangeanalysis.Bound as SharedBound private module BoundImpl = SharedBound::Bound; -/** - * A bound that may be inferred for an expression plus/minus an integer delta. - */ -class Bound = BoundImpl::Bound; - -/** - * The bound that corresponds to the integer 0. This is used to represent all - * integer bounds as bounds are always accompanied by an added integer delta. - */ -class ZeroBound = BoundImpl::ZeroBound; - -/** - * A bound corresponding to the value of an SSA variable. - */ -class SsaBound = BoundImpl::SsaBound; - -/** - * A bound that corresponds to the value of a specific expression that might be - * interesting, but isn't otherwise represented by the value of an SSA variable. - */ -class ExprBound = BoundImpl::ExprBound; \ No newline at end of file +import BoundImpl diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll index ba2f8027b30..5435eeb4492 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll @@ -29,4 +29,4 @@ module BoundDefs implements SharedBound::BoundDefinitions { predicate interestingExprBound(Expr e) { e.(J::FieldRead).getField() instanceof J::ArrayLengthField } -} \ No newline at end of file +} diff --git a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll index 10ef74d4001..af44e692745 100644 --- a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll +++ b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll @@ -5,48 +5,53 @@ private import codeql.util.Location signature module BoundDefinitions { - class Type; - class IntegralType extends Type; + class Type; - class ConstantIntegerExpr extends Expr { - int getIntValue(); - } + class IntegralType extends Type; - class SsaSourceVariable { - Type getType(); - } + class ConstantIntegerExpr extends Expr { + int getIntValue(); + } - class SsaVariable { - SsaSourceVariable getSourceVariable(); - string toString(); - Location getLocation(); - Expr getAUse(); - } + class SsaSourceVariable { + Type getType(); + } - class Expr { - string toString(); - Location getLocation(); - } + class SsaVariable { + SsaSourceVariable getSourceVariable(); - predicate interestingExprBound(Expr e); + string toString(); + + Location getLocation(); + + Expr getAUse(); + } + + class Expr { + string toString(); + + Location getLocation(); + } + + predicate interestingExprBound(Expr e); } overlay[local?] module Bound Defs> { - private import Defs + private import Defs - private newtype TBound = + private newtype TBound = TBoundZero() or TBoundSsa(SsaVariable v) { v.getSourceVariable().getType() instanceof IntegralType } or TBoundExpr(Expr e) { - interestingExprBound(e) and - not exists(SsaVariable v | e = v.getAUse()) + interestingExprBound(e) and + not exists(SsaVariable v | e = v.getAUse()) } - /** - * A bound that may be inferred for an expression plus/minus an integer delta. - */ - abstract class Bound extends TBound { + /** + * A bound that may be inferred for an expression plus/minus an integer delta. + */ + abstract class Bound extends TBound { /** Gets a textual representation of this bound. */ abstract string toString(); @@ -58,24 +63,24 @@ module Bound Defs> { /** Gets the location of this bound. */ abstract Location getLocation(); - } + } - /** - * The bound that corresponds to the integer 0. This is used to represent all - * integer bounds as bounds are always accompanied by an added integer delta. - */ - class ZeroBound extends Bound, TBoundZero { + /** + * The bound that corresponds to the integer 0. This is used to represent all + * integer bounds as bounds are always accompanied by an added integer delta. + */ + class ZeroBound extends Bound, TBoundZero { override string toString() { result = "0" } override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta } override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } - } + } - /** - * A bound corresponding to the value of an SSA variable. - */ - class SsaBound extends Bound, TBoundSsa { + /** + * A bound corresponding to the value of an SSA variable. + */ + class SsaBound extends Bound, TBoundSsa { /** Gets the SSA variable that equals this bound. */ SsaVariable getSsa() { this = TBoundSsa(result) } @@ -84,17 +89,17 @@ module Bound Defs> { override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 } override Location getLocation() { result = this.getSsa().getLocation() } - } + } - /** - * A bound that corresponds to the value of a specific expression that might be - * interesting, but isn't otherwise represented by the value of an SSA variable. - */ - class ExprBound extends Bound, TBoundExpr { + /** + * A bound that corresponds to the value of a specific expression that might be + * interesting, but isn't otherwise represented by the value of an SSA variable. + */ + class ExprBound extends Bound, TBoundExpr { override string toString() { result = this.getExpr().toString() } override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 } override Location getLocation() { result = this.getExpr().getLocation() } - } + } } From d1226b71de156cc4f7fae5cb3e7a622934d9fae6 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Mon, 1 Jun 2026 15:46:52 +0200 Subject: [PATCH 169/226] formatting --- shared/rangeanalysis/codeql/rangeanalysis/Bound.qll | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll index af44e692745..de3aba8781f 100644 --- a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll +++ b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll @@ -1,7 +1,3 @@ -/** - * Provides classes for representing abstract bounds for use in, for example, range analysis. - */ - private import codeql.util.Location signature module BoundDefinitions { @@ -36,6 +32,7 @@ signature module BoundDefinitions { predicate interestingExprBound(Expr e); } +/** Provides classes for representing abstract bounds for use in, for example, range analysis. */ overlay[local?] module Bound Defs> { private import Defs From c1c9287535857dc0db2c56dcbd485425c5806bdd Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Mon, 1 Jun 2026 15:48:26 +0200 Subject: [PATCH 170/226] restore file header --- shared/rangeanalysis/codeql/rangeanalysis/Bound.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll index de3aba8781f..13a3132c283 100644 --- a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll +++ b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll @@ -1,3 +1,9 @@ +/** + * Provides classes for representing abstract bounds for use in, for example, range analysis. + */ +overlay[local?] +module; + private import codeql.util.Location signature module BoundDefinitions { From 5fb75ac9878cf9fd59cffa267520979dc6fce0da Mon Sep 17 00:00:00 2001 From: yoff Date: Mon, 1 Jun 2026 14:04:43 +0000 Subject: [PATCH 171/226] Python: simplify decorator-detection predicates to pure AST match MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The internal predicates that identify `@staticmethod`, `@classmethod` and `@property` decorators previously required the decorator's `NameNode` to satisfy `isGlobal()` (i.e. no SSA def reaches the decorator's name use). That filter was correct but unnecessarily indirect: these three names are builtins, and even when a class body redefines one, the class body has not started executing at the decorator position, so Python uses the builtin. Match the decorator's AST `Name` directly instead, dropping the CFG/SSA detour. The slight semantic change — `isGlobal()` would have rejected module-level shadowing of these builtins — is negligible in practice and explicitly documented in the change note. `hasContextmanagerDecorator` and `hasOverloadDecorator` keep the `NameNode.isGlobal()` check because their target names (`contextmanager`, `overload`) are imported, not builtin, and local shadowing is a real concern. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...6-01-decorator-predicate-simplification.md | 4 ++++ .../new/internal/DataFlowDispatch.qll | 20 ++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 python/ql/lib/change-notes/2026-06-01-decorator-predicate-simplification.md diff --git a/python/ql/lib/change-notes/2026-06-01-decorator-predicate-simplification.md b/python/ql/lib/change-notes/2026-06-01-decorator-predicate-simplification.md new file mode 100644 index 00000000000..44ee5b5ff80 --- /dev/null +++ b/python/ql/lib/change-notes/2026-06-01-decorator-predicate-simplification.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Simplified the internal predicates that detect `@staticmethod`, `@classmethod` and `@property` decorators to match the decorator's AST `Name` directly, rather than going through the CFG and requiring the name to resolve globally. Code that shadows these three builtin decorators at the module-scope will now be classified by the decorator name alone; in practice, shadowing these names is extremely rare and the call-graph results are unchanged. diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 1db6c08f5f4..4e3a011e8d1 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -256,9 +256,12 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { */ overlay[local] predicate isStaticmethod(Function func) { - exists(NameNode id | id.getId() = "staticmethod" and id.isGlobal() | - func.getADecorator() = id.getNode() - ) + // The decorator is *syntactically* a `Name` "staticmethod" — we don't + // care which variable it resolves to. `staticmethod` is a builtin and + // is almost never shadowed in a module-level scope; even if a class + // redefines `staticmethod` in its body, the class body has not started + // executing yet at the decorator position, so Python uses the builtin. + func.getADecorator().(Name).getId() = "staticmethod" } /** @@ -268,9 +271,9 @@ predicate isStaticmethod(Function func) { */ overlay[local] predicate isClassmethod(Function func) { - exists(NameNode id | id.getId() = "classmethod" and id.isGlobal() | - func.getADecorator() = id.getNode() - ) + // See `isStaticmethod` for the rationale for matching on the AST `Name` + // rather than going via the CFG and `isGlobal()`. + func.getADecorator().(Name).getId() = "classmethod" or exists(Class cls | cls.getAMethod() = func and @@ -285,9 +288,8 @@ predicate isClassmethod(Function func) { /** Holds if the function `func` has a `property` decorator. */ overlay[local] predicate hasPropertyDecorator(Function func) { - exists(NameNode id | id.getId() = "property" and id.isGlobal() | - func.getADecorator() = id.getNode() - ) + // See `isStaticmethod` for the rationale for matching on the AST `Name`. + func.getADecorator().(Name).getId() = "property" } /** From fa63dad1d16874e3ee478763cdcf360fa42e096b Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Mon, 1 Jun 2026 18:16:51 +0200 Subject: [PATCH 172/226] change note --- shared/rangeanalysis/change-notes/released/1.0.52.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 shared/rangeanalysis/change-notes/released/1.0.52.md diff --git a/shared/rangeanalysis/change-notes/released/1.0.52.md b/shared/rangeanalysis/change-notes/released/1.0.52.md new file mode 100644 index 00000000000..a91f5a8025d --- /dev/null +++ b/shared/rangeanalysis/change-notes/released/1.0.52.md @@ -0,0 +1,3 @@ +## 1.0.52 + +No user-facing changes. From c610af88d3518b858bb74e16d396147f0af31b0e Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Mon, 1 Jun 2026 18:18:37 +0200 Subject: [PATCH 173/226] fix comment and add overlay[local?] --- .../csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll index 9d36d6a81b5..cbf395c24f4 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll @@ -1,6 +1,8 @@ /** * Provides C#-specific definitions for bounds. */ +overlay[local?] +module; private import csharp as CS private import semmle.code.csharp.dataflow.SSA::Ssa as Ssa @@ -9,7 +11,7 @@ private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU private import codeql.rangeanalysis.Bound as SharedBound -/** Holds if `e` is a bound expression and it is not an SSA variable read. */ +/** Provides C#-specific definitions for bounds. */ module BoundDefs implements SharedBound::BoundDefinitions { class Type = CS::Type; From 2a3cff382c4ffa044637d601a1e5946dd05ab87a Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Mon, 1 Jun 2026 18:20:50 +0200 Subject: [PATCH 174/226] more specific comment --- shared/rangeanalysis/codeql/rangeanalysis/Bound.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll index 13a3132c283..a39871000d9 100644 --- a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll +++ b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll @@ -38,7 +38,9 @@ signature module BoundDefinitions { predicate interestingExprBound(Expr e); } -/** Provides classes for representing abstract bounds for use in, for example, range analysis. */ +/** Provides classes for representing abstract bounds for use in, for example, range analysis. + * This is a generic implementation of bounds that relies on language specific modules to provide language-specific definitions of expressions, SSA variables, etc. +*/ overlay[local?] module Bound Defs> { private import Defs From 8d099cbe3833c5d4222cfe5717a7341e3f6823d8 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 13 Jun 2024 19:39:22 +0100 Subject: [PATCH 175/226] Recognize more non-returning logging functions --- go/ql/lib/semmle/go/Concepts.qll | 31 ++++++++++++------- go/ql/lib/semmle/go/frameworks/Logrus.qll | 6 ++++ go/ql/lib/semmle/go/frameworks/Zap.qll | 4 +-- go/ql/lib/semmle/go/frameworks/stdlib/Log.qll | 10 ++++-- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/go/ql/lib/semmle/go/Concepts.qll b/go/ql/lib/semmle/go/Concepts.qll index c33fb0ae6bb..f511bb8ac8d 100644 --- a/go/ql/lib/semmle/go/Concepts.qll +++ b/go/ql/lib/semmle/go/Concepts.qll @@ -413,17 +413,13 @@ private class ExternalLoggerCall extends LoggerCall::Range, DataFlow::CallNode { } } -/** - * A call to an interface that looks like a logger. It is common to use a - * locally-defined interface for logging to make it easy to changing logging - * library. - */ -private class HeuristicLoggerCall extends LoggerCall::Range, DataFlow::CallNode { - HeuristicLoggerCall() { - exists(Method m, string tp, string logFunctionPrefix, string name | - m = this.getTarget() and - m.hasQualifiedName(_, tp, name) and - m.getReceiverBaseType().getUnderlyingType() instanceof InterfaceType +private class HeuristicLoggerFunction extends Method { + string logFunctionPrefix; + + HeuristicLoggerFunction() { + exists(string tp, string name | + this.hasQualifiedName(_, tp, name) and + this.getReceiverBaseType().getUnderlyingType() instanceof InterfaceType | tp.regexpMatch(".*[lL]ogger") and logFunctionPrefix = @@ -435,6 +431,19 @@ private class HeuristicLoggerCall extends LoggerCall::Range, DataFlow::CallNode ) } + override predicate mayReturnNormally() { logFunctionPrefix != "Fatal" } + + override predicate mustPanic() { logFunctionPrefix = "Panic" } +} + +/** + * A call to an interface that looks like a logger. It is common to use a + * locally-defined interface for logging to make it easy to changing logging + * library. + */ +private class HeuristicLoggerCall extends LoggerCall::Range, DataFlow::CallNode { + HeuristicLoggerCall() { this.getTarget() instanceof HeuristicLoggerFunction } + override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() } } diff --git a/go/ql/lib/semmle/go/frameworks/Logrus.qll b/go/ql/lib/semmle/go/frameworks/Logrus.qll index 33287462c05..069764318d5 100644 --- a/go/ql/lib/semmle/go/frameworks/Logrus.qll +++ b/go/ql/lib/semmle/go/frameworks/Logrus.qll @@ -28,6 +28,12 @@ module Logrus { this.(Method).hasQualifiedName(packagePath(), ["Entry", "Logger"], name) ) } + + override predicate mayReturnNormally() { + not exists(string level, string suffix | level = ["Fatal", "Panic"] | + this.getName() = level + suffix + ) + } } private class StringFormatters extends StringOps::Formatting::Range instanceof LogFunction { diff --git a/go/ql/lib/semmle/go/frameworks/Zap.qll b/go/ql/lib/semmle/go/frameworks/Zap.qll index b634d8e9795..cf0abcd9336 100644 --- a/go/ql/lib/semmle/go/frameworks/Zap.qll +++ b/go/ql/lib/semmle/go/frameworks/Zap.qll @@ -47,7 +47,7 @@ module Zap { } /** A Zap logging function which always panics. */ - private class FatalLogMethod extends Method { + private class FatalLogMethod extends ZapFunction { FatalLogMethod() { this.hasQualifiedName(packagePath(), "Logger", "Fatal") or @@ -58,7 +58,7 @@ module Zap { } /** A Zap logging function which always panics. */ - private class MustPanicLogMethod extends Method { + private class MustPanicLogMethod extends ZapFunction { MustPanicLogMethod() { this.hasQualifiedName(packagePath(), "Logger", "Panic") or diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll index a5ebca68be5..390258591a9 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll @@ -29,14 +29,20 @@ module Log { } private class LogFormatter extends StringOps::Formatting::Range instanceof LogFunction { - LogFormatter() { this.getName() = ["Fatalf", "Panicf", "Printf"] } + LogFormatter() { this.getName() = ["Fatalf", "Panicf", "Printf", "Panic", "Panicf", "Panicln"] } override int getFormatStringIndex() { result = 0 } } /** A fatal log function, which calls `os.Exit`. */ private class FatalLogFunction extends Function { - FatalLogFunction() { this.hasQualifiedName("log", ["Fatal", "Fatalf", "Fatalln"]) } + FatalLogFunction() { + exists(string fn | fn = ["Fatal", "Fatalf", "Fatalln"] | + this.hasQualifiedName("log", fn) + or + this.(Method).hasQualifiedName("log", "Logger", fn) + ) + } override predicate mayReturnNormally() { none() } } From f3e3647209b009571e608e9f9202e685c6e09f9e Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Sun, 31 May 2026 09:08:51 +0100 Subject: [PATCH 176/226] Improve noretFunctions test --- .../ControlFlowGraph/NoretFunctions.expected | 26 +++++++++++-------- .../ControlFlowGraph/NoretFunctions.ql | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.expected b/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.expected index abd09c52976..9955274a4e0 100644 --- a/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.expected +++ b/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.expected @@ -1,11 +1,15 @@ -| file://:0:0:0:0 | Exit | package os | -| file://:0:0:0:0 | Fatal | package log | -| file://:0:0:0:0 | Fatalf | package log | -| file://:0:0:0:0 | Fatalln | package log | -| noretfunctions.go:8:6:8:12 | isNoRet | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph | -| noretfunctions.go:20:6:20:22 | noRetUsesLogFatal | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph | -| noretfunctions.go:24:6:24:23 | noRetUsesLogFatalf | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph | -| stmts7.go:10:6:10:15 | canRecover | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph | -| stmts.go:10:6:10:10 | test5 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph | -| stmts.go:46:6:46:10 | test6 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph | -| stmts.go:112:6:112:10 | test9 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph | +| file://:0:0:0:0 | Exit | os.Exit | +| file://:0:0:0:0 | Fatal | log.Fatal | +| file://:0:0:0:0 | Fatal | log.Logger.Fatal | +| file://:0:0:0:0 | Fatalf | log.Fatalf | +| file://:0:0:0:0 | Fatalf | log.Logger.Fatalf | +| file://:0:0:0:0 | Fatalln | log.Fatalln | +| file://:0:0:0:0 | Fatalln | log.Logger.Fatalln | +| file://:0:0:0:0 | panic | panic | +| noretfunctions.go:8:6:8:12 | isNoRet | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.isNoRet | +| noretfunctions.go:20:6:20:22 | noRetUsesLogFatal | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.noRetUsesLogFatal | +| noretfunctions.go:24:6:24:23 | noRetUsesLogFatalf | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.noRetUsesLogFatalf | +| stmts7.go:10:6:10:15 | canRecover | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.canRecover | +| stmts.go:10:6:10:10 | test5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test5 | +| stmts.go:46:6:46:10 | test6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test6 | +| stmts.go:112:6:112:10 | test9 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test9 | diff --git a/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.ql b/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.ql index b61493abb9f..b525004752f 100644 --- a/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.ql +++ b/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.ql @@ -2,4 +2,4 @@ import go from Function f where not f.mayReturnNormally() -select f, f.getPackage() +select f, f.getQualifiedName() From c99dab1d719a0f7d003e12ce8d0469b09b30da16 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Sun, 31 May 2026 09:09:08 +0100 Subject: [PATCH 177/226] Improve glog (and klog) modelling --- go/ql/lib/semmle/go/frameworks/Glog.qll | 33 +++++++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/go/ql/lib/semmle/go/frameworks/Glog.qll b/go/ql/lib/semmle/go/frameworks/Glog.qll index a9ffc432181..8883e47e686 100644 --- a/go/ql/lib/semmle/go/frameworks/Glog.qll +++ b/go/ql/lib/semmle/go/frameworks/Glog.qll @@ -12,17 +12,36 @@ import go * forks. */ module Glog { + string packagePath() { + result = + package([ + "github.com/golang/glog", "gopkg.in/glog", "k8s.io/klog", "github.com/barakmich/glog" + ], "") + } + private class GlogFunction extends Function { int firstPrintedArg; + string format; + string level; GlogFunction() { - exists(string pkg, string fn, string level | - pkg = package(["github.com/golang/glog", "gopkg.in/glog", "k8s.io/klog"], "") and + exists(string pkg, string context, int nContextArgs, string depth, int nDepthArgs, string fn | + pkg = packagePath() and level = ["Error", "Exit", "Fatal", "Info", "Warning"] and ( - fn = level + ["", "f", "ln"] and firstPrintedArg = 0 + context = "" and nContextArgs = 0 or - fn = level + "Depth" and firstPrintedArg = 1 + context = "Context" and nContextArgs = 1 + ) and + ( + depth = "" and nDepthArgs = 0 + or + depth = "Depth" and nDepthArgs = 1 + ) and + format = ["", "f", "ln"] and + ( + fn = level + context + depth + format and + firstPrintedArg = nContextArgs + nDepthArgs ) | this.hasQualifiedName(pkg, fn) @@ -35,10 +54,14 @@ module Glog { * Gets the index of the first argument that may be output, including a format string if one is present. */ int getFirstPrintedArg() { result = firstPrintedArg } + + predicate formatter() { format = "f" } + + override predicate mayReturnNormally() { level != "Fatal" and level != "Exit" } } private class StringFormatter extends StringOps::Formatting::Range instanceof GlogFunction { - StringFormatter() { this.getName().matches("%f") } + StringFormatter() { this.formatter() } override int getFormatStringIndex() { result = super.getFirstPrintedArg() } } From 45b1253b2396880fecb382fea7febec59c72e694 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Mon, 1 Jun 2026 23:44:40 +0100 Subject: [PATCH 178/226] Improve glog and klog tests --- .../semmle/go/concepts/LoggerCall/glog.go | 225 ++++++++++++++---- .../semmle/go/concepts/LoggerCall/go.mod | 2 +- .../semmle/go/concepts/LoggerCall/main.go | 1 + .../vendor/github.com/golang/glog/stub.go | 80 ++++++- .../LoggerCall/vendor/k8s.io/klog/stub.go | 14 +- .../go/concepts/LoggerCall/vendor/modules.txt | 2 +- 6 files changed, 275 insertions(+), 49 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/glog.go b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/glog.go index ab82527b5e0..25c245948f3 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/glog.go +++ b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/glog.go @@ -1,54 +1,181 @@ -//go:generate depstubber -vendor github.com/golang/glog "" Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,Warning,WarningDepth,Warningf,Warningln -//go:generate depstubber -vendor k8s.io/klog "" Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,Warning,WarningDepth,Warningf,Warningln +//go:generate depstubber -vendor github.com/golang/glog Level,Verbose Error,ErrorContext,ErrorContextDepth,ErrorContextDepthf,ErrorContextf,ErrorDepth,ErrorDepthf,Errorf,Errorln,Exit,ExitContext,ExitContextDepth,ExitContextDepthf,ExitContextf,ExitDepth,ExitDepthf,Exitf,Exitln,Fatal,FatalContext,FatalContextDepth,FatalContextDepthf,FatalContextf,FatalDepth,FatalDepthf,Fatalf,Fatalln,Info,InfoContext,InfoContextDepth,InfoContextDepthf,InfoContextf,InfoDepth,InfoDepthf,Infof,Infoln,V,VDepth,Warning,WarningContext,WarningContextDepth,WarningContextDepthf,WarningContextf,WarningDepth,WarningDepthf,Warningf,Warningln +//go:generate depstubber -vendor k8s.io/klog Level,Verbose Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,V,Warning,WarningDepth,Warningf,Warningln package main import ( + "context" + "github.com/golang/glog" "k8s.io/klog" ) -func glogTest() { - glog.Error(text) // $ logger=text - glog.ErrorDepth(0, text) // $ logger=text - glog.Errorf(fmt, text) // $ logger=fmt logger=text - glog.Errorln(text) // $ logger=text - glog.Exit(text) // $ logger=text - glog.ExitDepth(0, text) // $ logger=text - glog.Exitf(fmt, text) // $ logger=fmt logger=text - glog.Exitln(text) // $ logger=text - glog.Fatal(text) // $ logger=text - glog.FatalDepth(0, text) // $ logger=text - glog.Fatalf(fmt, text) // $ logger=fmt logger=text - glog.Fatalln(text) // $ logger=text - glog.Info(text) // $ logger=text - glog.InfoDepth(0, text) // $ logger=text - glog.Infof(fmt, text) // $ logger=fmt logger=text - glog.Infoln(text) // $ logger=text - glog.Warning(text) // $ logger=text - glog.WarningDepth(0, text) // $ logger=text - glog.Warningf(fmt, text) // $ logger=fmt logger=text - glog.Warningln(text) // $ logger=text +func glogTest(selector int) { + ctx := context.Background() + + glog.Error(text) // $ logger=text + glog.ErrorContext(ctx, text) // $ logger=text + glog.ErrorContextDepth(ctx, 0, text) // $ logger=text + glog.ErrorContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text + glog.ErrorContextf(ctx, fmt, text) // $ logger=fmt logger=text + glog.ErrorDepth(0, text) // $ logger=text + glog.ErrorDepthf(0, fmt, text) // $ logger=fmt logger=text + glog.Errorf(fmt, text) // $ logger=fmt logger=text + glog.Errorln(text) // $ logger=text + if selector == 1 { + glog.Exit(text) // $ logger=text + } + if selector == 2 { + glog.ExitContext(ctx, text) // $ logger=text + } + if selector == 3 { + glog.ExitContextDepth(ctx, 0, text) // $ logger=text + } + if selector == 4 { + glog.ExitContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text + } + if selector == 5 { + glog.ExitContextf(ctx, fmt, text) // $ logger=fmt logger=text + } + if selector == 6 { + glog.ExitDepth(0, text) // $ logger=text + } + if selector == 7 { + glog.ExitDepthf(0, fmt, text) // $ logger=fmt logger=text + } + if selector == 8 { + glog.Exitf(fmt, text) // $ logger=fmt logger=text + } + if selector == 9 { + glog.Exitln(text) // $ logger=text + } + if selector == 10 { + glog.Fatal(text) // $ logger=text + } + if selector == 11 { + glog.FatalContext(ctx, text) // $ logger=text + } + if selector == 12 { + glog.FatalContextDepth(ctx, 0, text) // $ logger=text + } + if selector == 13 { + glog.FatalContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text + } + if selector == 14 { + glog.FatalContextf(ctx, fmt, text) // $ logger=fmt logger=text + } + if selector == 15 { + glog.FatalDepth(0, text) // $ logger=text + } + if selector == 16 { + glog.FatalDepthf(0, fmt, text) // $ logger=fmt logger=text + } + if selector == 17 { + glog.Fatalf(fmt, text) // $ logger=fmt logger=text + } + if selector == 18 { + glog.Fatalln(text) // $ logger=text + } + glog.Info(text) // $ logger=text + glog.InfoContext(ctx, text) // $ logger=text + glog.InfoContextDepth(ctx, 0, text) // $ logger=text + glog.InfoContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text + glog.InfoContextf(ctx, fmt, text) // $ logger=fmt logger=text + glog.InfoDepth(0, text) // $ logger=text + glog.InfoDepthf(0, fmt, text) // $ logger=fmt logger=text + glog.Infof(fmt, text) // $ logger=fmt logger=text + glog.Infoln(text) // $ logger=text + glog.Warning(text) // $ logger=text + glog.WarningContext(ctx, text) // $ logger=text + glog.WarningContextDepth(ctx, 0, text) // $ logger=text + glog.WarningContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text + glog.WarningContextf(ctx, fmt, text) // $ logger=fmt logger=text + glog.WarningDepth(0, text) // $ logger=text + glog.WarningDepthf(0, fmt, text) // $ logger=fmt logger=text + glog.Warningf(fmt, text) // $ logger=fmt logger=text + glog.Warningln(text) // $ logger=text + + glog.V(0).Info(text) // $ logger=text + glog.V(0).InfoContext(ctx, text) // $ logger=text + glog.V(0).InfoContextDepth(ctx, 0, text) // $ logger=text + glog.V(0).InfoContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text + glog.V(0).InfoContextf(ctx, fmt, text) // $ logger=fmt logger=text + glog.V(0).InfoDepth(0, text) // $ logger=text + glog.V(0).InfoDepthf(0, fmt, text) // $ logger=fmt logger=text + glog.V(0).Infof(fmt, text) // $ logger=fmt logger=text + glog.V(0).Infoln(text) // $ logger=text + glog.VDepth(0, 0).Info(text) // $ logger=text // components corresponding to the format specifier "%T" are not considered vulnerable - glog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v - glog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v - glog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v - glog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v - glog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.ErrorContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.ErrorContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.ErrorDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + if selector == 19 { + glog.ExitContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + if selector == 20 { + glog.ExitContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + if selector == 21 { + glog.ExitDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + if selector == 22 { + glog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + if selector == 23 { + glog.FatalContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + if selector == 24 { + glog.FatalContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + if selector == 25 { + glog.FatalDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + if selector == 26 { + glog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + glog.InfoContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.InfoContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.InfoDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.WarningContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.WarningContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.WarningDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.V(0).InfoContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.V(0).InfoContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.V(0).InfoDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + glog.V(0).Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v - klog.Error(text) // $ logger=text - klog.ErrorDepth(0, text) // $ logger=text - klog.Errorf(fmt, text) // $ logger=fmt logger=text - klog.Errorln(text) // $ logger=text - klog.Exit(text) // $ logger=text - klog.ExitDepth(0, text) // $ logger=text - klog.Exitf(fmt, text) // $ logger=fmt logger=text - klog.Exitln(text) // $ logger=text - klog.Fatal(text) // $ logger=text - klog.FatalDepth(0, text) // $ logger=text - klog.Fatalf(fmt, text) // $ logger=fmt logger=text - klog.Fatalln(text) // $ logger=text + klog.Error(text) // $ logger=text + klog.ErrorDepth(0, text) // $ logger=text + klog.Errorf(fmt, text) // $ logger=fmt logger=text + klog.Errorln(text) // $ logger=text + if selector == 27 { + klog.Exit(text) // $ logger=text + } + if selector == 28 { + klog.ExitDepth(0, text) // $ logger=text + } + if selector == 29 { + klog.Exitf(fmt, text) // $ logger=fmt logger=text + } + if selector == 30 { + klog.Exitln(text) // $ logger=text + } + if selector == 31 { + klog.Fatal(text) // $ logger=text + } + if selector == 32 { + klog.FatalDepth(0, text) // $ logger=text + } + if selector == 33 { + klog.Fatalf(fmt, text) // $ logger=fmt logger=text + } + if selector == 34 { + klog.Fatalln(text) // $ logger=text + } klog.Info(text) // $ logger=text klog.InfoDepth(0, text) // $ logger=text klog.Infof(fmt, text) // $ logger=fmt logger=text @@ -57,11 +184,19 @@ func glogTest() { klog.WarningDepth(0, text) // $ logger=text klog.Warningf(fmt, text) // $ logger=fmt logger=text klog.Warningln(text) // $ logger=text + klog.V(0).Info(text) // $ logger=text + klog.V(0).Infof(fmt, text) // $ logger=fmt logger=text + klog.V(0).Infoln(text) // $ logger=text // components corresponding to the format specifier "%T" are not considered vulnerable - klog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v - klog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v - klog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v - klog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v - klog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + klog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + if selector == 35 { + klog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + if selector == 36 { + klog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + } + klog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + klog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v + klog.V(0).Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v } diff --git a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/go.mod b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/go.mod index 81d2785a409..0d3c053e7fe 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/go.mod +++ b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/go.mod @@ -3,7 +3,7 @@ module codeql-go-tests/concepts/loggercall go 1.15 require ( - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b + github.com/golang/glog v1.2.5 github.com/sirupsen/logrus v1.7.0 k8s.io/klog v1.0.0 ) diff --git a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/main.go b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/main.go index 5353d9155cc..688c59bc2ea 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/main.go +++ b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/main.go @@ -6,5 +6,6 @@ const text = "test" var v []byte func main() { + glogTest(len(v)) stdlib() } diff --git a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/github.com/golang/glog/stub.go b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/github.com/golang/glog/stub.go index 49f90bc21af..64a0aef2bfc 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/github.com/golang/glog/stub.go +++ b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/github.com/golang/glog/stub.go @@ -2,47 +2,125 @@ // This is a simple stub for github.com/golang/glog, strictly for use in testing. // See the LICENSE file for information about the licensing of the original library. -// Source: github.com/golang/glog (exports: ; functions: Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,Warning,WarningDepth,Warningf,Warningln) +// Source: github.com/golang/glog (exports: Level,Verbose; functions: Error,ErrorContext,ErrorContextDepth,ErrorContextDepthf,ErrorContextf,ErrorDepth,ErrorDepthf,Errorf,Errorln,Exit,ExitContext,ExitContextDepth,ExitContextDepthf,ExitContextf,ExitDepth,ExitDepthf,Exitf,Exitln,Fatal,FatalContext,FatalContextDepth,FatalContextDepthf,FatalContextf,FatalDepth,FatalDepthf,Fatalf,Fatalln,Info,InfoContext,InfoContextDepth,InfoContextDepthf,InfoContextf,InfoDepth,InfoDepthf,Infof,Infoln,V,VDepth,Warning,WarningContext,WarningContextDepth,WarningContextDepthf,WarningContextf,WarningDepth,WarningDepthf,Warningf,Warningln) // Package glog is a stub of github.com/golang/glog, generated by depstubber. package glog +import "context" + +type Level int32 + +type Verbose bool + func Error(_ ...interface{}) {} +func ErrorContext(_ context.Context, _ ...interface{}) {} + +func ErrorContextDepth(_ context.Context, _ int, _ ...interface{}) {} + +func ErrorContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {} + +func ErrorContextf(_ context.Context, _ string, _ ...interface{}) {} + func ErrorDepth(_ int, _ ...interface{}) {} +func ErrorDepthf(_ int, _ string, _ ...interface{}) {} + func Errorf(_ string, _ ...interface{}) {} func Errorln(_ ...interface{}) {} func Exit(_ ...interface{}) {} +func ExitContext(_ context.Context, _ ...interface{}) {} + +func ExitContextDepth(_ context.Context, _ int, _ ...interface{}) {} + +func ExitContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {} + +func ExitContextf(_ context.Context, _ string, _ ...interface{}) {} + func ExitDepth(_ int, _ ...interface{}) {} +func ExitDepthf(_ int, _ string, _ ...interface{}) {} + func Exitf(_ string, _ ...interface{}) {} func Exitln(_ ...interface{}) {} func Fatal(_ ...interface{}) {} +func FatalContext(_ context.Context, _ ...interface{}) {} + +func FatalContextDepth(_ context.Context, _ int, _ ...interface{}) {} + +func FatalContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {} + +func FatalContextf(_ context.Context, _ string, _ ...interface{}) {} + func FatalDepth(_ int, _ ...interface{}) {} +func FatalDepthf(_ int, _ string, _ ...interface{}) {} + func Fatalf(_ string, _ ...interface{}) {} func Fatalln(_ ...interface{}) {} func Info(_ ...interface{}) {} +func InfoContext(_ context.Context, _ ...interface{}) {} + +func InfoContextDepth(_ context.Context, _ int, _ ...interface{}) {} + +func InfoContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {} + +func InfoContextf(_ context.Context, _ string, _ ...interface{}) {} + func InfoDepth(_ int, _ ...interface{}) {} +func InfoDepthf(_ int, _ string, _ ...interface{}) {} + func Infof(_ string, _ ...interface{}) {} func Infoln(_ ...interface{}) {} +func V(_ Level) Verbose { return false } + +func VDepth(_ int, _ Level) Verbose { return false } + func Warning(_ ...interface{}) {} +func WarningContext(_ context.Context, _ ...interface{}) {} + +func WarningContextDepth(_ context.Context, _ int, _ ...interface{}) {} + +func WarningContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {} + +func WarningContextf(_ context.Context, _ string, _ ...interface{}) {} + func WarningDepth(_ int, _ ...interface{}) {} +func WarningDepthf(_ int, _ string, _ ...interface{}) {} + func Warningf(_ string, _ ...interface{}) {} func Warningln(_ ...interface{}) {} + +func (_ Verbose) Info(_ ...interface{}) {} + +func (_ Verbose) InfoContext(_ context.Context, _ ...interface{}) {} + +func (_ Verbose) InfoContextDepth(_ context.Context, _ int, _ ...interface{}) {} + +func (_ Verbose) InfoContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {} + +func (_ Verbose) InfoContextf(_ context.Context, _ string, _ ...interface{}) {} + +func (_ Verbose) InfoDepth(_ int, _ ...interface{}) {} + +func (_ Verbose) InfoDepthf(_ int, _ string, _ ...interface{}) {} + +func (_ Verbose) Infof(_ string, _ ...interface{}) {} + +func (_ Verbose) Infoln(_ ...interface{}) {} diff --git a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/k8s.io/klog/stub.go b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/k8s.io/klog/stub.go index 0c29992abcf..81eb6927c5b 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/k8s.io/klog/stub.go +++ b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/k8s.io/klog/stub.go @@ -2,11 +2,15 @@ // This is a simple stub for k8s.io/klog, strictly for use in testing. // See the LICENSE file for information about the licensing of the original library. -// Source: k8s.io/klog (exports: ; functions: Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,Warning,WarningDepth,Warningf,Warningln) +// Source: k8s.io/klog (exports: Level,Verbose; functions: Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,V,Warning,WarningDepth,Warningf,Warningln) // Package klog is a stub of k8s.io/klog, generated by depstubber. package klog +type Level int32 + +type Verbose bool + func Error(_ ...interface{}) {} func ErrorDepth(_ int, _ ...interface{}) {} @@ -39,6 +43,8 @@ func Infof(_ string, _ ...interface{}) {} func Infoln(_ ...interface{}) {} +func V(_ Level) Verbose { return false } + func Warning(_ ...interface{}) {} func WarningDepth(_ int, _ ...interface{}) {} @@ -46,3 +52,9 @@ func WarningDepth(_ int, _ ...interface{}) {} func Warningf(_ string, _ ...interface{}) {} func Warningln(_ ...interface{}) {} + +func (_ Verbose) Info(_ ...interface{}) {} + +func (_ Verbose) Infof(_ string, _ ...interface{}) {} + +func (_ Verbose) Infoln(_ ...interface{}) {} diff --git a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/modules.txt b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/modules.txt index da35ae80c08..bf162a2d5a4 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/modules.txt +++ b/go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b +# github.com/golang/glog v1.2.5 ## explicit github.com/golang/glog # github.com/sirupsen/logrus v1.7.0 From 28bb1a68708dd05c0e2199bade641fff293f7ac7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 00:15:30 +0100 Subject: [PATCH 179/226] Add change note --- go/ql/lib/change-notes/2026-06-01-non-returning-functions.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/lib/change-notes/2026-06-01-non-returning-functions.md diff --git a/go/ql/lib/change-notes/2026-06-01-non-returning-functions.md b/go/ql/lib/change-notes/2026-06-01-non-returning-functions.md new file mode 100644 index 00000000000..c48b2f32f83 --- /dev/null +++ b/go/ql/lib/change-notes/2026-06-01-non-returning-functions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* More logging functions are now recognized as not returning or panicking. From 1a747dd8be406829691a3a4b50fffa6794cf27a0 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 00:39:25 +0100 Subject: [PATCH 180/226] (Trivial) Fix QLDoc grammar --- go/ql/lib/semmle/go/Concepts.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/lib/semmle/go/Concepts.qll b/go/ql/lib/semmle/go/Concepts.qll index f511bb8ac8d..30214914952 100644 --- a/go/ql/lib/semmle/go/Concepts.qll +++ b/go/ql/lib/semmle/go/Concepts.qll @@ -438,7 +438,7 @@ private class HeuristicLoggerFunction extends Method { /** * A call to an interface that looks like a logger. It is common to use a - * locally-defined interface for logging to make it easy to changing logging + * locally-defined interface for logging to make it easy to change logging * library. */ private class HeuristicLoggerCall extends LoggerCall::Range, DataFlow::CallNode { From 8a1e6d4f64430230c3ae897ba22f6b7f3d17b40a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 00:41:48 +0100 Subject: [PATCH 181/226] Add missing QLDocs --- go/ql/lib/semmle/go/frameworks/Glog.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go/ql/lib/semmle/go/frameworks/Glog.qll b/go/ql/lib/semmle/go/frameworks/Glog.qll index 8883e47e686..9715cc91073 100644 --- a/go/ql/lib/semmle/go/frameworks/Glog.qll +++ b/go/ql/lib/semmle/go/frameworks/Glog.qll @@ -12,6 +12,7 @@ import go * forks. */ module Glog { + /** Gets a package name for `glog` or `klog` (which is a fork). */ string packagePath() { result = package([ @@ -55,6 +56,7 @@ module Glog { */ int getFirstPrintedArg() { result = firstPrintedArg } + /** Holds if this function takes a format string. */ predicate formatter() { format = "f" } override predicate mayReturnNormally() { level != "Fatal" and level != "Exit" } From e706c5f444b4632cd0b7208660c064f053ada026 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 00:56:12 +0100 Subject: [PATCH 182/226] Improve test for non-returning fns --- .../Security/CWE-117/LogInjection.go | 396 +++++++++++------- 1 file changed, 250 insertions(+), 146 deletions(-) diff --git a/go/ql/test/query-tests/Security/CWE-117/LogInjection.go b/go/ql/test/query-tests/Security/CWE-117/LogInjection.go index fc9d7179158..fbd3b4a0610 100644 --- a/go/ql/test/query-tests/Security/CWE-117/LogInjection.go +++ b/go/ql/test/query-tests/Security/CWE-117/LogInjection.go @@ -49,22 +49,22 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { log.Printf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password" log.Println("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" - if testFlag == "true" { + if testFlag == "1" { log.Fatal("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" } - if testFlag == "true" { + if testFlag == "2" { log.Fatalf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password" } - if testFlag == "true" { + if testFlag == "3" { log.Fatalln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" } - if testFlag == "true" { + if testFlag == "4" { log.Panic("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" } - if testFlag == "true" { + if testFlag == "5" { log.Panicf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password" } - if testFlag == "true" { + if testFlag == "6" { log.Panicln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" } @@ -72,12 +72,24 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { logger.Print("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" logger.Printf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password" logger.Println("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" - logger.Fatal("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" - logger.Fatalf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password" - logger.Fatalln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" - logger.Panic("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" - logger.Panicf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password" - logger.Panicln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" + if testFlag == "7" { + logger.Fatal("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" + } + if testFlag == "8" { + logger.Fatalf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password" + } + if testFlag == "9" { + logger.Fatalln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" + } + if testFlag == "10" { + logger.Panic("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" + } + if testFlag == "11" { + logger.Panicf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password" + } + if testFlag == "12" { + logger.Panicln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password" + } } // k8s.io/klog { @@ -91,12 +103,24 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { klog.Error(username) // $ hasTaintFlow="username" klog.Errorf(username) // $ hasTaintFlow="username" klog.Errorln(username) // $ hasTaintFlow="username" - klog.Fatal(username) // $ hasTaintFlow="username" - klog.Fatalf(username) // $ hasTaintFlow="username" - klog.Fatalln(username) // $ hasTaintFlow="username" - klog.Exit(username) // $ hasTaintFlow="username" - klog.Exitf(username) // $ hasTaintFlow="username" - klog.Exitln(username) // $ hasTaintFlow="username" + if testFlag == "77" { + klog.Fatal(username) // $ hasTaintFlow="username" + } + if testFlag == "78" { + klog.Fatalf(username) // $ hasTaintFlow="username" + } + if testFlag == "79" { + klog.Fatalln(username) // $ hasTaintFlow="username" + } + if testFlag == "80" { + klog.Exit(username) // $ hasTaintFlow="username" + } + if testFlag == "81" { + klog.Exitf(username) // $ hasTaintFlow="username" + } + if testFlag == "82" { + klog.Exitln(username) // $ hasTaintFlow="username" + } } // astaxie/beego { @@ -161,14 +185,30 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { glog.ErrorDepth(0, username) // $ hasTaintFlow="username" glog.Errorf(username) // $ hasTaintFlow="username" glog.Errorln(username) // $ hasTaintFlow="username" - glog.Fatal(username) // $ hasTaintFlow="username" - glog.FatalDepth(0, username) // $ hasTaintFlow="username" - glog.Fatalf(username) // $ hasTaintFlow="username" - glog.Fatalln(username) // $ hasTaintFlow="username" - glog.Exit(username) // $ hasTaintFlow="username" - glog.ExitDepth(0, username) // $ hasTaintFlow="username" - glog.Exitf(username) // $ hasTaintFlow="username" - glog.Exitln(username) // $ hasTaintFlow="username" + if testFlag == "83" { + glog.Fatal(username) // $ hasTaintFlow="username" + } + if testFlag == "84" { + glog.FatalDepth(0, username) // $ hasTaintFlow="username" + } + if testFlag == "85" { + glog.Fatalf(username) // $ hasTaintFlow="username" + } + if testFlag == "86" { + glog.Fatalln(username) // $ hasTaintFlow="username" + } + if testFlag == "87" { + glog.Exit(username) // $ hasTaintFlow="username" + } + if testFlag == "88" { + glog.ExitDepth(0, username) // $ hasTaintFlow="username" + } + if testFlag == "89" { + glog.Exitf(username) // $ hasTaintFlow="username" + } + if testFlag == "90" { + glog.Exitln(username) // $ hasTaintFlow="username" + } } // sirupsen/logrus @@ -179,26 +219,42 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { logger := logrus.New() entry := logrus.NewEntry(logger) - logrus.Debug(username) // $ hasTaintFlow="username" - logrus.Debugf(username, "") // $ hasTaintFlow="username" - logrus.Debugf("", username) // $ hasTaintFlow="username" - logrus.Debugln(username) // $ hasTaintFlow="username" - logrus.Error(username) // $ hasTaintFlow="username" - logrus.Errorf(username, "") // $ hasTaintFlow="username" - logrus.Errorf("", username) // $ hasTaintFlow="username" - logrus.Errorln(username) // $ hasTaintFlow="username" - logrus.Fatal(username) // $ hasTaintFlow="username" - logrus.Fatalf(username, "") // $ hasTaintFlow="username" - logrus.Fatalf("", username) // $ hasTaintFlow="username" - logrus.Fatalln(username) // $ hasTaintFlow="username" - logrus.Info(username) // $ hasTaintFlow="username" - logrus.Infof(username, "") // $ hasTaintFlow="username" - logrus.Infof("", username) // $ hasTaintFlow="username" - logrus.Infoln(username) // $ hasTaintFlow="username" - logrus.Panic(username) // $ hasTaintFlow="username" - logrus.Panicf(username, "") // $ hasTaintFlow="username" - logrus.Panicf("", username) // $ hasTaintFlow="username" - logrus.Panicln(username) // $ hasTaintFlow="username" + logrus.Debug(username) // $ hasTaintFlow="username" + logrus.Debugf(username, "") // $ hasTaintFlow="username" + logrus.Debugf("", username) // $ hasTaintFlow="username" + logrus.Debugln(username) // $ hasTaintFlow="username" + logrus.Error(username) // $ hasTaintFlow="username" + logrus.Errorf(username, "") // $ hasTaintFlow="username" + logrus.Errorf("", username) // $ hasTaintFlow="username" + logrus.Errorln(username) // $ hasTaintFlow="username" + if testFlag == "13" { + logrus.Fatal(username) // $ hasTaintFlow="username" + } + if testFlag == "14" { + logrus.Fatalf(username, "") // $ hasTaintFlow="username" + } + if testFlag == "15" { + logrus.Fatalf("", username) // $ hasTaintFlow="username" + } + if testFlag == "16" { + logrus.Fatalln(username) // $ hasTaintFlow="username" + } + logrus.Info(username) // $ hasTaintFlow="username" + logrus.Infof(username, "") // $ hasTaintFlow="username" + logrus.Infof("", username) // $ hasTaintFlow="username" + logrus.Infoln(username) // $ hasTaintFlow="username" + if testFlag == "17" { + logrus.Panic(username) // $ hasTaintFlow="username" + } + if testFlag == "18" { + logrus.Panicf(username, "") // $ hasTaintFlow="username" + } + if testFlag == "19" { + logrus.Panicf("", username) // $ hasTaintFlow="username" + } + if testFlag == "20" { + logrus.Panicln(username) // $ hasTaintFlow="username" + } logrus.Print(username) // $ hasTaintFlow="username" logrus.Printf(username, "") // $ hasTaintFlow="username" logrus.Printf("", username) // $ hasTaintFlow="username" @@ -220,30 +276,46 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { logrus.WithField("", username) // $ hasTaintFlow="username" logrus.WithFields(fields) // $ hasTaintFlow="fields" - entry.Debug(username) // $ hasTaintFlow="username" - entry.Debugf(username, "") // $ hasTaintFlow="username" - entry.Debugf("", username) // $ hasTaintFlow="username" - entry.Debugln(username) // $ hasTaintFlow="username" - entry.Error(username) // $ hasTaintFlow="username" - entry.Errorf(username, "") // $ hasTaintFlow="username" - entry.Errorf("", username) // $ hasTaintFlow="username" - entry.Errorln(username) // $ hasTaintFlow="username" - entry.Fatal(username) // $ hasTaintFlow="username" - entry.Fatalf(username, "") // $ hasTaintFlow="username" - entry.Fatalf("", username) // $ hasTaintFlow="username" - entry.Fatalln(username) // $ hasTaintFlow="username" - entry.Info(username) // $ hasTaintFlow="username" - entry.Infof(username, "") // $ hasTaintFlow="username" - entry.Infof("", username) // $ hasTaintFlow="username" - entry.Infoln(username) // $ hasTaintFlow="username" - entry.Log(0, username) // $ hasTaintFlow="username" - entry.Logf(0, username, "") // $ hasTaintFlow="username" - entry.Logf(0, "", username) // $ hasTaintFlow="username" - entry.Logln(0, username) // $ hasTaintFlow="username" - entry.Panic(username) // $ hasTaintFlow="username" - entry.Panicf(username, "") // $ hasTaintFlow="username" - entry.Panicf("", username) // $ hasTaintFlow="username" - entry.Panicln(username) // $ hasTaintFlow="username" + entry.Debug(username) // $ hasTaintFlow="username" + entry.Debugf(username, "") // $ hasTaintFlow="username" + entry.Debugf("", username) // $ hasTaintFlow="username" + entry.Debugln(username) // $ hasTaintFlow="username" + entry.Error(username) // $ hasTaintFlow="username" + entry.Errorf(username, "") // $ hasTaintFlow="username" + entry.Errorf("", username) // $ hasTaintFlow="username" + entry.Errorln(username) // $ hasTaintFlow="username" + if testFlag == "21" { + entry.Fatal(username) // $ hasTaintFlow="username" + } + if testFlag == "22" { + entry.Fatalf(username, "") // $ hasTaintFlow="username" + } + if testFlag == "23" { + entry.Fatalf("", username) // $ hasTaintFlow="username" + } + if testFlag == "24" { + entry.Fatalln(username) // $ hasTaintFlow="username" + } + entry.Info(username) // $ hasTaintFlow="username" + entry.Infof(username, "") // $ hasTaintFlow="username" + entry.Infof("", username) // $ hasTaintFlow="username" + entry.Infoln(username) // $ hasTaintFlow="username" + entry.Log(0, username) // $ hasTaintFlow="username" + entry.Logf(0, username, "") // $ hasTaintFlow="username" + entry.Logf(0, "", username) // $ hasTaintFlow="username" + entry.Logln(0, username) // $ hasTaintFlow="username" + if testFlag == "25" { + entry.Panic(username) // $ hasTaintFlow="username" + } + if testFlag == "26" { + entry.Panicf(username, "") // $ hasTaintFlow="username" + } + if testFlag == "27" { + entry.Panicf("", username) // $ hasTaintFlow="username" + } + if testFlag == "28" { + entry.Panicln(username) // $ hasTaintFlow="username" + } entry.Print(username) // $ hasTaintFlow="username" entry.Printf(username, "") // $ hasTaintFlow="username" entry.Printf("", username) // $ hasTaintFlow="username" @@ -265,30 +337,46 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { entry.WithField("", username) // $ hasTaintFlow="username" entry.WithFields(fields) // $ hasTaintFlow="fields" - logger.Debug(username) // $ hasTaintFlow="username" - logger.Debugf(username, "") // $ hasTaintFlow="username" - logger.Debugf("", username) // $ hasTaintFlow="username" - logger.Debugln(username) // $ hasTaintFlow="username" - logger.Error(username) // $ hasTaintFlow="username" - logger.Errorf(username, "") // $ hasTaintFlow="username" - logger.Errorf("", username) // $ hasTaintFlow="username" - logger.Errorln(username) // $ hasTaintFlow="username" - logger.Fatal(username) // $ hasTaintFlow="username" - logger.Fatalf(username, "") // $ hasTaintFlow="username" - logger.Fatalf("", username) // $ hasTaintFlow="username" - logger.Fatalln(username) // $ hasTaintFlow="username" - logger.Info(username) // $ hasTaintFlow="username" - logger.Infof(username, "") // $ hasTaintFlow="username" - logger.Infof("", username) // $ hasTaintFlow="username" - logger.Infoln(username) // $ hasTaintFlow="username" - logger.Log(0, username) // $ hasTaintFlow="username" - logger.Logf(0, username, "") // $ hasTaintFlow="username" - logger.Logf(0, "", username) // $ hasTaintFlow="username" - logger.Logln(0, username) // $ hasTaintFlow="username" - logger.Panic(username) // $ hasTaintFlow="username" - logger.Panicf(username, "") // $ hasTaintFlow="username" - logger.Panicf("", username) // $ hasTaintFlow="username" - logger.Panicln(username) // $ hasTaintFlow="username" + logger.Debug(username) // $ hasTaintFlow="username" + logger.Debugf(username, "") // $ hasTaintFlow="username" + logger.Debugf("", username) // $ hasTaintFlow="username" + logger.Debugln(username) // $ hasTaintFlow="username" + logger.Error(username) // $ hasTaintFlow="username" + logger.Errorf(username, "") // $ hasTaintFlow="username" + logger.Errorf("", username) // $ hasTaintFlow="username" + logger.Errorln(username) // $ hasTaintFlow="username" + if testFlag == "29" { + logger.Fatal(username) // $ hasTaintFlow="username" + } + if testFlag == "30" { + logger.Fatalf(username, "") // $ hasTaintFlow="username" + } + if testFlag == "31" { + logger.Fatalf("", username) // $ hasTaintFlow="username" + } + if testFlag == "32" { + logger.Fatalln(username) // $ hasTaintFlow="username" + } + logger.Info(username) // $ hasTaintFlow="username" + logger.Infof(username, "") // $ hasTaintFlow="username" + logger.Infof("", username) // $ hasTaintFlow="username" + logger.Infoln(username) // $ hasTaintFlow="username" + logger.Log(0, username) // $ hasTaintFlow="username" + logger.Logf(0, username, "") // $ hasTaintFlow="username" + logger.Logf(0, "", username) // $ hasTaintFlow="username" + logger.Logln(0, username) // $ hasTaintFlow="username" + if testFlag == "33" { + logger.Panic(username) // $ hasTaintFlow="username" + } + if testFlag == "34" { + logger.Panicf(username, "") // $ hasTaintFlow="username" + } + if testFlag == "35" { + logger.Panicf("", username) // $ hasTaintFlow="username" + } + if testFlag == "36" { + logger.Panicln(username) // $ hasTaintFlow="username" + } logger.Print(username) // $ hasTaintFlow="username" logger.Printf(username, "") // $ hasTaintFlow="username" logger.Printf("", username) // $ hasTaintFlow="username" @@ -311,26 +399,42 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { logger.WithFields(fields) // $ hasTaintFlow="fields" var fieldlogger logrus.FieldLogger = entry - fieldlogger.Debug(username) // $ hasTaintFlow="username" - fieldlogger.Debugf(username, "") // $ hasTaintFlow="username" - fieldlogger.Debugf("", username) // $ hasTaintFlow="username" - fieldlogger.Debugln(username) // $ hasTaintFlow="username" - fieldlogger.Error(username) // $ hasTaintFlow="username" - fieldlogger.Errorf(username, "") // $ hasTaintFlow="username" - fieldlogger.Errorf("", username) // $ hasTaintFlow="username" - fieldlogger.Errorln(username) // $ hasTaintFlow="username" - fieldlogger.Fatal(username) // $ hasTaintFlow="username" - fieldlogger.Fatalf(username, "") // $ hasTaintFlow="username" - fieldlogger.Fatalf("", username) // $ hasTaintFlow="username" - fieldlogger.Fatalln(username) // $ hasTaintFlow="username" - fieldlogger.Info(username) // $ hasTaintFlow="username" - fieldlogger.Infof(username, "") // $ hasTaintFlow="username" - fieldlogger.Infof("", username) // $ hasTaintFlow="username" - fieldlogger.Infoln(username) // $ hasTaintFlow="username" - fieldlogger.Panic(username) // $ hasTaintFlow="username" - fieldlogger.Panicf(username, "") // $ hasTaintFlow="username" - fieldlogger.Panicf("", username) // $ hasTaintFlow="username" - fieldlogger.Panicln(username) // $ hasTaintFlow="username" + fieldlogger.Debug(username) // $ hasTaintFlow="username" + fieldlogger.Debugf(username, "") // $ hasTaintFlow="username" + fieldlogger.Debugf("", username) // $ hasTaintFlow="username" + fieldlogger.Debugln(username) // $ hasTaintFlow="username" + fieldlogger.Error(username) // $ hasTaintFlow="username" + fieldlogger.Errorf(username, "") // $ hasTaintFlow="username" + fieldlogger.Errorf("", username) // $ hasTaintFlow="username" + fieldlogger.Errorln(username) // $ hasTaintFlow="username" + if testFlag == "37" { + fieldlogger.Fatal(username) // $ hasTaintFlow="username" + } + if testFlag == "38" { + fieldlogger.Fatalf(username, "") // $ hasTaintFlow="username" + } + if testFlag == "39" { + fieldlogger.Fatalf("", username) // $ hasTaintFlow="username" + } + if testFlag == "40" { + fieldlogger.Fatalln(username) // $ hasTaintFlow="username" + } + fieldlogger.Info(username) // $ hasTaintFlow="username" + fieldlogger.Infof(username, "") // $ hasTaintFlow="username" + fieldlogger.Infof("", username) // $ hasTaintFlow="username" + fieldlogger.Infoln(username) // $ hasTaintFlow="username" + if testFlag == "41" { + fieldlogger.Panic(username) // $ hasTaintFlow="username" + } + if testFlag == "42" { + fieldlogger.Panicf(username, "") // $ hasTaintFlow="username" + } + if testFlag == "43" { + fieldlogger.Panicf("", username) // $ hasTaintFlow="username" + } + if testFlag == "44" { + fieldlogger.Panicln(username) // $ hasTaintFlow="username" + } fieldlogger.Print(username) // $ hasTaintFlow="username" fieldlogger.Printf(username, "") // $ hasTaintFlow="username" fieldlogger.Printf("", username) // $ hasTaintFlow="username" @@ -366,11 +470,11 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { logger.DPanic(username) // $ hasTaintFlow="username" logger.Debug(username) // $ hasTaintFlow="username" logger.Error(username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "45" { logger.Fatal(username) // $ hasTaintFlow="username" } logger.Info(username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "46" { logger.Panic(username) // $ hasTaintFlow="username" } logger.Warn(username) // $ hasTaintFlow="username" @@ -382,33 +486,33 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) { sLogger.DPanic(username) // $ hasTaintFlow="username" sLogger.Debug(username) // $ hasTaintFlow="username" sLogger.Error(username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "47" { sLogger.Fatal(username) // $ hasTaintFlow="username" } sLogger.Info(username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "48" { sLogger.Panic(username) // $ hasTaintFlow="username" } sLogger.Warn(username) // $ hasTaintFlow="username" sLogger.DPanicf(username) // $ hasTaintFlow="username" sLogger.Debugf(username) // $ hasTaintFlow="username" sLogger.Errorf(username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "49" { sLogger.Fatalf(username) // $ hasTaintFlow="username" } sLogger.Infof(username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "50" { sLogger.Panicf(username) // $ hasTaintFlow="username" } sLogger.Warnf(username) // $ hasTaintFlow="username" sLogger.DPanicw(username) // $ hasTaintFlow="username" sLogger.Debugw(username) // $ hasTaintFlow="username" sLogger.Errorw(username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "51" { sLogger.Fatalw(username) // $ hasTaintFlow="username" } sLogger.Infow(username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "52" { sLogger.Panicw(username) // $ hasTaintFlow="username" } sLogger.Warnw(username) // $ hasTaintFlow="username" @@ -515,10 +619,10 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { verbose.Infof("user %q logged in.\n", username) klog.Infof("user %q logged in.\n", username) klog.Errorf("user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "53" { klog.Fatalf("user %q logged in.\n", username) } - if testFlag == " true" { + if testFlag == "54" { klog.Exitf("user %q logged in.\n", username) } } @@ -534,10 +638,10 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { glog.Infof("user %q logged in.\n", username) glog.Errorf("user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "55" { glog.Fatalf("user %q logged in.\n", username) } - if testFlag == " true" { + if testFlag == "56" { glog.Exitf("user %q logged in.\n", username) } } @@ -545,11 +649,11 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { { logrus.Debugf("user %q logged in.\n", username) logrus.Errorf("user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "57" { logrus.Fatalf("user %q logged in.\n", username) } logrus.Infof("user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "58" { logrus.Panicf("user %q logged in.\n", username) } logrus.Printf("user %q logged in.\n", username) @@ -561,12 +665,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { entry := logrus.WithFields(fields) entry.Debugf("user %q logged in.\n", username) entry.Errorf("user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "59" { entry.Fatalf("user %q logged in.\n", username) } entry.Infof("user %q logged in.\n", username) entry.Logf(0, "user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "60" { entry.Panicf("user %q logged in.\n", username) } entry.Printf("user %q logged in.\n", username) @@ -577,12 +681,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { logger := entry.Logger logger.Debugf("user %q logged in.\n", username) logger.Errorf("user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "61" { logger.Fatalf("user %q logged in.\n", username) } logger.Infof("user %q logged in.\n", username) logger.Logf(0, "user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "62" { logger.Panicf("user %q logged in.\n", username) } logger.Printf("user %q logged in.\n", username) @@ -603,11 +707,11 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { sLogger.DPanicf("user %q logged in.\n", username) sLogger.Debugf("user %q logged in.\n", username) sLogger.Errorf("user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "63" { sLogger.Fatalf("user %q logged in.\n", username) } sLogger.Infof("user %q logged in.\n", username) - if testFlag == " true" { + if testFlag == "64" { sLogger.Panicf("user %q logged in.\n", username) } sLogger.Warnf("user %q logged in.\n", username) @@ -620,10 +724,10 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { verbose.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username" klog.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username" klog.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "65" { klog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } - if testFlag == " true" { + if testFlag == "66" { klog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } } @@ -639,10 +743,10 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { glog.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username" glog.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "67" { glog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } - if testFlag == " true" { + if testFlag == "68" { glog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } } @@ -650,11 +754,11 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { { logrus.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username" logrus.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "69" { logrus.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } logrus.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "70" { logrus.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } logrus.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username" @@ -666,12 +770,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { entry := logrus.WithFields(fields) entry.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username" entry.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "71" { entry.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } entry.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username" entry.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "72" { entry.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } entry.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username" @@ -682,12 +786,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { logger := entry.Logger logger.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username" logger.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "73" { logger.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } logger.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username" logger.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "74" { logger.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } logger.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username" @@ -708,11 +812,11 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) { sLogger.DPanicf("user %#q logged in.\n", username) // $ hasTaintFlow="username" sLogger.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username" sLogger.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "75" { sLogger.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } sLogger.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username" - if testFlag == " true" { + if testFlag == "76" { sLogger.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username" } sLogger.Warnf("user %#q logged in.\n", username) // $ hasTaintFlow="username" From adc9b7714b7bdc2c3561f34c84094e67e6711936 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 00:57:06 +0100 Subject: [PATCH 183/226] Accept changed test output --- .../CWE-312/CleartextLogging.expected | 60 ------------------- 1 file changed, 60 deletions(-) diff --git a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index f748c7a7773..bc513a693a7 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -82,13 +82,9 @@ edges | main.go:53:11:53:18 | password | main.go:54:12:54:19 | password | provenance | | | main.go:53:11:53:18 | password | main.go:54:12:54:19 | password | provenance | | | main.go:54:12:54:19 | password | main.go:56:11:56:18 | password | provenance | | -| main.go:54:12:54:19 | password | main.go:56:11:56:18 | password | provenance | | | main.go:54:12:54:19 | password | main.go:59:18:59:25 | password | provenance | | -| main.go:54:12:54:19 | password | main.go:59:18:59:25 | password | provenance | | -| main.go:54:12:54:19 | password | main.go:62:12:62:19 | password | provenance | | | main.go:54:12:54:19 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 | | main.go:54:12:54:19 | password | main.go:65:13:65:20 | password | provenance | | -| main.go:54:12:54:19 | password | main.go:65:13:65:20 | password | provenance | | | main.go:54:12:54:19 | password | main.go:68:11:68:18 | password | provenance | | | main.go:54:12:54:19 | password | main.go:68:11:68:18 | password | provenance | | | main.go:54:12:54:19 | password | main.go:71:18:71:25 | password | provenance | | @@ -99,58 +95,6 @@ edges | main.go:54:12:54:19 | password | main.go:77:13:77:20 | password | provenance | | | main.go:54:12:54:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | | main.go:54:12:54:19 | password | main.go:80:17:80:24 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:59:18:59:25 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:59:18:59:25 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:62:12:62:19 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 | -| main.go:56:11:56:18 | password | main.go:65:13:65:20 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:65:13:65:20 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:68:11:68:18 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:68:11:68:18 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:74:12:74:19 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | -| main.go:56:11:56:18 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:56:11:56:18 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | -| main.go:56:11:56:18 | password | main.go:80:17:80:24 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:62:12:62:19 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 | -| main.go:59:18:59:25 | password | main.go:65:13:65:20 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:65:13:65:20 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:68:11:68:18 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:68:11:68:18 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:74:12:74:19 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | -| main.go:59:18:59:25 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:59:18:59:25 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | -| main.go:59:18:59:25 | password | main.go:80:17:80:24 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:65:13:65:20 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:65:13:65:20 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:68:11:68:18 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:68:11:68:18 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:74:12:74:19 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | -| main.go:62:12:62:19 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:62:12:62:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | -| main.go:62:12:62:19 | password | main.go:80:17:80:24 | password | provenance | | -| main.go:65:13:65:20 | password | main.go:68:11:68:18 | password | provenance | | -| main.go:65:13:65:20 | password | main.go:68:11:68:18 | password | provenance | | -| main.go:65:13:65:20 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:65:13:65:20 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:65:13:65:20 | password | main.go:74:12:74:19 | password | provenance | | -| main.go:65:13:65:20 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | -| main.go:65:13:65:20 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:65:13:65:20 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:65:13:65:20 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | -| main.go:65:13:65:20 | password | main.go:80:17:80:24 | password | provenance | | | main.go:68:11:68:18 | password | main.go:71:18:71:25 | password | provenance | | | main.go:68:11:68:18 | password | main.go:71:18:71:25 | password | provenance | | | main.go:68:11:68:18 | password | main.go:74:12:74:19 | password | provenance | | @@ -274,12 +218,8 @@ nodes | main.go:54:12:54:19 | password | semmle.label | password | | main.go:54:12:54:19 | password | semmle.label | password | | main.go:56:11:56:18 | password | semmle.label | password | -| main.go:56:11:56:18 | password | semmle.label | password | -| main.go:59:18:59:25 | password | semmle.label | password | | main.go:59:18:59:25 | password | semmle.label | password | | main.go:62:12:62:19 | password | semmle.label | password | -| main.go:62:12:62:19 | password | semmle.label | password | -| main.go:65:13:65:20 | password | semmle.label | password | | main.go:65:13:65:20 | password | semmle.label | password | | main.go:68:11:68:18 | password | semmle.label | password | | main.go:68:11:68:18 | password | semmle.label | password | From e6e8e3d005406f88467bc87179e170f15262f2bd Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 01:31:44 +0100 Subject: [PATCH 184/226] Taint doesn't flow through panicking functions --- go/ql/lib/semmle/go/frameworks/stdlib/Log.qll | 24 ----- .../go/frameworks/StdlibTaintFlow/Log.go | 96 ------------------- 2 files changed, 120 deletions(-) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll index 390258591a9..ad5353fb699 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll @@ -69,30 +69,6 @@ module Log { FunctionOutput outp; MethodModels() { - // signature: func (*Logger) Fatal(v ...interface{}) - this.hasQualifiedName("log", "Logger", "Fatal") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (*Logger) Fatalf(format string, v ...interface{}) - this.hasQualifiedName("log", "Logger", "Fatalf") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (*Logger) Fatalln(v ...interface{}) - this.hasQualifiedName("log", "Logger", "Fatalln") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (*Logger) Panic(v ...interface{}) - this.hasQualifiedName("log", "Logger", "Panic") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (*Logger) Panicf(format string, v ...interface{}) - this.hasQualifiedName("log", "Logger", "Panicf") and - (inp.isParameter(_) and outp.isReceiver()) - or - // signature: func (*Logger) Panicln(v ...interface{}) - this.hasQualifiedName("log", "Logger", "Panicln") and - (inp.isParameter(_) and outp.isReceiver()) - or // signature: func (*Logger) Print(v ...interface{}) this.hasQualifiedName("log", "Logger", "Print") and (inp.isParameter(_) and outp.isReceiver()) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Log.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Log.go index 703c4086ae1..50dcfd1170b 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Log.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Log.go @@ -15,62 +15,6 @@ func TaintStepTest_LogNew_B0I0O0(sourceCQL interface{}) interface{} { return intoWriter414 } -func TaintStepTest_LogLoggerFatal_B0I0O0(sourceCQL interface{}) interface{} { - fromInterface518 := sourceCQL.(interface{}) - var intoLogger650 log.Logger - intoLogger650.Fatal(fromInterface518) - return intoLogger650 -} - -func TaintStepTest_LogLoggerFatalf_B0I0O0(sourceCQL interface{}) interface{} { - fromString784 := sourceCQL.(string) - var intoLogger957 log.Logger - intoLogger957.Fatalf(fromString784, nil) - return intoLogger957 -} - -func TaintStepTest_LogLoggerFatalf_B0I1O0(sourceCQL interface{}) interface{} { - fromInterface520 := sourceCQL.(interface{}) - var intoLogger443 log.Logger - intoLogger443.Fatalf("", fromInterface520) - return intoLogger443 -} - -func TaintStepTest_LogLoggerFatalln_B0I0O0(sourceCQL interface{}) interface{} { - fromInterface127 := sourceCQL.(interface{}) - var intoLogger483 log.Logger - intoLogger483.Fatalln(fromInterface127) - return intoLogger483 -} - -func TaintStepTest_LogLoggerPanic_B0I0O0(sourceCQL interface{}) interface{} { - fromInterface989 := sourceCQL.(interface{}) - var intoLogger982 log.Logger - intoLogger982.Panic(fromInterface989) - return intoLogger982 -} - -func TaintStepTest_LogLoggerPanicf_B0I0O0(sourceCQL interface{}) interface{} { - fromString417 := sourceCQL.(string) - var intoLogger584 log.Logger - intoLogger584.Panicf(fromString417, nil) - return intoLogger584 -} - -func TaintStepTest_LogLoggerPanicf_B0I1O0(sourceCQL interface{}) interface{} { - fromInterface991 := sourceCQL.(interface{}) - var intoLogger881 log.Logger - intoLogger881.Panicf("", fromInterface991) - return intoLogger881 -} - -func TaintStepTest_LogLoggerPanicln_B0I0O0(sourceCQL interface{}) interface{} { - fromInterface186 := sourceCQL.(interface{}) - var intoLogger284 log.Logger - intoLogger284.Panicln(fromInterface186) - return intoLogger284 -} - func TaintStepTest_LogLoggerPrint_B0I0O0(sourceCQL interface{}) interface{} { fromInterface908 := sourceCQL.(interface{}) var intoLogger137 log.Logger @@ -125,46 +69,6 @@ func RunAllTaints_Log() { out := TaintStepTest_LogNew_B0I0O0(source) sink(0, out) } - { - source := newSource(1) - out := TaintStepTest_LogLoggerFatal_B0I0O0(source) - sink(1, out) - } - { - source := newSource(2) - out := TaintStepTest_LogLoggerFatalf_B0I0O0(source) - sink(2, out) - } - { - source := newSource(3) - out := TaintStepTest_LogLoggerFatalf_B0I1O0(source) - sink(3, out) - } - { - source := newSource(4) - out := TaintStepTest_LogLoggerFatalln_B0I0O0(source) - sink(4, out) - } - { - source := newSource(5) - out := TaintStepTest_LogLoggerPanic_B0I0O0(source) - sink(5, out) - } - { - source := newSource(6) - out := TaintStepTest_LogLoggerPanicf_B0I0O0(source) - sink(6, out) - } - { - source := newSource(7) - out := TaintStepTest_LogLoggerPanicf_B0I1O0(source) - sink(7, out) - } - { - source := newSource(8) - out := TaintStepTest_LogLoggerPanicln_B0I0O0(source) - sink(8, out) - } { source := newSource(9) out := TaintStepTest_LogLoggerPrint_B0I0O0(source) From 703cea2b65040ddb44fe821b30bd2071919970e6 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 01:32:00 +0100 Subject: [PATCH 185/226] Model panicking log functions better --- go/ql/lib/semmle/go/frameworks/stdlib/Log.qll | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll index ad5353fb699..1ff1a4b320f 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Log.qll @@ -47,6 +47,19 @@ module Log { override predicate mayReturnNormally() { none() } } + /** A log function which must panic. */ + private class PanicLogFunction extends Function { + PanicLogFunction() { + exists(string fn | fn = ["Panic", "Panicf", "Panicln"] | + this.hasQualifiedName("log", fn) + or + this.(Method).hasQualifiedName("log", "Logger", fn) + ) + } + + override predicate mustPanic() { any() } + } + // These models are not implemented using Models-as-Data because they represent reverse flow. private class FunctionModels extends TaintTracking::FunctionModel { FunctionInput inp; From 0547e9c98d5a8ef5133291520223d67214a8a49a Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 1 Jun 2026 15:18:21 +0200 Subject: [PATCH 186/226] Rust: Path resolution for `static` items --- .../lib/codeql/rust/elements/StaticAccess.qll | 7 + .../rust/elements/internal/ConstImpl.qll | 4 +- .../rust/elements/internal/StaticImpl.qll | 31 ++- .../codeql/rust/internal/PathResolution.qll | 32 +++ rust/ql/lib/rust.qll | 1 + rust/ql/test/TestUtils.qll | 9 + .../generated/Const/Const.expected | 8 +- .../ExternItemList/ExternItemList.expected | 2 +- .../generated/Static/Static.expected | 8 +- .../macro-expansion/PrintAst.expected | 2 +- .../macro-expansion/test.expected | 2 +- .../const_access/const_access.expected | 15 +- .../const_access/const_access.ql | 14 +- .../test/library-tests/const_access/main.rs | 30 ++- .../library-tests/controlflow/Cfg.expected | 4 +- .../library-tests/path-resolution/main.rs | 46 ++++ .../path-resolution/path-resolution.expected | 199 ++++++++++-------- .../library-tests/static_access/Cargo.lock | 7 + .../test/library-tests/static_access/main.rs | 33 +++ .../static_access/static_access.expected | 8 + .../static_access/static_access.ql | 31 +++ .../test/library-tests/variables/variables.ql | 7 - 22 files changed, 378 insertions(+), 122 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/elements/StaticAccess.qll create mode 100644 rust/ql/test/library-tests/static_access/Cargo.lock create mode 100644 rust/ql/test/library-tests/static_access/main.rs create mode 100644 rust/ql/test/library-tests/static_access/static_access.expected create mode 100644 rust/ql/test/library-tests/static_access/static_access.ql diff --git a/rust/ql/lib/codeql/rust/elements/StaticAccess.qll b/rust/ql/lib/codeql/rust/elements/StaticAccess.qll new file mode 100644 index 00000000000..50b4bea14d1 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/StaticAccess.qll @@ -0,0 +1,7 @@ +/** + * This module provides the public class `StaticAccess`. + */ + +private import internal.StaticImpl + +final class StaticAccess = Impl::StaticAccess; diff --git a/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll index 44114674a56..776215ee4f4 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll @@ -24,7 +24,9 @@ module Impl { * const X: i32 = 42; * ``` */ - class Const extends Generated::Const { } + class Const extends Generated::Const { + override string toStringImpl() { result = "const " + this.getName().getText() } + } /** * A constant access. diff --git a/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll index 53042411bca..7eb08653d2d 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `Static`. * @@ -6,6 +5,9 @@ */ private import codeql.rust.elements.internal.generated.Static +private import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl +private import codeql.rust.elements.internal.PathExprImpl::Impl as PathExprImpl +private import codeql.rust.internal.PathResolution /** * INTERNAL: This module contains the customizable definition of `Static` and should not @@ -20,5 +22,30 @@ module Impl { * static X: i32 = 42; * ``` */ - class Static extends Generated::Static { } + class Static extends Generated::Static { + override string toStringImpl() { result = "static " + this.getName().getText() } + } + + /** + * A static access. + * + * For example: + * ```rust + * static X: i32 = 42; + * + * fn main() { + * println!("{}", X); + * } + * ``` + */ + class StaticAccess extends AstNodeImpl::AstNode, PathExprImpl::PathExpr { + private Static s; + + StaticAccess() { s = resolvePath(this.getPath()) } + + /** Gets the static being accessed. */ + Static getStatic() { result = s } + + override string getAPrimaryQlClass() { result = "StaticAccess" } + } } diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 10d18786880..7235f3e05e6 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -659,6 +659,38 @@ private class ConstItemNode extends AssocItemNode instanceof Const { override TypeParam getTypeParam(int i) { none() } } +private class StaticItemNode extends ItemNode instanceof Static { + override string getName() { result = Static.super.getName().getText() } + + override Namespace getNamespace() { result.isValue() } + + override Visibility getVisibility() { result = Static.super.getVisibility() } + + override Attr getAnAttr() { result = Static.super.getAnAttr() } + + override TypeParam getTypeParam(int i) { none() } + + override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) } + + bindingset[c] + private string getCanonicalPathPart(Crate c, int i) { + i = 0 and + result = this.getCanonicalPathPrefix(c) + or + i = 1 and + result = "::" + or + i = 2 and + result = this.getName() + } + + language[monotonicAggregates] + override string getCanonicalPath(Crate c) { + this.hasCanonicalPath(c) and + result = strictconcat(int i | i in [0 .. 2] | this.getCanonicalPathPart(c, i) order by i) + } +} + private class TypeItemTypeItemNode extends NamedItemNode, TypeItemNode instanceof TypeItem { override string getName() { result = TypeItem.super.getName().getText() } diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index 410f062d91e..46e6e605d41 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -11,6 +11,7 @@ import codeql.rust.elements.AssignmentOperation import codeql.rust.elements.BitwiseOperation import codeql.rust.elements.ComparisonOperation import codeql.rust.elements.ConstAccess +import codeql.rust.elements.StaticAccess import codeql.rust.elements.DerefExpr import codeql.rust.elements.LiteralExprExt import codeql.rust.elements.LogicalOperation diff --git a/rust/ql/test/TestUtils.qll b/rust/ql/test/TestUtils.qll index a68d9554d34..d622af7f4d3 100644 --- a/rust/ql/test/TestUtils.qll +++ b/rust/ql/test/TestUtils.qll @@ -20,3 +20,12 @@ class CrateElement extends Element { class Builtin extends AstNode { Builtin() { this.getFile().getAbsolutePath().matches("%/builtins/%.rs") } } + +predicate commmentAt(string text, string filepath, int line) { + exists(Comment c | + c.getLocation().hasLocationInfo(filepath, line, _, _, _) and + c.getCommentText().trim() = text and + c.fromSource() and + not text.matches("$%") + ) +} diff --git a/rust/ql/test/extractor-tests/generated/Const/Const.expected b/rust/ql/test/extractor-tests/generated/Const/Const.expected index cc1f282193f..0ab5fbb85db 100644 --- a/rust/ql/test/extractor-tests/generated/Const/Const.expected +++ b/rust/ql/test/extractor-tests/generated/Const/Const.expected @@ -1,13 +1,13 @@ instances -| gen_const.rs:4:5:7:22 | Const | isConst: | yes | isDefault: | no | hasImplementation: | yes | +| gen_const.rs:4:5:7:22 | const X | isConst: | yes | isDefault: | no | hasImplementation: | yes | getAttributeMacroExpansion getAttr getBody -| gen_const.rs:4:5:7:22 | Const | gen_const.rs:7:20:7:21 | 42 | +| gen_const.rs:4:5:7:22 | const X | gen_const.rs:7:20:7:21 | 42 | getGenericParamList getName -| gen_const.rs:4:5:7:22 | Const | gen_const.rs:7:11:7:11 | X | +| gen_const.rs:4:5:7:22 | const X | gen_const.rs:7:11:7:11 | X | getTypeRepr -| gen_const.rs:4:5:7:22 | Const | gen_const.rs:7:14:7:16 | i32 | +| gen_const.rs:4:5:7:22 | const X | gen_const.rs:7:14:7:16 | i32 | getVisibility getWhereClause diff --git a/rust/ql/test/extractor-tests/generated/ExternItemList/ExternItemList.expected b/rust/ql/test/extractor-tests/generated/ExternItemList/ExternItemList.expected index 8b6eb94b1b2..579420663af 100644 --- a/rust/ql/test/extractor-tests/generated/ExternItemList/ExternItemList.expected +++ b/rust/ql/test/extractor-tests/generated/ExternItemList/ExternItemList.expected @@ -3,4 +3,4 @@ instances getAttr getExternItem | gen_extern_item_list.rs:7:16:10:5 | ExternItemList | 0 | gen_extern_item_list.rs:8:9:8:17 | fn foo | -| gen_extern_item_list.rs:7:16:10:5 | ExternItemList | 1 | gen_extern_item_list.rs:9:9:9:24 | Static | +| gen_extern_item_list.rs:7:16:10:5 | ExternItemList | 1 | gen_extern_item_list.rs:9:9:9:24 | static BAR | diff --git a/rust/ql/test/extractor-tests/generated/Static/Static.expected b/rust/ql/test/extractor-tests/generated/Static/Static.expected index 074c6600f8c..9ac6884c18c 100644 --- a/rust/ql/test/extractor-tests/generated/Static/Static.expected +++ b/rust/ql/test/extractor-tests/generated/Static/Static.expected @@ -1,11 +1,11 @@ instances -| gen_static.rs:4:5:7:23 | Static | isMut: | no | isStatic: | yes | isUnsafe: | no | +| gen_static.rs:4:5:7:23 | static X | isMut: | no | isStatic: | yes | isUnsafe: | no | getAttributeMacroExpansion getAttr getBody -| gen_static.rs:4:5:7:23 | Static | gen_static.rs:7:21:7:22 | 42 | +| gen_static.rs:4:5:7:23 | static X | gen_static.rs:7:21:7:22 | 42 | getName -| gen_static.rs:4:5:7:23 | Static | gen_static.rs:7:12:7:12 | X | +| gen_static.rs:4:5:7:23 | static X | gen_static.rs:7:12:7:12 | X | getTypeRepr -| gen_static.rs:4:5:7:23 | Static | gen_static.rs:7:15:7:17 | i32 | +| gen_static.rs:4:5:7:23 | static X | gen_static.rs:7:15:7:17 | i32 | getVisibility diff --git a/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected b/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected index 6f0b278d062..765b46d01d8 100644 --- a/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected +++ b/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected @@ -957,7 +957,7 @@ macro_expansion.rs: # 94| getName(): [Name] MyTrait # 98| getItem(20): [Union] union MyDeriveUnion # 99| getDeriveMacroExpansion(0): [MacroItems] MacroItems -# 99| getItem(0): [Const] Const +# 99| getItem(0): [Const] const CONST_MyDeriveUnion # 98| getBody(): [IntegerLiteralExpr] 42 # 99| getName(): [Name] CONST_MyDeriveUnion # 98| getTypeRepr(): [PathTypeRepr] u32 diff --git a/rust/ql/test/extractor-tests/macro-expansion/test.expected b/rust/ql/test/extractor-tests/macro-expansion/test.expected index f47a7455e91..f7d5cae7340 100644 --- a/rust/ql/test/extractor-tests/macro-expansion/test.expected +++ b/rust/ql/test/extractor-tests/macro-expansion/test.expected @@ -18,7 +18,7 @@ derive_macros | macro_expansion.rs:83:1:86:1 | struct MyDerive | 0 | 0 | macro_expansion.rs:84:8:85:9 | impl ...::Debug for MyDerive::<...> { ... } | | macro_expansion.rs:88:1:92:1 | enum MyDeriveEnum | 0 | 0 | macro_expansion.rs:89:6:91:12 | impl ...::PartialEq for MyDeriveEnum::<...> { ... } | | macro_expansion.rs:88:1:92:1 | enum MyDeriveEnum | 1 | 0 | macro_expansion.rs:89:6:89:17 | impl ...::Eq for MyDeriveEnum::<...> { ... } | -| macro_expansion.rs:98:1:102:1 | union MyDeriveUnion | 0 | 0 | macro_expansion.rs:99:7:99:19 | Const | +| macro_expansion.rs:98:1:102:1 | union MyDeriveUnion | 0 | 0 | macro_expansion.rs:99:7:99:19 | const CONST_MyDeriveUnion | | macro_expansion.rs:98:1:102:1 | union MyDeriveUnion | 0 | 1 | macro_expansion.rs:99:7:99:19 | impl MyTrait for MyDeriveUnion { ... } | macro_calls | macro_expansion.rs:5:9:5:35 | concat!... | macro_expansion.rs:5:17:5:34 | "Hello world!" | diff --git a/rust/ql/test/library-tests/const_access/const_access.expected b/rust/ql/test/library-tests/const_access/const_access.expected index 83c5022aca8..ccecf6365b4 100644 --- a/rust/ql/test/library-tests/const_access/const_access.expected +++ b/rust/ql/test/library-tests/const_access/const_access.expected @@ -1,8 +1,11 @@ testFailures constAccess -| main.rs:17:13:17:24 | GLOBAL_CONST | main.rs:1:1:1:29 | Const | -| main.rs:19:13:19:24 | STRING_CONST | main.rs:2:1:2:35 | Const | -| main.rs:21:13:21:33 | ...::ASSOC_CONST | main.rs:9:5:9:33 | Const | -| main.rs:23:13:23:35 | ...::MODULE_CONST | main.rs:13:5:13:38 | Const | -| main.rs:25:8:25:19 | GLOBAL_CONST | main.rs:1:1:1:29 | Const | -| main.rs:29:16:29:36 | ...::ASSOC_CONST | main.rs:9:5:9:33 | Const | +| main.rs:17:13:17:24 | GLOBAL_CONST | main.rs:1:1:1:29 | const GLOBAL_CONST | +| main.rs:19:13:19:24 | STRING_CONST | main.rs:2:1:2:35 | const STRING_CONST | +| main.rs:21:13:21:33 | ...::ASSOC_CONST | main.rs:9:5:9:33 | const ASSOC_CONST | +| main.rs:23:13:23:35 | ...::MODULE_CONST | main.rs:13:5:13:38 | const MODULE_CONST | +| main.rs:26:16:26:27 | GLOBAL_CONST | main.rs:1:1:1:29 | const GLOBAL_CONST | +| main.rs:30:16:30:36 | ...::ASSOC_CONST | main.rs:9:5:9:33 | const ASSOC_CONST | +| main.rs:33:20:33:31 | GLOBAL_CONST | main.rs:1:1:1:29 | const GLOBAL_CONST | +| main.rs:39:17:39:28 | STRING_CONST | main.rs:38:9:38:43 | const STRING_CONST | +| main.rs:43:21:43:32 | STRING_CONST | main.rs:42:13:42:48 | const STRING_CONST | diff --git a/rust/ql/test/library-tests/const_access/const_access.ql b/rust/ql/test/library-tests/const_access/const_access.ql index b3bb7363392..f10479fdb81 100644 --- a/rust/ql/test/library-tests/const_access/const_access.ql +++ b/rust/ql/test/library-tests/const_access/const_access.ql @@ -5,15 +5,25 @@ import TestUtils query predicate constAccess(ConstAccess ca, Const c) { toBeTested(ca) and c = ca.getConst() } module ConstAccessTest implements TestSig { + private predicate constAt(Const c, string filepath, int line) { + c.getLocation().hasLocationInfo(filepath, _, _, line, _) + } + string getARelevantTag() { result = "const_access" } predicate hasActualResult(Location location, string element, string tag, string value) { - exists(ConstAccess ca | + exists(ConstAccess ca, Const c, string filepath, int line | toBeTested(ca) and location = ca.getLocation() and element = ca.toString() and tag = "const_access" and - value = ca.getConst().getName().getText() + c = ca.getConst() and + constAt(c, filepath, line) + | + commmentAt(value, filepath, line) + or + not commmentAt(_, filepath, line) and + value = c.getName().getText() ) } } diff --git a/rust/ql/test/library-tests/const_access/main.rs b/rust/ql/test/library-tests/const_access/main.rs index 0cf2467d100..aebf6bba1bf 100644 --- a/rust/ql/test/library-tests/const_access/main.rs +++ b/rust/ql/test/library-tests/const_access/main.rs @@ -15,18 +15,34 @@ mod my_module { fn use_consts() { let x = GLOBAL_CONST; // $ const_access=GLOBAL_CONST - + let s = STRING_CONST; // $ const_access=STRING_CONST - + let y = MyStruct::ASSOC_CONST; // $ const_access=ASSOC_CONST - + let z = my_module::MODULE_CONST; // $ const_access=MODULE_CONST - - if GLOBAL_CONST > 0 { // $ const_access=GLOBAL_CONST + + #[rustfmt::skip] + let _ = if GLOBAL_CONST > 0 { // $ const_access=GLOBAL_CONST println!("positive"); - } - + }; + let arr = [MyStruct::ASSOC_CONST; 5]; // $ const_access=ASSOC_CONST + + #[rustfmt::skip] + let _ = if let GLOBAL_CONST = 0 { // $ const_access=GLOBAL_CONST + println!("zero"); + }; + + { + const STRING_CONST: &str = "inner"; // Inner1 + let _ = STRING_CONST; // $ const_access=Inner1 + + { + const STRING_CONST: &str = "inner2"; // Inner2 + let _ = STRING_CONST; // $ const_access=Inner2 + } + } } fn main() { diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index ef97a3b628f..438b841ff16 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1317,10 +1317,10 @@ edges | test.rs:533:21:533:48 | { ... } | test.rs:533:21:533:48 | { ... } | | | test.rs:533:48:533:48 | 0 | test.rs:533:21:533:48 | ... > ... | | | test.rs:536:9:536:10 | 42 | test.rs:529:41:537:5 | { ... } | | -| test.rs:539:5:548:5 | enter fn const_block_panic | test.rs:540:9:540:30 | Const | | +| test.rs:539:5:548:5 | enter fn const_block_panic | test.rs:540:9:540:30 | const N | | | test.rs:539:5:548:5 | exit fn const_block_panic (normal) | test.rs:539:5:548:5 | exit fn const_block_panic | | | test.rs:539:35:548:5 | { ... } | test.rs:539:5:548:5 | exit fn const_block_panic (normal) | | -| test.rs:540:9:540:30 | Const | test.rs:541:9:546:9 | ExprStmt | | +| test.rs:540:9:540:30 | const N | test.rs:541:9:546:9 | ExprStmt | | | test.rs:541:9:546:9 | ExprStmt | test.rs:541:12:541:16 | false | | | test.rs:541:9:546:9 | if false {...} | test.rs:547:9:547:9 | N | | | test.rs:541:12:541:16 | false | test.rs:541:9:546:9 | if false {...} | false | diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs index c96f9ef30f0..f95b6ef09ef 100644 --- a/rust/ql/test/library-tests/path-resolution/main.rs +++ b/rust/ql/test/library-tests/path-resolution/main.rs @@ -1098,6 +1098,52 @@ mod self_types { } } +#[rustfmt::skip] +mod const_static { + use crate::const_static; // $ item=const_static + + pub const CONST_ITEM: i32 = 42; // $ item=i32 + + pub static STATIC_ITEM: i32 = 42; // $ item=i32 + + fn use_const_static() { + let _ = CONST_ITEM; // $ item=CONST_ITEM + let _ = STATIC_ITEM; // $ item=STATIC_ITEM + let _ = const_static::CONST_ITEM; // $ item=CONST_ITEM + let _ = const_static::STATIC_ITEM; // $ item=STATIC_ITEM + let _ = CONST_ALIAS; // $ item=C1 + let _ = STATIC_ALIAS; // $ item=S1 + + const CONST_ALIAS: i32 = CONST_ITEM // $ item=CONST_ITEM item=i32 + ; // C1 + static STATIC_ALIAS: i32 = STATIC_ITEM // $ item=STATIC_ITEM item=i32 + ; // S1 + + let _ = CONST_ALIAS; // $ item=C1 + let _ = STATIC_ALIAS; // $ item=S1 + + { + const CONST_ALIAS: i32 = CONST_ITEM // $ item=CONST_ITEM item=i32 + ; // C2 + static STATIC_ALIAS: i32 = STATIC_ITEM // $ item=STATIC_ITEM item=i32 + ; // S2 + + let _ = CONST_ALIAS; // $ item=C2 + let _ = STATIC_ALIAS; // $ item=S2 + } + + { + const CONST_ALIAS: i32 = CONST_ITEM // $ item=CONST_ITEM item=i32 + ; // C3 + static STATIC_ALIAS: i32 = STATIC_ITEM // $ item=STATIC_ITEM item=i32 + ; // S3 + + let _ = CONST_ALIAS; // $ item=C3 + let _ = STATIC_ALIAS; // $ item=S3 + } + } +} + fn main() { my::nested::nested1::nested2::f(); // $ item=I4 my::f(); // $ item=I38 diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected index e85bb7876da..ef881e62f53 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -36,6 +36,7 @@ mod | main.rs:981:1:1022:1 | mod patterns | | main.rs:1024:1:1068:1 | mod self_constructors | | main.rs:1070:1:1099:1 | mod self_types | +| main.rs:1101:1:1145:1 | mod const_static | | my2/mod.rs:1:1:1:16 | mod nested2 | | my2/mod.rs:20:1:20:12 | mod my3 | | my2/mod.rs:22:1:23:10 | mod mymod | @@ -77,7 +78,7 @@ resolvePath | main.rs:37:17:37:24 | ...::f | main.rs:26:9:28:9 | fn f | | main.rs:39:17:39:23 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:40:17:40:17 | f | main.rs:26:9:28:9 | fn f | -| main.rs:47:9:47:13 | super | main.rs:1:1:1138:2 | SourceFile | +| main.rs:47:9:47:13 | super | main.rs:1:1:1184:2 | SourceFile | | main.rs:47:9:47:17 | ...::m1 | main.rs:20:1:44:1 | mod m1 | | main.rs:47:9:47:21 | ...::m2 | main.rs:25:5:43:5 | mod m2 | | main.rs:47:9:47:24 | ...::g | main.rs:30:9:34:9 | fn g | @@ -92,7 +93,7 @@ resolvePath | main.rs:68:17:68:19 | Foo | main.rs:66:9:66:21 | struct Foo | | main.rs:71:13:71:15 | Foo | main.rs:60:5:60:17 | struct Foo | | main.rs:73:5:73:5 | f | main.rs:62:5:69:5 | fn f | -| main.rs:75:5:75:8 | self | main.rs:1:1:1138:2 | SourceFile | +| main.rs:75:5:75:8 | self | main.rs:1:1:1184:2 | SourceFile | | main.rs:75:5:75:11 | ...::i | main.rs:78:1:90:1 | fn i | | main.rs:79:5:79:11 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:81:13:81:15 | Foo | main.rs:55:1:55:13 | struct Foo | @@ -114,7 +115,7 @@ resolvePath | main.rs:112:9:112:15 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:118:9:118:15 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:122:9:122:15 | println | {EXTERNAL LOCATION} | MacroRules | -| main.rs:125:13:125:17 | super | main.rs:1:1:1138:2 | SourceFile | +| main.rs:125:13:125:17 | super | main.rs:1:1:1184:2 | SourceFile | | main.rs:125:13:125:21 | ...::m5 | main.rs:110:1:114:1 | mod m5 | | main.rs:126:9:126:9 | f | main.rs:111:5:113:5 | fn f | | main.rs:126:9:126:9 | f | main.rs:117:5:119:5 | fn f | @@ -234,7 +235,7 @@ resolvePath | main.rs:407:13:407:16 | Self | main.rs:398:5:411:5 | trait Trait2 | | main.rs:407:13:407:19 | ...::g | main.rs:385:9:387:9 | fn g | | main.rs:409:13:409:16 | Self | main.rs:398:5:411:5 | trait Trait2 | -| main.rs:409:13:409:19 | ...::c | main.rs:394:9:395:9 | Const | +| main.rs:409:13:409:19 | ...::c | main.rs:394:9:395:9 | const c | | main.rs:416:10:418:5 | Trait1::<...> | main.rs:378:5:396:5 | trait Trait1 | | main.rs:417:7:417:7 | S | main.rs:413:5:413:13 | struct S | | main.rs:419:11:419:11 | S | main.rs:413:5:413:13 | struct S | @@ -245,7 +246,7 @@ resolvePath | main.rs:426:24:426:24 | S | main.rs:413:5:413:13 | struct S | | main.rs:427:13:427:19 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:428:13:428:16 | Self | main.rs:415:5:433:5 | impl Trait1::<...> for S { ... } | -| main.rs:428:13:428:19 | ...::c | main.rs:431:9:432:9 | Const | +| main.rs:428:13:428:19 | ...::c | main.rs:431:9:432:9 | const c | | main.rs:431:18:431:18 | S | main.rs:413:5:413:13 | struct S | | main.rs:431:22:431:22 | S | main.rs:413:5:413:13 | struct S | | main.rs:436:10:438:5 | Trait2::<...> | main.rs:398:5:411:5 | trait Trait2 | @@ -256,7 +257,7 @@ resolvePath | main.rs:441:13:441:19 | ...::g | main.rs:426:9:429:9 | fn g | | main.rs:442:13:442:19 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:443:13:443:16 | Self | main.rs:435:5:445:5 | impl Trait2::<...> for S { ... } | -| main.rs:443:13:443:19 | ...::c | main.rs:431:9:432:9 | Const | +| main.rs:443:13:443:19 | ...::c | main.rs:431:9:432:9 | const c | | main.rs:449:9:449:15 | println | {EXTERNAL LOCATION} | MacroRules | | main.rs:450:17:450:17 | S | main.rs:413:5:413:13 | struct S | | main.rs:451:9:455:9 | <...> | main.rs:378:5:396:5 | trait Trait1 | @@ -274,9 +275,9 @@ resolvePath | main.rs:463:9:463:9 | S | main.rs:413:5:413:13 | struct S | | main.rs:463:9:463:12 | ...::h | main.rs:389:9:392:9 | fn h | | main.rs:465:9:465:9 | S | main.rs:413:5:413:13 | struct S | -| main.rs:465:9:465:12 | ...::c | main.rs:431:9:432:9 | Const | +| main.rs:465:9:465:12 | ...::c | main.rs:431:9:432:9 | const c | | main.rs:466:9:470:9 | <...> | main.rs:378:5:396:5 | trait Trait1 | -| main.rs:466:9:470:12 | ...::c | main.rs:394:9:395:9 | Const | +| main.rs:466:9:470:12 | ...::c | main.rs:394:9:395:9 | const c | | main.rs:466:10:466:10 | S | main.rs:413:5:413:13 | struct S | | main.rs:467:14:469:11 | Trait1::<...> | main.rs:378:5:396:5 | trait Trait1 | | main.rs:468:13:468:13 | S | main.rs:413:5:413:13 | struct S | @@ -545,8 +546,8 @@ resolvePath | main.rs:1011:17:1011:20 | Some | {EXTERNAL LOCATION} | Some | | main.rs:1013:13:1013:16 | Some | {EXTERNAL LOCATION} | Some | | main.rs:1018:13:1018:16 | Some | {EXTERNAL LOCATION} | Some | -| main.rs:1018:18:1018:18 | z | main.rs:1005:5:1007:12 | Const | -| main.rs:1018:24:1018:24 | z | main.rs:1005:5:1007:12 | Const | +| main.rs:1018:18:1018:18 | z | main.rs:1005:5:1007:12 | const z | +| main.rs:1018:24:1018:24 | z | main.rs:1005:5:1007:12 | const z | | main.rs:1026:24:1026:26 | i32 | {EXTERNAL LOCATION} | struct i32 | | main.rs:1029:10:1029:20 | TupleStruct | main.rs:1026:5:1026:28 | struct TupleStruct | | main.rs:1031:19:1031:21 | i32 | {EXTERNAL LOCATION} | struct i32 | @@ -582,79 +583,109 @@ resolvePath | main.rs:1096:17:1096:17 | T | main.rs:1093:9:1093:9 | T | | main.rs:1097:16:1097:16 | T | main.rs:1093:9:1093:9 | T | | main.rs:1097:23:1097:26 | Self | main.rs:1090:5:1098:5 | union NonEmptyListUnion | -| main.rs:1102:5:1102:6 | my | main.rs:1:1:1:7 | mod my | -| main.rs:1102:5:1102:14 | ...::nested | my.rs:1:1:1:15 | mod nested | -| main.rs:1102:5:1102:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | -| main.rs:1102:5:1102:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 | -| main.rs:1102:5:1102:35 | ...::f | my/nested.rs:3:9:5:9 | fn f | -| main.rs:1103:5:1103:6 | my | main.rs:1:1:1:7 | mod my | -| main.rs:1103:5:1103:9 | ...::f | my.rs:5:1:7:1 | fn f | -| main.rs:1104:5:1104:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | -| main.rs:1104:5:1104:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | -| main.rs:1104:5:1104:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | -| main.rs:1104:5:1104:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:1105:5:1105:5 | f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:1106:5:1106:5 | g | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:1107:5:1107:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | -| main.rs:1107:5:1107:12 | ...::h | main.rs:57:1:76:1 | fn h | -| main.rs:1108:5:1108:6 | m1 | main.rs:20:1:44:1 | mod m1 | -| main.rs:1108:5:1108:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 | -| main.rs:1108:5:1108:13 | ...::g | main.rs:30:9:34:9 | fn g | -| main.rs:1109:5:1109:6 | m1 | main.rs:20:1:44:1 | mod m1 | -| main.rs:1109:5:1109:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 | -| main.rs:1109:5:1109:14 | ...::m3 | main.rs:36:9:42:9 | mod m3 | -| main.rs:1109:5:1109:17 | ...::h | main.rs:37:27:41:13 | fn h | -| main.rs:1110:5:1110:6 | m4 | main.rs:46:1:53:1 | mod m4 | -| main.rs:1110:5:1110:9 | ...::i | main.rs:49:5:52:5 | fn i | -| main.rs:1111:5:1111:5 | h | main.rs:57:1:76:1 | fn h | -| main.rs:1112:5:1112:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:1113:5:1113:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:1114:5:1114:5 | j | main.rs:104:1:108:1 | fn j | -| main.rs:1115:5:1115:6 | m6 | main.rs:116:1:128:1 | mod m6 | -| main.rs:1115:5:1115:9 | ...::g | main.rs:121:5:127:5 | fn g | -| main.rs:1116:5:1116:6 | m7 | main.rs:130:1:149:1 | mod m7 | -| main.rs:1116:5:1116:9 | ...::f | main.rs:141:5:148:5 | fn f | -| main.rs:1117:5:1117:6 | m8 | main.rs:151:1:205:1 | mod m8 | -| main.rs:1117:5:1117:9 | ...::g | main.rs:189:5:204:5 | fn g | -| main.rs:1118:5:1118:6 | m9 | main.rs:207:1:215:1 | mod m9 | -| main.rs:1118:5:1118:9 | ...::f | main.rs:210:5:214:5 | fn f | -| main.rs:1119:5:1119:7 | m11 | main.rs:238:1:275:1 | mod m11 | -| main.rs:1119:5:1119:10 | ...::f | main.rs:243:5:246:5 | fn f | -| main.rs:1120:5:1120:7 | m15 | main.rs:306:1:375:1 | mod m15 | -| main.rs:1120:5:1120:10 | ...::f | main.rs:362:5:374:5 | fn f | -| main.rs:1121:5:1121:7 | m16 | main.rs:377:1:575:1 | mod m16 | -| main.rs:1121:5:1121:10 | ...::f | main.rs:447:5:471:5 | fn f | -| main.rs:1122:5:1122:20 | trait_visibility | main.rs:577:1:634:1 | mod trait_visibility | -| main.rs:1122:5:1122:23 | ...::f | main.rs:604:5:633:5 | fn f | -| main.rs:1123:5:1123:7 | m17 | main.rs:636:1:666:1 | mod m17 | -| main.rs:1123:5:1123:10 | ...::f | main.rs:660:5:665:5 | fn f | -| main.rs:1124:5:1124:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | -| main.rs:1124:5:1124:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | -| main.rs:1125:5:1125:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | -| main.rs:1125:5:1125:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | -| main.rs:1126:5:1126:7 | my3 | my2/mod.rs:20:1:20:12 | mod my3 | -| main.rs:1126:5:1126:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | -| main.rs:1127:5:1127:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | -| main.rs:1128:5:1128:12 | my_alias | main.rs:1:1:1:7 | mod my | -| main.rs:1128:5:1128:22 | ...::nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | -| main.rs:1129:5:1129:7 | m18 | main.rs:668:1:686:1 | mod m18 | -| main.rs:1129:5:1129:12 | ...::m19 | main.rs:673:5:685:5 | mod m19 | -| main.rs:1129:5:1129:17 | ...::m20 | main.rs:678:9:684:9 | mod m20 | -| main.rs:1129:5:1129:20 | ...::g | main.rs:679:13:683:13 | fn g | -| main.rs:1130:5:1130:7 | m23 | main.rs:715:1:740:1 | mod m23 | -| main.rs:1130:5:1130:10 | ...::f | main.rs:735:5:739:5 | fn f | -| main.rs:1131:5:1131:7 | m24 | main.rs:742:1:810:1 | mod m24 | -| main.rs:1131:5:1131:10 | ...::f | main.rs:796:5:809:5 | fn f | -| main.rs:1132:5:1132:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) | -| main.rs:1132:5:1132:11 | ...::h | main.rs:57:1:76:1 | fn h | -| main.rs:1133:5:1133:13 | z_changed | main.rs:815:1:815:9 | fn z_changed | -| main.rs:1134:5:1134:11 | AStruct | main.rs:817:1:817:17 | struct AStruct | -| main.rs:1134:5:1134:22 | ...::z_on_type | main.rs:821:5:821:17 | fn z_on_type | -| main.rs:1135:5:1135:11 | AStruct | main.rs:817:1:817:17 | struct AStruct | -| main.rs:1136:5:1136:29 | impl_with_attribute_macro | main.rs:960:1:979:1 | mod impl_with_attribute_macro | -| main.rs:1136:5:1136:35 | ...::test | main.rs:975:5:978:5 | fn test | -| main.rs:1137:5:1137:12 | patterns | main.rs:981:1:1022:1 | mod patterns | -| main.rs:1137:5:1137:18 | ...::test | main.rs:982:5:996:5 | fn test | +| main.rs:1103:9:1103:13 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | +| main.rs:1103:9:1103:27 | ...::const_static | main.rs:1101:1:1145:1 | mod const_static | +| main.rs:1105:27:1105:29 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:1107:29:1107:31 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:1110:17:1110:26 | CONST_ITEM | main.rs:1105:5:1105:35 | const CONST_ITEM | +| main.rs:1111:17:1111:27 | STATIC_ITEM | main.rs:1107:5:1107:37 | static STATIC_ITEM | +| main.rs:1112:17:1112:28 | const_static | main.rs:1101:1:1145:1 | mod const_static | +| main.rs:1112:17:1112:40 | ...::CONST_ITEM | main.rs:1105:5:1105:35 | const CONST_ITEM | +| main.rs:1113:17:1113:28 | const_static | main.rs:1101:1:1145:1 | mod const_static | +| main.rs:1113:17:1113:41 | ...::STATIC_ITEM | main.rs:1107:5:1107:37 | static STATIC_ITEM | +| main.rs:1114:17:1114:27 | CONST_ALIAS | main.rs:1117:9:1118:13 | const CONST_ALIAS | +| main.rs:1115:17:1115:28 | STATIC_ALIAS | main.rs:1118:15:1120:13 | static STATIC_ALIAS | +| main.rs:1117:28:1117:30 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:1117:34:1117:43 | CONST_ITEM | main.rs:1105:5:1105:35 | const CONST_ITEM | +| main.rs:1119:30:1119:32 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:1119:36:1119:46 | STATIC_ITEM | main.rs:1107:5:1107:37 | static STATIC_ITEM | +| main.rs:1122:17:1122:27 | CONST_ALIAS | main.rs:1117:9:1118:13 | const CONST_ALIAS | +| main.rs:1123:17:1123:28 | STATIC_ALIAS | main.rs:1118:15:1120:13 | static STATIC_ALIAS | +| main.rs:1126:32:1126:34 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:1126:38:1126:47 | CONST_ITEM | main.rs:1105:5:1105:35 | const CONST_ITEM | +| main.rs:1128:34:1128:36 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:1128:40:1128:50 | STATIC_ITEM | main.rs:1107:5:1107:37 | static STATIC_ITEM | +| main.rs:1131:21:1131:31 | CONST_ALIAS | main.rs:1126:13:1127:17 | const CONST_ALIAS | +| main.rs:1132:21:1132:32 | STATIC_ALIAS | main.rs:1127:19:1129:17 | static STATIC_ALIAS | +| main.rs:1136:32:1136:34 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:1136:38:1136:47 | CONST_ITEM | main.rs:1105:5:1105:35 | const CONST_ITEM | +| main.rs:1138:34:1138:36 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:1138:40:1138:50 | STATIC_ITEM | main.rs:1107:5:1107:37 | static STATIC_ITEM | +| main.rs:1141:21:1141:31 | CONST_ALIAS | main.rs:1136:13:1137:17 | const CONST_ALIAS | +| main.rs:1142:21:1142:32 | STATIC_ALIAS | main.rs:1137:19:1139:17 | static STATIC_ALIAS | +| main.rs:1148:5:1148:6 | my | main.rs:1:1:1:7 | mod my | +| main.rs:1148:5:1148:14 | ...::nested | my.rs:1:1:1:15 | mod nested | +| main.rs:1148:5:1148:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | +| main.rs:1148:5:1148:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 | +| main.rs:1148:5:1148:35 | ...::f | my/nested.rs:3:9:5:9 | fn f | +| main.rs:1149:5:1149:6 | my | main.rs:1:1:1:7 | mod my | +| main.rs:1149:5:1149:9 | ...::f | my.rs:5:1:7:1 | fn f | +| main.rs:1150:5:1150:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | +| main.rs:1150:5:1150:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | +| main.rs:1150:5:1150:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | +| main.rs:1150:5:1150:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:1151:5:1151:5 | f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:1152:5:1152:5 | g | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:1153:5:1153:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | +| main.rs:1153:5:1153:12 | ...::h | main.rs:57:1:76:1 | fn h | +| main.rs:1154:5:1154:6 | m1 | main.rs:20:1:44:1 | mod m1 | +| main.rs:1154:5:1154:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 | +| main.rs:1154:5:1154:13 | ...::g | main.rs:30:9:34:9 | fn g | +| main.rs:1155:5:1155:6 | m1 | main.rs:20:1:44:1 | mod m1 | +| main.rs:1155:5:1155:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 | +| main.rs:1155:5:1155:14 | ...::m3 | main.rs:36:9:42:9 | mod m3 | +| main.rs:1155:5:1155:17 | ...::h | main.rs:37:27:41:13 | fn h | +| main.rs:1156:5:1156:6 | m4 | main.rs:46:1:53:1 | mod m4 | +| main.rs:1156:5:1156:9 | ...::i | main.rs:49:5:52:5 | fn i | +| main.rs:1157:5:1157:5 | h | main.rs:57:1:76:1 | fn h | +| main.rs:1158:5:1158:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:1159:5:1159:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:1160:5:1160:5 | j | main.rs:104:1:108:1 | fn j | +| main.rs:1161:5:1161:6 | m6 | main.rs:116:1:128:1 | mod m6 | +| main.rs:1161:5:1161:9 | ...::g | main.rs:121:5:127:5 | fn g | +| main.rs:1162:5:1162:6 | m7 | main.rs:130:1:149:1 | mod m7 | +| main.rs:1162:5:1162:9 | ...::f | main.rs:141:5:148:5 | fn f | +| main.rs:1163:5:1163:6 | m8 | main.rs:151:1:205:1 | mod m8 | +| main.rs:1163:5:1163:9 | ...::g | main.rs:189:5:204:5 | fn g | +| main.rs:1164:5:1164:6 | m9 | main.rs:207:1:215:1 | mod m9 | +| main.rs:1164:5:1164:9 | ...::f | main.rs:210:5:214:5 | fn f | +| main.rs:1165:5:1165:7 | m11 | main.rs:238:1:275:1 | mod m11 | +| main.rs:1165:5:1165:10 | ...::f | main.rs:243:5:246:5 | fn f | +| main.rs:1166:5:1166:7 | m15 | main.rs:306:1:375:1 | mod m15 | +| main.rs:1166:5:1166:10 | ...::f | main.rs:362:5:374:5 | fn f | +| main.rs:1167:5:1167:7 | m16 | main.rs:377:1:575:1 | mod m16 | +| main.rs:1167:5:1167:10 | ...::f | main.rs:447:5:471:5 | fn f | +| main.rs:1168:5:1168:20 | trait_visibility | main.rs:577:1:634:1 | mod trait_visibility | +| main.rs:1168:5:1168:23 | ...::f | main.rs:604:5:633:5 | fn f | +| main.rs:1169:5:1169:7 | m17 | main.rs:636:1:666:1 | mod m17 | +| main.rs:1169:5:1169:10 | ...::f | main.rs:660:5:665:5 | fn f | +| main.rs:1170:5:1170:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | +| main.rs:1170:5:1170:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | +| main.rs:1171:5:1171:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | +| main.rs:1171:5:1171:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | +| main.rs:1172:5:1172:7 | my3 | my2/mod.rs:20:1:20:12 | mod my3 | +| main.rs:1172:5:1172:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | +| main.rs:1173:5:1173:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | +| main.rs:1174:5:1174:12 | my_alias | main.rs:1:1:1:7 | mod my | +| main.rs:1174:5:1174:22 | ...::nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | +| main.rs:1175:5:1175:7 | m18 | main.rs:668:1:686:1 | mod m18 | +| main.rs:1175:5:1175:12 | ...::m19 | main.rs:673:5:685:5 | mod m19 | +| main.rs:1175:5:1175:17 | ...::m20 | main.rs:678:9:684:9 | mod m20 | +| main.rs:1175:5:1175:20 | ...::g | main.rs:679:13:683:13 | fn g | +| main.rs:1176:5:1176:7 | m23 | main.rs:715:1:740:1 | mod m23 | +| main.rs:1176:5:1176:10 | ...::f | main.rs:735:5:739:5 | fn f | +| main.rs:1177:5:1177:7 | m24 | main.rs:742:1:810:1 | mod m24 | +| main.rs:1177:5:1177:10 | ...::f | main.rs:796:5:809:5 | fn f | +| main.rs:1178:5:1178:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) | +| main.rs:1178:5:1178:11 | ...::h | main.rs:57:1:76:1 | fn h | +| main.rs:1179:5:1179:13 | z_changed | main.rs:815:1:815:9 | fn z_changed | +| main.rs:1180:5:1180:11 | AStruct | main.rs:817:1:817:17 | struct AStruct | +| main.rs:1180:5:1180:22 | ...::z_on_type | main.rs:821:5:821:17 | fn z_on_type | +| main.rs:1181:5:1181:11 | AStruct | main.rs:817:1:817:17 | struct AStruct | +| main.rs:1182:5:1182:29 | impl_with_attribute_macro | main.rs:960:1:979:1 | mod impl_with_attribute_macro | +| main.rs:1182:5:1182:35 | ...::test | main.rs:975:5:978:5 | fn test | +| main.rs:1183:5:1183:12 | patterns | main.rs:981:1:1022:1 | mod patterns | +| main.rs:1183:5:1183:18 | ...::test | main.rs:982:5:996:5 | fn test | | my2/mod.rs:4:5:4:11 | println | {EXTERNAL LOCATION} | MacroRules | | my2/mod.rs:5:5:5:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | | my2/mod.rs:5:5:5:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | @@ -680,7 +711,7 @@ resolvePath | my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g | | my2/my3/mod.rs:4:5:4:5 | h | main.rs:57:1:76:1 | fn h | | my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:25:34 | SourceFile | -| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:1138:2 | SourceFile | +| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:1184:2 | SourceFile | | my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:57:1:76:1 | fn h | | my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:25:34 | SourceFile | | my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g | diff --git a/rust/ql/test/library-tests/static_access/Cargo.lock b/rust/ql/test/library-tests/static_access/Cargo.lock new file mode 100644 index 00000000000..b9856cfaf77 --- /dev/null +++ b/rust/ql/test/library-tests/static_access/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "test" +version = "0.0.1" diff --git a/rust/ql/test/library-tests/static_access/main.rs b/rust/ql/test/library-tests/static_access/main.rs new file mode 100644 index 00000000000..33f170874cf --- /dev/null +++ b/rust/ql/test/library-tests/static_access/main.rs @@ -0,0 +1,33 @@ +static GLOBAL_STATIC: i32 = 42; +static STRING_STATIC: &str = "hello"; + +mod my_module { + pub static MODULE_STATIC: i32 = 200; +} + +fn use_statics() { + let x = GLOBAL_STATIC; // $ static_access=GLOBAL_STATIC + + let s = STRING_STATIC; // $ static_access=STRING_STATIC + + let z = my_module::MODULE_STATIC; // $ static_access=MODULE_STATIC + + #[rustfmt::skip] + let _ = if GLOBAL_STATIC > 0 { // $ static_access=GLOBAL_STATIC + println!("positive"); + }; + + { + static STRING_STATIC: &str = "inner"; // Inner1 + let _ = STRING_STATIC; // $ static_access=Inner1 + + { + static STRING_STATIC: &str = "inner2"; // Inner2 + let _ = STRING_STATIC; // $ static_access=Inner2 + } + } +} + +fn main() { + use_statics(); +} diff --git a/rust/ql/test/library-tests/static_access/static_access.expected b/rust/ql/test/library-tests/static_access/static_access.expected new file mode 100644 index 00000000000..893b356418f --- /dev/null +++ b/rust/ql/test/library-tests/static_access/static_access.expected @@ -0,0 +1,8 @@ +testFailures +staticAccess +| main.rs:9:13:9:25 | GLOBAL_STATIC | main.rs:1:1:1:31 | static GLOBAL_STATIC | +| main.rs:11:13:11:25 | STRING_STATIC | main.rs:2:1:2:37 | static STRING_STATIC | +| main.rs:13:13:13:36 | ...::MODULE_STATIC | main.rs:5:5:5:40 | static MODULE_STATIC | +| main.rs:16:16:16:28 | GLOBAL_STATIC | main.rs:1:1:1:31 | static GLOBAL_STATIC | +| main.rs:22:17:22:29 | STRING_STATIC | main.rs:21:9:21:45 | static STRING_STATIC | +| main.rs:26:21:26:33 | STRING_STATIC | main.rs:25:13:25:50 | static STRING_STATIC | diff --git a/rust/ql/test/library-tests/static_access/static_access.ql b/rust/ql/test/library-tests/static_access/static_access.ql new file mode 100644 index 00000000000..d755bf5a350 --- /dev/null +++ b/rust/ql/test/library-tests/static_access/static_access.ql @@ -0,0 +1,31 @@ +import rust +import utils.test.InlineExpectationsTest +import TestUtils + +query predicate staticAccess(StaticAccess sa, Static s) { toBeTested(sa) and s = sa.getStatic() } + +module StaticAccessTest implements TestSig { + private predicate staticAt(Static s, string filepath, int line) { + s.getLocation().hasLocationInfo(filepath, _, _, line, _) + } + + string getARelevantTag() { result = "static_access" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(StaticAccess sa, Static s, string filepath, int line | + toBeTested(sa) and + location = sa.getLocation() and + element = sa.toString() and + tag = "static_access" and + s = sa.getStatic() and + staticAt(s, filepath, line) + | + commmentAt(value, filepath, line) + or + not commmentAt(_, filepath, line) and + value = s.getName().getText() + ) + } +} + +import MakeTest diff --git a/rust/ql/test/library-tests/variables/variables.ql b/rust/ql/test/library-tests/variables/variables.ql index 9997b29c7d0..8380512d99f 100644 --- a/rust/ql/test/library-tests/variables/variables.ql +++ b/rust/ql/test/library-tests/variables/variables.ql @@ -38,13 +38,6 @@ module VariableAccessTest implements TestSig { if v.getPat().isFromMacroExpansion() then inMacro = true else inMacro = false } - private predicate commmentAt(string text, string filepath, int line) { - exists(Comment c | - c.getLocation().hasLocationInfo(filepath, line, _, _, _) and - c.getCommentText().trim() = text - ) - } - private predicate decl(Variable v, string value) { exists(string filepath, int line, boolean inMacro | declAt(v, filepath, line, inMacro) | commmentAt(value, filepath, line) and inMacro = false From c4e3720d8ac899c72973708427cafc01bf786b10 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 1 Jun 2026 13:57:28 +0200 Subject: [PATCH 187/226] Rust: Run codegen --- rust/ql/.generated.list | 1 - rust/ql/.gitattributes | 1 - rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 87cd5eb4808..0550763ed0c 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -373,7 +373,6 @@ lib/codeql/rust/elements/internal/SliceTypeReprImpl.qll ba1a53a3ecc90a7f54c003fc lib/codeql/rust/elements/internal/SourceFileConstructor.qll 1dc559887ea7798774528b5505c8601c61030c17480f7ffca49b68b76fcc0321 75a635b88622e3110b16795bd12ca6fc4af176c92d6e441518d60aa47255edc1 lib/codeql/rust/elements/internal/SourceFileImpl.qll 829cc59d508c190fecfcfb0e27df232fd0a53cb98a6c6f110aecc7242db6f794 2834ab836557ae294410ccde023cca6ef6315aa4b78a7c238862437cec697583 lib/codeql/rust/elements/internal/StaticConstructor.qll 6dd7ee3fd16466c407de35b439074b56341fc97a9c36846b725c2eb43fd4a643 5bf5b0e78d0e9eb294a57b91075de6e4b86a9e6335f546c83ec11ab4c51e5679 -lib/codeql/rust/elements/internal/StaticImpl.qll 48071e29c72032b59ad82771d54be92ac0f4c1a68fb1129c5c7991385804d7b1 85c0be8e37a91d6e775b191f0cb52dd8bf70418e6e9947b82c58c40a6d73b406 lib/codeql/rust/elements/internal/StmtImpl.qll ea99d261f32592ff368cc3a1960864989897c92944f1675549e0753964cb562f 9117b4cdfad56f8fa3bc5d921c2146b4ff0658e8914ac51bf48eb3e68599dd6b lib/codeql/rust/elements/internal/StmtListConstructor.qll 435d59019e17a6279110a23d3d5dfbc1d1e16fc358a93a1d688484d22a754866 23fcb60a5cbb66174e459bc10bd7c28ed532fd1ab46f10b9f0c8a6291d3e343f lib/codeql/rust/elements/internal/StructConstructor.qll 52921ea6e70421fd08884dc061d0c2dfbbb8dd83d98f1f3c70572cfe57b2a173 dcb3ea8e45ee875525c645fe5d08e6db9013b86bd351c77df4590d0c1439ab9f diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 6ea7d011a5d..e88e5d2d960 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -375,7 +375,6 @@ /lib/codeql/rust/elements/internal/SourceFileConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/SourceFileImpl.qll linguist-generated /lib/codeql/rust/elements/internal/StaticConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/StaticImpl.qll linguist-generated /lib/codeql/rust/elements/internal/StmtImpl.qll linguist-generated /lib/codeql/rust/elements/internal/StmtListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/StructConstructor.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll index 7eb08653d2d..42045aea684 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll @@ -14,6 +14,7 @@ private import codeql.rust.internal.PathResolution * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A static item declaration. * From 1fd31d0ddd2983d52cdef650b7b37374a4edcf61 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 1 Jun 2026 20:21:02 +0200 Subject: [PATCH 188/226] Rust: Data flow for `const`s and `static`s --- .../internal/ControlFlowGraphImpl.qll | 2 ++ .../rust/controlflow/internal/Scope.qll | 11 ++++++++ .../rust/dataflow/internal/DataFlowImpl.qll | 16 ++++++++++- .../codeql/rust/dataflow/internal/Node.qll | 14 +++++++++- .../lib/codeql/rust/elements/StaticAccess.qll | 4 +++ .../rust/elements/internal/AstNodeImpl.qll | 16 ++++++++++- .../rust/elements/internal/ConstImpl.qll | 3 ++ .../rust/elements/internal/StaticImpl.qll | 14 ++++++++++ .../library-tests/controlflow/Cfg.expected | 3 +- .../dataflow/global/inline-flow.expected | 25 +++++++++++++++++ .../library-tests/dataflow/global/main.rs | 21 +++++++++++++- .../dataflow/global/viableCallable.expected | 28 +++++++++++-------- .../dataflow/global/viableCallable.ql | 3 +- .../dataflow/local/DataFlowStep.expected | 2 -- .../dataflow/local/DataFlowStep.ql | 4 ++- 15 files changed, 145 insertions(+), 21 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 16e14ce84a2..f8a182685b6 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -99,6 +99,8 @@ class FormatTemplateVariableAccessTree extends LeafTree, FormatTemplateVariableA class ItemTree extends LeafTree, Item { ItemTree() { not this instanceof MacroCall and + not this instanceof Const and + not this instanceof Static and this = any(StmtList s).getAStatement() } } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll index 94c5300b062..303920ce7d0 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll @@ -45,3 +45,14 @@ final class CallableScope extends CfgScopeImpl, Callable { /** Holds if `scope` is exited when `last` finishes with completion `c`. */ override predicate scopeLast(AstNode last, Completion c) { last(this.getBody(), last, c) } } + +/** + * A special scope used to represent the context in which `const`s and + * `static`s are initialized. We do not actually compute a CFG for such + * scopes. + */ +final class SourceFileScope extends CfgScopeImpl, SourceFile { + override predicate scopeFirst(AstNode first) { none() } + + override predicate scopeLast(AstNode last, Completion c) { none() } +} diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 4ad3af0f42a..a7e2e2e4c6b 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -653,8 +653,22 @@ module RustDataFlowGen implements InputSig */ predicate jumpStep(Node node1, Node node2) { FlowSummaryImpl::Private::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(), - node2.(FlowSummaryNode).getSummaryNode()) or + node2.(FlowSummaryNode).getSummaryNode()) + or FlowSummaryImpl::Private::Steps::sourceJumpStep(node1.(FlowSummaryNode).getSummaryNode(), node2) + or + exists(Const c | + node1.asExpr() = c.getBody() and + node2.asExpr() = c.getAnAccess() + ) + or + exists(StaticNode sn, Static s | s = sn.getStatic() | + node1 = sn and + node2.asExpr() = s.getAnAccess().(StaticReadAccess) + or + node1.asExpr() = [s.getBody(), s.getAnAccess().(StaticWriteAccess)] and + node2 = sn + ) } pragma[nomagic] diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll index 1ccb7db73f5..9ef2c3a08fa 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll @@ -704,6 +704,17 @@ final class CastNode extends ExprNode { CastNode() { none() } } +/** + * A node in the data flow graph that corresponds to a `static`. + */ +class StaticNode extends AstNodeNode, TStaticNode { + override Static n; + + StaticNode() { this = TStaticNode(n) } + + Static getStatic() { result = n } +} + cached newtype TNode = TExprNode(Expr e) { e.hasEnclosingCfgScope() and Stages::DataFlowStage::ref() } or @@ -755,4 +766,5 @@ newtype TNode = ) } or TClosureSelfReferenceNode(CfgScope c) { lambdaCreationExpr(c) } or - TCaptureNode(VariableCapture::Flow::SynthesizedCaptureNode cn) + TCaptureNode(VariableCapture::Flow::SynthesizedCaptureNode cn) or + TStaticNode(Static s) diff --git a/rust/ql/lib/codeql/rust/elements/StaticAccess.qll b/rust/ql/lib/codeql/rust/elements/StaticAccess.qll index 50b4bea14d1..f0171a23771 100644 --- a/rust/ql/lib/codeql/rust/elements/StaticAccess.qll +++ b/rust/ql/lib/codeql/rust/elements/StaticAccess.qll @@ -5,3 +5,7 @@ private import internal.StaticImpl final class StaticAccess = Impl::StaticAccess; + +final class StaticWriteAccess = Impl::StaticWriteAccess; + +final class StaticReadAccess = Impl::StaticReadAccess; diff --git a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll index 554942f0fdd..0c9d736cc57 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll @@ -48,15 +48,29 @@ module Impl { ) } + pragma[nomagic] + private predicate isConstOrStatic(File f) { + f = this.getFile() and + ( + this instanceof Const + or + this instanceof Static + ) + } + /** Gets the CFG scope that encloses this node, if any. */ cached CfgScope getEnclosingCfgScope() { exists(AstNode p | p = this.getParentNode() | - result = p + result = p and + not result instanceof SourceFile or not p instanceof CfgScope and + not this.isConstOrStatic(_) and result = p.getEnclosingCfgScope() ) + or + this.isConstOrStatic(result.(SourceFile).getFile()) } /** Holds if this node is inside a CFG scope. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll index 776215ee4f4..e90ae621779 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll @@ -25,6 +25,9 @@ module Impl { * ``` */ class Const extends Generated::Const { + /** Gets an access to this constant item. */ + ConstAccess getAnAccess() { this = result.getConst() } + override string toStringImpl() { result = "const " + this.getName().getText() } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll index 42045aea684..8002947bae8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StaticImpl.qll @@ -7,6 +7,7 @@ private import codeql.rust.elements.internal.generated.Static private import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl private import codeql.rust.elements.internal.PathExprImpl::Impl as PathExprImpl +private import codeql.rust.elements.internal.VariableImpl::Impl as VariableImpl private import codeql.rust.internal.PathResolution /** @@ -24,6 +25,9 @@ module Impl { * ``` */ class Static extends Generated::Static { + /** Gets an access to this static item. */ + StaticAccess getAnAccess() { this = result.getStatic() } + override string toStringImpl() { result = "static " + this.getName().getText() } } @@ -49,4 +53,14 @@ module Impl { override string getAPrimaryQlClass() { result = "StaticAccess" } } + + /** A static write access. */ + class StaticWriteAccess extends StaticAccess { + StaticWriteAccess() { VariableImpl::assignmentOperationDescendant(_, this) } + } + + /** A static read access. */ + class StaticReadAccess extends StaticAccess { + StaticReadAccess() { not this instanceof StaticWriteAccess } + } } diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 438b841ff16..2d1036c93c9 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1317,10 +1317,9 @@ edges | test.rs:533:21:533:48 | { ... } | test.rs:533:21:533:48 | { ... } | | | test.rs:533:48:533:48 | 0 | test.rs:533:21:533:48 | ... > ... | | | test.rs:536:9:536:10 | 42 | test.rs:529:41:537:5 | { ... } | | -| test.rs:539:5:548:5 | enter fn const_block_panic | test.rs:540:9:540:30 | const N | | +| test.rs:539:5:548:5 | enter fn const_block_panic | test.rs:541:9:546:9 | ExprStmt | | | test.rs:539:5:548:5 | exit fn const_block_panic (normal) | test.rs:539:5:548:5 | exit fn const_block_panic | | | test.rs:539:35:548:5 | { ... } | test.rs:539:5:548:5 | exit fn const_block_panic (normal) | | -| test.rs:540:9:540:30 | const N | test.rs:541:9:546:9 | ExprStmt | | | test.rs:541:9:546:9 | ExprStmt | test.rs:541:12:541:16 | false | | | test.rs:541:9:546:9 | if false {...} | test.rs:547:9:547:9 | N | | | test.rs:541:12:541:16 | false | test.rs:541:9:546:9 | if false {...} | false | diff --git a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected index 5caa5c1c3ed..4828b56542b 100644 --- a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected @@ -222,6 +222,15 @@ edges | main.rs:415:18:415:38 | i.get_double_number() | main.rs:415:13:415:14 | n4 | provenance | | | main.rs:418:13:418:14 | n5 | main.rs:419:14:419:15 | n5 | provenance | | | main.rs:418:18:418:41 | ...::get_default(...) | main.rs:418:13:418:14 | n5 | provenance | | +| main.rs:426:30:426:39 | source(...) | main.rs:430:35:430:45 | CONST_VALUE | provenance | | +| main.rs:427:5:427:46 | static STATIC_VALUE | main.rs:433:32:433:43 | STATIC_VALUE | provenance | | +| main.rs:427:5:427:46 | static STATIC_VALUE | main.rs:437:18:437:29 | STATIC_VALUE | provenance | | +| main.rs:427:36:427:45 | source(...) | main.rs:427:5:427:46 | static STATIC_VALUE | provenance | | +| main.rs:430:35:430:45 | CONST_VALUE | main.rs:431:14:431:25 | CONST_VALUE2 | provenance | | +| main.rs:433:17:433:28 | static_value | main.rs:434:18:434:29 | static_value | provenance | | +| main.rs:433:32:433:43 | STATIC_VALUE | main.rs:433:17:433:28 | static_value | provenance | | +| main.rs:436:13:436:24 | STATIC_VALUE | main.rs:427:5:427:46 | static STATIC_VALUE | provenance | | +| main.rs:436:28:436:37 | source(...) | main.rs:436:13:436:24 | STATIC_VALUE | provenance | | nodes | main.rs:12:28:14:1 | { ... } | semmle.label | { ... } | | main.rs:13:5:13:13 | source(...) | semmle.label | source(...) | @@ -464,6 +473,17 @@ nodes | main.rs:418:13:418:14 | n5 | semmle.label | n5 | | main.rs:418:18:418:41 | ...::get_default(...) | semmle.label | ...::get_default(...) | | main.rs:419:14:419:15 | n5 | semmle.label | n5 | +| main.rs:426:30:426:39 | source(...) | semmle.label | source(...) | +| main.rs:427:5:427:46 | static STATIC_VALUE | semmle.label | static STATIC_VALUE | +| main.rs:427:36:427:45 | source(...) | semmle.label | source(...) | +| main.rs:430:35:430:45 | CONST_VALUE | semmle.label | CONST_VALUE | +| main.rs:431:14:431:25 | CONST_VALUE2 | semmle.label | CONST_VALUE2 | +| main.rs:433:17:433:28 | static_value | semmle.label | static_value | +| main.rs:433:32:433:43 | STATIC_VALUE | semmle.label | STATIC_VALUE | +| main.rs:434:18:434:29 | static_value | semmle.label | static_value | +| main.rs:436:13:436:24 | STATIC_VALUE | semmle.label | STATIC_VALUE | +| main.rs:436:28:436:37 | source(...) | semmle.label | source(...) | +| main.rs:437:18:437:29 | STATIC_VALUE | semmle.label | STATIC_VALUE | subpaths | main.rs:38:16:38:24 | source(...) | main.rs:26:28:26:33 | ...: i64 | main.rs:26:17:26:25 | SelfParam [Return] [&ref, MyStruct] | main.rs:38:5:38:5 | [post] a [MyStruct] | | main.rs:39:10:39:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | main.rs:30:31:32:5 | { ... } | main.rs:39:10:39:21 | a.get_data() | @@ -525,3 +545,8 @@ testFailures | main.rs:412:14:412:15 | n3 | main.rs:371:13:371:21 | source(...) | main.rs:412:14:412:15 | n3 | $@ | main.rs:371:13:371:21 | source(...) | source(...) | | main.rs:416:14:416:15 | n4 | main.rs:391:13:391:22 | source(...) | main.rs:416:14:416:15 | n4 | $@ | main.rs:391:13:391:22 | source(...) | source(...) | | main.rs:419:14:419:15 | n5 | main.rs:395:13:395:21 | source(...) | main.rs:419:14:419:15 | n5 | $@ | main.rs:395:13:395:21 | source(...) | source(...) | +| main.rs:431:14:431:25 | CONST_VALUE2 | main.rs:426:30:426:39 | source(...) | main.rs:431:14:431:25 | CONST_VALUE2 | $@ | main.rs:426:30:426:39 | source(...) | source(...) | +| main.rs:434:18:434:29 | static_value | main.rs:427:36:427:45 | source(...) | main.rs:434:18:434:29 | static_value | $@ | main.rs:427:36:427:45 | source(...) | source(...) | +| main.rs:434:18:434:29 | static_value | main.rs:436:28:436:37 | source(...) | main.rs:434:18:434:29 | static_value | $@ | main.rs:436:28:436:37 | source(...) | source(...) | +| main.rs:437:18:437:29 | STATIC_VALUE | main.rs:427:36:427:45 | source(...) | main.rs:437:18:437:29 | STATIC_VALUE | $@ | main.rs:427:36:427:45 | source(...) | source(...) | +| main.rs:437:18:437:29 | STATIC_VALUE | main.rs:436:28:436:37 | source(...) | main.rs:437:18:437:29 | STATIC_VALUE | $@ | main.rs:436:28:436:37 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/global/main.rs b/rust/ql/test/library-tests/dataflow/global/main.rs index ac737570771..b3a3af1be95 100644 --- a/rust/ql/test/library-tests/dataflow/global/main.rs +++ b/rust/ql/test/library-tests/dataflow/global/main.rs @@ -1,4 +1,4 @@ -fn source(i: i64) -> i64 { +const fn source(i: i64) -> i64 { 1000 + i } @@ -420,6 +420,25 @@ mod not_trait_dispatch { } } +mod const_static { + use super::{sink, source}; + + const CONST_VALUE: i64 = source(42); + static mut STATIC_VALUE: i64 = source(43); + + fn test_const_static() { + const CONST_VALUE2: i64 = CONST_VALUE; + sink(CONST_VALUE2); // $ hasValueFlow=42 + unsafe { + let static_value = STATIC_VALUE; + sink(static_value); // $ hasValueFlow=43 $ SPURIOUS: hasValueFlow=44 (statics are not control-flow sensitive) + + STATIC_VALUE = source(44); + sink(STATIC_VALUE); // $ hasValueFlow=44 $ SPURIOUS: hasValueFlow=43 (statics are not control-flow sensitive) + } + } +} + fn main() { data_out_of_call(); data_out_of_call_side_effect1(); diff --git a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected index 26db4dc3962..6f30416d54a 100644 --- a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected +++ b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected @@ -128,14 +128,20 @@ | main.rs:416:9:416:16 | sink(...) | main.rs:5:1:7:1 | fn sink | | main.rs:418:18:418:41 | ...::get_default(...) | main.rs:394:9:396:9 | fn get_default | | main.rs:419:9:419:16 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:424:5:424:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call | -| main.rs:425:5:425:35 | data_out_of_call_side_effect1(...) | main.rs:35:1:40:1 | fn data_out_of_call_side_effect1 | -| main.rs:426:5:426:35 | data_out_of_call_side_effect2(...) | main.rs:42:1:50:1 | fn data_out_of_call_side_effect2 | -| main.rs:427:5:427:21 | data_in_to_call(...) | main.rs:56:1:59:1 | fn data_in_to_call | -| main.rs:428:5:428:23 | data_through_call(...) | main.rs:65:1:69:1 | fn data_through_call | -| main.rs:429:5:429:34 | data_through_nested_function(...) | main.rs:79:1:88:1 | fn data_through_nested_function | -| main.rs:431:5:431:24 | data_out_of_method(...) | main.rs:152:1:162:1 | fn data_out_of_method | -| main.rs:432:5:432:28 | data_in_to_method_call(...) | main.rs:169:1:179:1 | fn data_in_to_method_call | -| main.rs:433:5:433:25 | data_through_method(...) | main.rs:187:1:199:1 | fn data_through_method | -| main.rs:435:5:435:31 | test_operator_overloading(...) | main.rs:256:1:298:1 | fn test_operator_overloading | -| main.rs:436:5:436:22 | test_async_await(...) | main.rs:353:1:358:1 | fn test_async_await | +| main.rs:426:30:426:39 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:427:36:427:45 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:431:9:431:26 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:434:13:434:30 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:436:28:436:37 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:437:13:437:30 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:443:5:443:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call | +| main.rs:444:5:444:35 | data_out_of_call_side_effect1(...) | main.rs:35:1:40:1 | fn data_out_of_call_side_effect1 | +| main.rs:445:5:445:35 | data_out_of_call_side_effect2(...) | main.rs:42:1:50:1 | fn data_out_of_call_side_effect2 | +| main.rs:446:5:446:21 | data_in_to_call(...) | main.rs:56:1:59:1 | fn data_in_to_call | +| main.rs:447:5:447:23 | data_through_call(...) | main.rs:65:1:69:1 | fn data_through_call | +| main.rs:448:5:448:34 | data_through_nested_function(...) | main.rs:79:1:88:1 | fn data_through_nested_function | +| main.rs:450:5:450:24 | data_out_of_method(...) | main.rs:152:1:162:1 | fn data_out_of_method | +| main.rs:451:5:451:28 | data_in_to_method_call(...) | main.rs:169:1:179:1 | fn data_in_to_method_call | +| main.rs:452:5:452:25 | data_through_method(...) | main.rs:187:1:199:1 | fn data_through_method | +| main.rs:454:5:454:31 | test_operator_overloading(...) | main.rs:256:1:298:1 | fn test_operator_overloading | +| main.rs:455:5:455:22 | test_async_await(...) | main.rs:353:1:358:1 | fn test_async_await | diff --git a/rust/ql/test/library-tests/dataflow/global/viableCallable.ql b/rust/ql/test/library-tests/dataflow/global/viableCallable.ql index 3daa8b4b17f..dbb49e4855d 100644 --- a/rust/ql/test/library-tests/dataflow/global/viableCallable.ql +++ b/rust/ql/test/library-tests/dataflow/global/viableCallable.ql @@ -1,5 +1,6 @@ import codeql.rust.dataflow.internal.DataFlowImpl query predicate viableCallable(DataFlowCall call, DataFlowCallable callee) { - RustDataFlow::viableCallable(call) = callee + RustDataFlow::viableCallable(call) = callee and + (call.asCall().fromSource() or call.isImplicitDerefCall(_, _, _, _)) } diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index e220a769ece..7d70ff90eaa 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -1,6 +1,4 @@ localStep -| file://:0:0:0:0 | [summary param] 0 in fn canonicalize | file://:0:0:0:0 | [summary] read: Argument[0].OptionalBarrier[normalize-path] in fn canonicalize | -| file://:0:0:0:0 | [summary] read: Argument[self].Reference in fn canonicalize | file://:0:0:0:0 | [summary] read: Argument[self].Reference.OptionalBarrier[normalize-path] in fn canonicalize | | main.rs:4:11:4:11 | [SSA] i | main.rs:5:12:5:12 | i | | main.rs:4:11:4:11 | i | main.rs:4:11:4:11 | [SSA] i | | main.rs:4:11:4:11 | i | main.rs:4:11:4:11 | i | diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.ql b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.ql index 21e45974529..14fa90e3d44 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.ql +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.ql @@ -5,7 +5,9 @@ import utils.test.TranslateModels query predicate localStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { // Local flow steps that don't originate from a flow summary. - RustDataFlow::simpleLocalFlowStep(nodeFrom, nodeTo, "") + RustDataFlow::simpleLocalFlowStep(nodeFrom, nodeTo, "") and + nodeFrom.getLocation().fromSource() and + nodeTo.getLocation().fromSource() } class Node extends DataFlow::Node { From be9c785cb28eac94c467515bfea888e1832b471b Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Tue, 2 Jun 2026 09:26:13 +0100 Subject: [PATCH 189/226] Fix incorrect QLDoc Co-authored-by: Tom Hvitved --- shared/controlflow/codeql/controlflow/ControlFlowGraph.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index 68b230f735b..33a609d5552 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -95,7 +95,7 @@ signature module AstSig { Stmt getElse(); } - /** Gets the initializer of this `if` statement, if any. */ + /** Gets the initializer of `if` statement `ifstmt`, if any. */ default AstNode getIfInit(IfStmt ifstmt) { none() } /** From 9dbe9adb001d2b41b216578bb2ca29414ff3e2f1 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 09:34:03 +0100 Subject: [PATCH 190/226] Update tests --- .../ControlFlowGraph/NoretFunctions.expected | 6 + .../CONSISTENCY/DataFlowConsistency.expected | 12 +- .../CWE-312/CleartextLogging.expected | 212 ++++++++---------- .../query-tests/Security/CWE-312/passwords.go | 6 +- 4 files changed, 108 insertions(+), 128 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.expected b/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.expected index 9955274a4e0..4e466b74504 100644 --- a/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.expected +++ b/go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.expected @@ -5,6 +5,12 @@ | file://:0:0:0:0 | Fatalf | log.Logger.Fatalf | | file://:0:0:0:0 | Fatalln | log.Fatalln | | file://:0:0:0:0 | Fatalln | log.Logger.Fatalln | +| file://:0:0:0:0 | Panic | log.Logger.Panic | +| file://:0:0:0:0 | Panic | log.Panic | +| file://:0:0:0:0 | Panicf | log.Logger.Panicf | +| file://:0:0:0:0 | Panicf | log.Panicf | +| file://:0:0:0:0 | Panicln | log.Logger.Panicln | +| file://:0:0:0:0 | Panicln | log.Panicln | | file://:0:0:0:0 | panic | panic | | noretfunctions.go:8:6:8:12 | isNoRet | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.isNoRet | | noretfunctions.go:20:6:20:22 | noRetUsesLogFatal | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.noRetUsesLogFatal | diff --git a/go/ql/test/query-tests/Security/CWE-117/CONSISTENCY/DataFlowConsistency.expected b/go/ql/test/query-tests/Security/CWE-117/CONSISTENCY/DataFlowConsistency.expected index 2f4d9e320f8..a683e969167 100644 --- a/go/ql/test/query-tests/Security/CWE-117/CONSISTENCY/DataFlowConsistency.expected +++ b/go/ql/test/query-tests/Security/CWE-117/CONSISTENCY/DataFlowConsistency.expected @@ -3,9 +3,9 @@ reverseRead | LogInjection.go:33:14:33:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | | LogInjection.go:34:18:34:20 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | | LogInjection.go:35:14:35:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| LogInjection.go:447:14:447:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| LogInjection.go:455:14:455:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| LogInjection.go:463:14:463:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| LogInjection.go:498:14:498:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| LogInjection.go:499:14:499:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| LogInjection.go:724:12:724:14 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| LogInjection.go:551:14:551:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| LogInjection.go:559:14:559:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| LogInjection.go:567:14:567:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| LogInjection.go:602:14:602:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| LogInjection.go:603:14:603:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| LogInjection.go:828:12:828:14 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | diff --git a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index bc513a693a7..66392b22752 100644 --- a/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/go/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -37,22 +37,22 @@ | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | $@ flows to a logging call. | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by an access to password | | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | $@ flows to a logging call. | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by a call to getPassword | | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by a call to getPassword | -| passwords.go:32:12:32:19 | password | passwords.go:21:2:21:9 | definition of password | passwords.go:32:12:32:19 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:34:14:34:35 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:34:14:34:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:39:14:39:17 | obj1 | passwords.go:37:13:37:13 | x | passwords.go:39:14:39:17 | obj1 | $@ flows to a logging call. | passwords.go:37:13:37:13 | x | Sensitive data returned by an access to password | -| passwords.go:44:14:44:17 | obj2 | passwords.go:21:2:21:9 | definition of password | passwords.go:44:14:44:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:51:14:51:27 | fixed_password | passwords.go:50:2:50:15 | definition of fixed_password | passwords.go:51:14:51:27 | fixed_password | $@ flows to a logging call. | passwords.go:50:2:50:15 | definition of fixed_password | Sensitive data returned by an access to fixed_password | -| passwords.go:89:14:89:26 | utilityObject | passwords.go:87:16:87:36 | call to make | passwords.go:89:14:89:26 | utilityObject | $@ flows to a logging call. | passwords.go:87:16:87:36 | call to make | Sensitive data returned by an access to passwordSet | -| passwords.go:92:23:92:28 | secret | passwords.go:21:2:21:9 | definition of password | passwords.go:92:23:92:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:102:15:102:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:102:15:102:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:108:16:108:41 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:108:16:108:41 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:113:15:113:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:113:15:113:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:117:14:117:45 | ...+... | passwords.go:116:6:116:14 | definition of password1 | passwords.go:117:14:117:45 | ...+... | $@ flows to a logging call. | passwords.go:116:6:116:14 | definition of password1 | Sensitive data returned by an access to password1 | -| passwords.go:127:14:127:19 | config | passwords.go:21:2:21:9 | definition of password | passwords.go:127:14:127:19 | config | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:127:14:127:19 | config | passwords.go:121:13:121:14 | x3 | passwords.go:127:14:127:19 | config | $@ flows to a logging call. | passwords.go:121:13:121:14 | x3 | Sensitive data returned by an access to password | -| passwords.go:127:14:127:19 | config | passwords.go:124:13:124:25 | call to getPassword | passwords.go:127:14:127:19 | config | $@ flows to a logging call. | passwords.go:124:13:124:25 | call to getPassword | Sensitive data returned by a call to getPassword | -| passwords.go:128:14:128:21 | selection of x | passwords.go:21:2:21:9 | definition of password | passwords.go:128:14:128:21 | selection of x | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | -| passwords.go:129:14:129:21 | selection of y | passwords.go:124:13:124:25 | call to getPassword | passwords.go:129:14:129:21 | selection of y | $@ flows to a logging call. | passwords.go:124:13:124:25 | call to getPassword | Sensitive data returned by a call to getPassword | +| passwords.go:33:13:33:20 | password | passwords.go:21:2:21:9 | definition of password | passwords.go:33:13:33:20 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:36:14:36:35 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:36:14:36:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:41:14:41:17 | obj1 | passwords.go:39:13:39:13 | x | passwords.go:41:14:41:17 | obj1 | $@ flows to a logging call. | passwords.go:39:13:39:13 | x | Sensitive data returned by an access to password | +| passwords.go:46:14:46:17 | obj2 | passwords.go:21:2:21:9 | definition of password | passwords.go:46:14:46:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:53:14:53:27 | fixed_password | passwords.go:52:2:52:15 | definition of fixed_password | passwords.go:53:14:53:27 | fixed_password | $@ flows to a logging call. | passwords.go:52:2:52:15 | definition of fixed_password | Sensitive data returned by an access to fixed_password | +| passwords.go:91:14:91:26 | utilityObject | passwords.go:89:16:89:36 | call to make | passwords.go:91:14:91:26 | utilityObject | $@ flows to a logging call. | passwords.go:89:16:89:36 | call to make | Sensitive data returned by an access to passwordSet | +| passwords.go:94:23:94:28 | secret | passwords.go:21:2:21:9 | definition of password | passwords.go:94:23:94:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:104:15:104:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:104:15:104:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:110:16:110:41 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:110:16:110:41 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:115:15:115:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:115:15:115:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:119:14:119:45 | ...+... | passwords.go:118:6:118:14 | definition of password1 | passwords.go:119:14:119:45 | ...+... | $@ flows to a logging call. | passwords.go:118:6:118:14 | definition of password1 | Sensitive data returned by an access to password1 | +| passwords.go:129:14:129:19 | config | passwords.go:21:2:21:9 | definition of password | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:129:14:129:19 | config | passwords.go:123:13:123:14 | x3 | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:123:13:123:14 | x3 | Sensitive data returned by an access to password | +| passwords.go:129:14:129:19 | config | passwords.go:126:13:126:25 | call to getPassword | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword | +| passwords.go:130:14:130:21 | selection of x | passwords.go:21:2:21:9 | definition of password | passwords.go:130:14:130:21 | selection of x | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password | +| passwords.go:131:14:131:21 | selection of y | passwords.go:126:13:126:25 | call to getPassword | passwords.go:131:14:131:21 | selection of y | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword | | protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:9:2:9:9 | definition of password | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:9:2:9:9 | definition of password | Sensitive data returned by an access to password | edges | klog.go:21:3:26:3 | range statement[1] | klog.go:22:27:22:33 | headers | provenance | | @@ -86,35 +86,11 @@ edges | main.go:54:12:54:19 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 | | main.go:54:12:54:19 | password | main.go:65:13:65:20 | password | provenance | | | main.go:54:12:54:19 | password | main.go:68:11:68:18 | password | provenance | | -| main.go:54:12:54:19 | password | main.go:68:11:68:18 | password | provenance | | | main.go:54:12:54:19 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:54:12:54:19 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:54:12:54:19 | password | main.go:74:12:74:19 | password | provenance | | | main.go:54:12:54:19 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | | main.go:54:12:54:19 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:54:12:54:19 | password | main.go:77:13:77:20 | password | provenance | | | main.go:54:12:54:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | | main.go:54:12:54:19 | password | main.go:80:17:80:24 | password | provenance | | -| main.go:68:11:68:18 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:68:11:68:18 | password | main.go:71:18:71:25 | password | provenance | | -| main.go:68:11:68:18 | password | main.go:74:12:74:19 | password | provenance | | -| main.go:68:11:68:18 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | -| main.go:68:11:68:18 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:68:11:68:18 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:68:11:68:18 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | -| main.go:68:11:68:18 | password | main.go:80:17:80:24 | password | provenance | | -| main.go:71:18:71:25 | password | main.go:74:12:74:19 | password | provenance | | -| main.go:71:18:71:25 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 | -| main.go:71:18:71:25 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:71:18:71:25 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:71:18:71:25 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | -| main.go:71:18:71:25 | password | main.go:80:17:80:24 | password | provenance | | -| main.go:74:12:74:19 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:74:12:74:19 | password | main.go:77:13:77:20 | password | provenance | | -| main.go:74:12:74:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | -| main.go:74:12:74:19 | password | main.go:80:17:80:24 | password | provenance | | -| main.go:77:13:77:20 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 | -| main.go:77:13:77:20 | password | main.go:80:17:80:24 | password | provenance | | | main.go:80:17:80:24 | password | main.go:82:12:82:19 | password | provenance | | | main.go:80:17:80:24 | password | main.go:83:17:83:24 | password | provenance | | | main.go:80:17:80:24 | password | main.go:86:19:86:26 | password | provenance | | @@ -126,46 +102,46 @@ edges | passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x | provenance | | | passwords.go:21:2:21:9 | definition of password | passwords.go:25:14:25:21 | password | provenance | | | passwords.go:21:2:21:9 | definition of password | passwords.go:30:8:30:15 | password | provenance | | -| passwords.go:21:2:21:9 | definition of password | passwords.go:32:12:32:19 | password | provenance | | -| passwords.go:21:2:21:9 | definition of password | passwords.go:34:28:34:35 | password | provenance | | +| passwords.go:21:2:21:9 | definition of password | passwords.go:33:13:33:20 | password | provenance | | +| passwords.go:21:2:21:9 | definition of password | passwords.go:36:28:36:35 | password | provenance | | | passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | | -| passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | provenance | Config | -| passwords.go:34:28:34:35 | password | passwords.go:42:6:42:13 | password | provenance | | -| passwords.go:36:10:38:2 | struct literal | passwords.go:39:14:39:17 | obj1 | provenance | | -| passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal | provenance | Config | -| passwords.go:41:10:43:2 | struct literal | passwords.go:44:14:44:17 | obj2 | provenance | | -| passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal | provenance | Config | -| passwords.go:42:6:42:13 | password | passwords.go:48:11:48:18 | password | provenance | | -| passwords.go:48:11:48:18 | password | passwords.go:92:23:92:28 | secret | provenance | | -| passwords.go:48:11:48:18 | password | passwords.go:102:33:102:40 | password | provenance | | -| passwords.go:48:11:48:18 | password | passwords.go:108:34:108:41 | password | provenance | | -| passwords.go:48:11:48:18 | password | passwords.go:113:33:113:40 | password | provenance | | -| passwords.go:48:11:48:18 | password | passwords.go:123:13:123:20 | password | provenance | | -| passwords.go:50:2:50:15 | definition of fixed_password | passwords.go:51:14:51:27 | fixed_password | provenance | | -| passwords.go:86:19:88:2 | struct literal | passwords.go:89:14:89:26 | utilityObject | provenance | | -| passwords.go:87:16:87:36 | call to make | passwords.go:86:19:88:2 | struct literal | provenance | Config | -| passwords.go:102:33:102:40 | password | passwords.go:102:15:102:40 | ...+... | provenance | Config | -| passwords.go:102:33:102:40 | password | passwords.go:108:34:108:41 | password | provenance | | -| passwords.go:102:33:102:40 | password | passwords.go:113:33:113:40 | password | provenance | | -| passwords.go:102:33:102:40 | password | passwords.go:123:13:123:20 | password | provenance | | -| passwords.go:108:34:108:41 | password | passwords.go:108:16:108:41 | ...+... | provenance | Config | -| passwords.go:108:34:108:41 | password | passwords.go:113:33:113:40 | password | provenance | | -| passwords.go:108:34:108:41 | password | passwords.go:123:13:123:20 | password | provenance | | -| passwords.go:113:33:113:40 | password | passwords.go:113:15:113:40 | ...+... | provenance | Config | -| passwords.go:113:33:113:40 | password | passwords.go:123:13:123:20 | password | provenance | | -| passwords.go:116:6:116:14 | definition of password1 | passwords.go:117:28:117:36 | password1 | provenance | | -| passwords.go:117:28:117:36 | password1 | passwords.go:117:28:117:45 | call to String | provenance | Config | -| passwords.go:117:28:117:45 | call to String | passwords.go:117:14:117:45 | ...+... | provenance | Config | -| passwords.go:120:12:125:2 | struct literal | passwords.go:127:14:127:19 | config | provenance | | -| passwords.go:120:12:125:2 | struct literal [x] | passwords.go:128:14:128:19 | config [x] | provenance | | -| passwords.go:120:12:125:2 | struct literal [y] | passwords.go:129:14:129:19 | config [y] | provenance | | -| passwords.go:121:13:121:14 | x3 | passwords.go:120:12:125:2 | struct literal | provenance | Config | -| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal | provenance | Config | -| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal [x] | provenance | | -| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal | provenance | Config | -| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal [y] | provenance | | -| passwords.go:128:14:128:19 | config [x] | passwords.go:128:14:128:21 | selection of x | provenance | | -| passwords.go:129:14:129:19 | config [y] | passwords.go:129:14:129:21 | selection of y | provenance | | +| passwords.go:36:28:36:35 | password | passwords.go:36:14:36:35 | ...+... | provenance | Config | +| passwords.go:36:28:36:35 | password | passwords.go:44:6:44:13 | password | provenance | | +| passwords.go:38:10:40:2 | struct literal | passwords.go:41:14:41:17 | obj1 | provenance | | +| passwords.go:39:13:39:13 | x | passwords.go:38:10:40:2 | struct literal | provenance | Config | +| passwords.go:43:10:45:2 | struct literal | passwords.go:46:14:46:17 | obj2 | provenance | | +| passwords.go:44:6:44:13 | password | passwords.go:43:10:45:2 | struct literal | provenance | Config | +| passwords.go:44:6:44:13 | password | passwords.go:50:11:50:18 | password | provenance | | +| passwords.go:50:11:50:18 | password | passwords.go:94:23:94:28 | secret | provenance | | +| passwords.go:50:11:50:18 | password | passwords.go:104:33:104:40 | password | provenance | | +| passwords.go:50:11:50:18 | password | passwords.go:110:34:110:41 | password | provenance | | +| passwords.go:50:11:50:18 | password | passwords.go:115:33:115:40 | password | provenance | | +| passwords.go:50:11:50:18 | password | passwords.go:125:13:125:20 | password | provenance | | +| passwords.go:52:2:52:15 | definition of fixed_password | passwords.go:53:14:53:27 | fixed_password | provenance | | +| passwords.go:88:19:90:2 | struct literal | passwords.go:91:14:91:26 | utilityObject | provenance | | +| passwords.go:89:16:89:36 | call to make | passwords.go:88:19:90:2 | struct literal | provenance | Config | +| passwords.go:104:33:104:40 | password | passwords.go:104:15:104:40 | ...+... | provenance | Config | +| passwords.go:104:33:104:40 | password | passwords.go:110:34:110:41 | password | provenance | | +| passwords.go:104:33:104:40 | password | passwords.go:115:33:115:40 | password | provenance | | +| passwords.go:104:33:104:40 | password | passwords.go:125:13:125:20 | password | provenance | | +| passwords.go:110:34:110:41 | password | passwords.go:110:16:110:41 | ...+... | provenance | Config | +| passwords.go:110:34:110:41 | password | passwords.go:115:33:115:40 | password | provenance | | +| passwords.go:110:34:110:41 | password | passwords.go:125:13:125:20 | password | provenance | | +| passwords.go:115:33:115:40 | password | passwords.go:115:15:115:40 | ...+... | provenance | Config | +| passwords.go:115:33:115:40 | password | passwords.go:125:13:125:20 | password | provenance | | +| passwords.go:118:6:118:14 | definition of password1 | passwords.go:119:28:119:36 | password1 | provenance | | +| passwords.go:119:28:119:36 | password1 | passwords.go:119:28:119:45 | call to String | provenance | Config | +| passwords.go:119:28:119:45 | call to String | passwords.go:119:14:119:45 | ...+... | provenance | Config | +| passwords.go:122:12:127:2 | struct literal | passwords.go:129:14:129:19 | config | provenance | | +| passwords.go:122:12:127:2 | struct literal [x] | passwords.go:130:14:130:19 | config [x] | provenance | | +| passwords.go:122:12:127:2 | struct literal [y] | passwords.go:131:14:131:19 | config [y] | provenance | | +| passwords.go:123:13:123:14 | x3 | passwords.go:122:12:127:2 | struct literal | provenance | Config | +| passwords.go:125:13:125:20 | password | passwords.go:122:12:127:2 | struct literal | provenance | Config | +| passwords.go:125:13:125:20 | password | passwords.go:122:12:127:2 | struct literal [x] | provenance | | +| passwords.go:126:13:126:25 | call to getPassword | passwords.go:122:12:127:2 | struct literal | provenance | Config | +| passwords.go:126:13:126:25 | call to getPassword | passwords.go:122:12:127:2 | struct literal [y] | provenance | | +| passwords.go:130:14:130:19 | config [x] | passwords.go:130:14:130:21 | selection of x | provenance | | +| passwords.go:131:14:131:19 | config [y] | passwords.go:131:14:131:21 | selection of y | provenance | | | protobuf.go:9:2:9:9 | definition of password | protobuf.go:12:22:12:29 | password | provenance | | | protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | provenance | | | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | | @@ -222,12 +198,8 @@ nodes | main.go:62:12:62:19 | password | semmle.label | password | | main.go:65:13:65:20 | password | semmle.label | password | | main.go:68:11:68:18 | password | semmle.label | password | -| main.go:68:11:68:18 | password | semmle.label | password | -| main.go:71:18:71:25 | password | semmle.label | password | | main.go:71:18:71:25 | password | semmle.label | password | | main.go:74:12:74:19 | password | semmle.label | password | -| main.go:74:12:74:19 | password | semmle.label | password | -| main.go:77:13:77:20 | password | semmle.label | password | | main.go:77:13:77:20 | password | semmle.label | password | | main.go:79:14:79:21 | password | semmle.label | password | | main.go:80:17:80:24 | password | semmle.label | password | @@ -248,43 +220,43 @@ nodes | passwords.go:27:14:27:26 | call to getPassword | semmle.label | call to getPassword | | passwords.go:28:14:28:28 | call to getPassword | semmle.label | call to getPassword | | passwords.go:30:8:30:15 | password | semmle.label | password | -| passwords.go:32:12:32:19 | password | semmle.label | password | -| passwords.go:34:14:34:35 | ...+... | semmle.label | ...+... | -| passwords.go:34:28:34:35 | password | semmle.label | password | -| passwords.go:36:10:38:2 | struct literal | semmle.label | struct literal | -| passwords.go:37:13:37:13 | x | semmle.label | x | -| passwords.go:39:14:39:17 | obj1 | semmle.label | obj1 | -| passwords.go:41:10:43:2 | struct literal | semmle.label | struct literal | -| passwords.go:42:6:42:13 | password | semmle.label | password | -| passwords.go:44:14:44:17 | obj2 | semmle.label | obj2 | -| passwords.go:48:11:48:18 | password | semmle.label | password | -| passwords.go:50:2:50:15 | definition of fixed_password | semmle.label | definition of fixed_password | -| passwords.go:51:14:51:27 | fixed_password | semmle.label | fixed_password | -| passwords.go:86:19:88:2 | struct literal | semmle.label | struct literal | -| passwords.go:87:16:87:36 | call to make | semmle.label | call to make | -| passwords.go:89:14:89:26 | utilityObject | semmle.label | utilityObject | -| passwords.go:92:23:92:28 | secret | semmle.label | secret | -| passwords.go:102:15:102:40 | ...+... | semmle.label | ...+... | -| passwords.go:102:33:102:40 | password | semmle.label | password | -| passwords.go:108:16:108:41 | ...+... | semmle.label | ...+... | -| passwords.go:108:34:108:41 | password | semmle.label | password | -| passwords.go:113:15:113:40 | ...+... | semmle.label | ...+... | -| passwords.go:113:33:113:40 | password | semmle.label | password | -| passwords.go:116:6:116:14 | definition of password1 | semmle.label | definition of password1 | -| passwords.go:117:14:117:45 | ...+... | semmle.label | ...+... | -| passwords.go:117:28:117:36 | password1 | semmle.label | password1 | -| passwords.go:117:28:117:45 | call to String | semmle.label | call to String | -| passwords.go:120:12:125:2 | struct literal | semmle.label | struct literal | -| passwords.go:120:12:125:2 | struct literal [x] | semmle.label | struct literal [x] | -| passwords.go:120:12:125:2 | struct literal [y] | semmle.label | struct literal [y] | -| passwords.go:121:13:121:14 | x3 | semmle.label | x3 | -| passwords.go:123:13:123:20 | password | semmle.label | password | -| passwords.go:124:13:124:25 | call to getPassword | semmle.label | call to getPassword | -| passwords.go:127:14:127:19 | config | semmle.label | config | -| passwords.go:128:14:128:19 | config [x] | semmle.label | config [x] | -| passwords.go:128:14:128:21 | selection of x | semmle.label | selection of x | -| passwords.go:129:14:129:19 | config [y] | semmle.label | config [y] | -| passwords.go:129:14:129:21 | selection of y | semmle.label | selection of y | +| passwords.go:33:13:33:20 | password | semmle.label | password | +| passwords.go:36:14:36:35 | ...+... | semmle.label | ...+... | +| passwords.go:36:28:36:35 | password | semmle.label | password | +| passwords.go:38:10:40:2 | struct literal | semmle.label | struct literal | +| passwords.go:39:13:39:13 | x | semmle.label | x | +| passwords.go:41:14:41:17 | obj1 | semmle.label | obj1 | +| passwords.go:43:10:45:2 | struct literal | semmle.label | struct literal | +| passwords.go:44:6:44:13 | password | semmle.label | password | +| passwords.go:46:14:46:17 | obj2 | semmle.label | obj2 | +| passwords.go:50:11:50:18 | password | semmle.label | password | +| passwords.go:52:2:52:15 | definition of fixed_password | semmle.label | definition of fixed_password | +| passwords.go:53:14:53:27 | fixed_password | semmle.label | fixed_password | +| passwords.go:88:19:90:2 | struct literal | semmle.label | struct literal | +| passwords.go:89:16:89:36 | call to make | semmle.label | call to make | +| passwords.go:91:14:91:26 | utilityObject | semmle.label | utilityObject | +| passwords.go:94:23:94:28 | secret | semmle.label | secret | +| passwords.go:104:15:104:40 | ...+... | semmle.label | ...+... | +| passwords.go:104:33:104:40 | password | semmle.label | password | +| passwords.go:110:16:110:41 | ...+... | semmle.label | ...+... | +| passwords.go:110:34:110:41 | password | semmle.label | password | +| passwords.go:115:15:115:40 | ...+... | semmle.label | ...+... | +| passwords.go:115:33:115:40 | password | semmle.label | password | +| passwords.go:118:6:118:14 | definition of password1 | semmle.label | definition of password1 | +| passwords.go:119:14:119:45 | ...+... | semmle.label | ...+... | +| passwords.go:119:28:119:36 | password1 | semmle.label | password1 | +| passwords.go:119:28:119:45 | call to String | semmle.label | call to String | +| passwords.go:122:12:127:2 | struct literal | semmle.label | struct literal | +| passwords.go:122:12:127:2 | struct literal [x] | semmle.label | struct literal [x] | +| passwords.go:122:12:127:2 | struct literal [y] | semmle.label | struct literal [y] | +| passwords.go:123:13:123:14 | x3 | semmle.label | x3 | +| passwords.go:125:13:125:20 | password | semmle.label | password | +| passwords.go:126:13:126:25 | call to getPassword | semmle.label | call to getPassword | +| passwords.go:129:14:129:19 | config | semmle.label | config | +| passwords.go:130:14:130:19 | config [x] | semmle.label | config [x] | +| passwords.go:130:14:130:21 | selection of x | semmle.label | selection of x | +| passwords.go:131:14:131:19 | config [y] | semmle.label | config [y] | +| passwords.go:131:14:131:21 | selection of y | semmle.label | selection of y | | protobuf.go:9:2:9:9 | definition of password | semmle.label | definition of password | | protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | semmle.label | implicit dereference [postupdate] [Description] | | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | semmle.label | query [postupdate] [pointer, Description] | diff --git a/go/ql/test/query-tests/Security/CWE-312/passwords.go b/go/ql/test/query-tests/Security/CWE-312/passwords.go index 38c977e41b8..dc569970a39 100644 --- a/go/ql/test/query-tests/Security/CWE-312/passwords.go +++ b/go/ql/test/query-tests/Security/CWE-312/passwords.go @@ -16,7 +16,7 @@ func redact(kind, value string) string { return value } -func test() { +func test(selector int) { name := "user" password := "P@ssw0rd" // $ Source x := "horsebatterystapleincorrect" @@ -29,7 +29,9 @@ func test() { myLog(password) - log.Panic(password) // $ Alert + if selector == 1 { + log.Panic(password) // $ Alert + } log.Println(name + ", " + password) // $ Alert From 566a92e55519bdad0fab656cb44edcd8e8837ffd Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Tue, 2 Jun 2026 10:41:10 +0200 Subject: [PATCH 191/226] formatting again --- shared/rangeanalysis/codeql/rangeanalysis/Bound.qll | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll index a39871000d9..353cb94064b 100644 --- a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll +++ b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll @@ -38,9 +38,10 @@ signature module BoundDefinitions { predicate interestingExprBound(Expr e); } -/** Provides classes for representing abstract bounds for use in, for example, range analysis. +/** + * Provides classes for representing abstract bounds for use in, for example, range analysis. * This is a generic implementation of bounds that relies on language specific modules to provide language-specific definitions of expressions, SSA variables, etc. -*/ + */ overlay[local?] module Bound Defs> { private import Defs From dc0c7d7ec221af4b3e93dbfc71eac3133054da41 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 2 Jun 2026 14:41:27 +0200 Subject: [PATCH 192/226] Fix `commment` typos --- .../lib/utils/test/PathResolutionInlineExpectationsTest.qll | 6 +++--- rust/ql/test/TestUtils.qll | 2 +- rust/ql/test/library-tests/const_access/const_access.ql | 4 ++-- rust/ql/test/library-tests/static_access/static_access.ql | 4 ++-- rust/ql/test/library-tests/variables/variables.ql | 4 ++-- shared/util/codeql/util/test/InlineExpectationsTest.qll | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll b/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll index f4544cafacc..a6ab8cd48ca 100644 --- a/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll +++ b/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll @@ -14,7 +14,7 @@ private module ResolveTest implements TestSig { i.getLocation().hasLocationInfo(filepath, _, _, line, _) } - private predicate commmentAt(string text, string filepath, int line) { + private predicate commentAt(string text, string filepath, int line) { exists(Comment c | c.getLocation().hasLocationInfo(filepath, line, _, _, _) and c.getCommentText().trim() = text and @@ -28,9 +28,9 @@ private module ResolveTest implements TestSig { if i instanceof SourceFile then value = i.getFile().getBaseName() else ( - commmentAt(value, filepath, line) + commentAt(value, filepath, line) or - not commmentAt(_, filepath, line) and + not commentAt(_, filepath, line) and value = i.getName() ) ) diff --git a/rust/ql/test/TestUtils.qll b/rust/ql/test/TestUtils.qll index d622af7f4d3..a55c24544b8 100644 --- a/rust/ql/test/TestUtils.qll +++ b/rust/ql/test/TestUtils.qll @@ -21,7 +21,7 @@ class Builtin extends AstNode { Builtin() { this.getFile().getAbsolutePath().matches("%/builtins/%.rs") } } -predicate commmentAt(string text, string filepath, int line) { +predicate commentAt(string text, string filepath, int line) { exists(Comment c | c.getLocation().hasLocationInfo(filepath, line, _, _, _) and c.getCommentText().trim() = text and diff --git a/rust/ql/test/library-tests/const_access/const_access.ql b/rust/ql/test/library-tests/const_access/const_access.ql index f10479fdb81..27d1726f106 100644 --- a/rust/ql/test/library-tests/const_access/const_access.ql +++ b/rust/ql/test/library-tests/const_access/const_access.ql @@ -20,9 +20,9 @@ module ConstAccessTest implements TestSig { c = ca.getConst() and constAt(c, filepath, line) | - commmentAt(value, filepath, line) + commentAt(value, filepath, line) or - not commmentAt(_, filepath, line) and + not commentAt(_, filepath, line) and value = c.getName().getText() ) } diff --git a/rust/ql/test/library-tests/static_access/static_access.ql b/rust/ql/test/library-tests/static_access/static_access.ql index d755bf5a350..8a21ee5fb9b 100644 --- a/rust/ql/test/library-tests/static_access/static_access.ql +++ b/rust/ql/test/library-tests/static_access/static_access.ql @@ -20,9 +20,9 @@ module StaticAccessTest implements TestSig { s = sa.getStatic() and staticAt(s, filepath, line) | - commmentAt(value, filepath, line) + commentAt(value, filepath, line) or - not commmentAt(_, filepath, line) and + not commentAt(_, filepath, line) and value = s.getName().getText() ) } diff --git a/rust/ql/test/library-tests/variables/variables.ql b/rust/ql/test/library-tests/variables/variables.ql index 8380512d99f..934b3c4c420 100644 --- a/rust/ql/test/library-tests/variables/variables.ql +++ b/rust/ql/test/library-tests/variables/variables.ql @@ -40,9 +40,9 @@ module VariableAccessTest implements TestSig { private predicate decl(Variable v, string value) { exists(string filepath, int line, boolean inMacro | declAt(v, filepath, line, inMacro) | - commmentAt(value, filepath, line) and inMacro = false + commentAt(value, filepath, line) and inMacro = false or - not (commmentAt(_, filepath, line) and inMacro = false) and + not (commentAt(_, filepath, line) and inMacro = false) and value = v.getText() ) } diff --git a/shared/util/codeql/util/test/InlineExpectationsTest.qll b/shared/util/codeql/util/test/InlineExpectationsTest.qll index e2ea9b87e74..e785adda456 100644 --- a/shared/util/codeql/util/test/InlineExpectationsTest.qll +++ b/shared/util/codeql/util/test/InlineExpectationsTest.qll @@ -597,7 +597,7 @@ private string mainResultSet() { result = ["#select", "problems"] } * foo(); // $ Alert[rust/unreachable-code] * ``` * - * In the example above, the `$ Alert[rust/unused-value]` commment is only taken + * In the example above, the `$ Alert[rust/unused-value]` comment is only taken * into account in the test for the query with ID `rust/unused-value`, and vice * versa for the `$ Alert[rust/unreachable-code]` comment. * From 9d5dfea5c5388852492d4a8b03cf4f809454e8f0 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 2 Jun 2026 16:55:28 +0200 Subject: [PATCH 193/226] JS: Add Vue to `file_coverage_languages` and `github_api_languages` --- javascript/resources/codeql-extractor.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/javascript/resources/codeql-extractor.yml b/javascript/resources/codeql-extractor.yml index 14ec56e2429..bfc99d826fc 100644 --- a/javascript/resources/codeql-extractor.yml +++ b/javascript/resources/codeql-extractor.yml @@ -21,13 +21,19 @@ file_coverage_languages: scc_languages: - TypeScript - TypeScript Typings + - name: vue + display_name: Vue.js component + scc_languages: + - Vue github_api_languages: - JavaScript - TypeScript + - Vue scc_languages: - JavaScript - TypeScript - TypeScript Typings + - Vue file_types: - name: javascript display_name: JavaScript From ad97b6dd644700a76372838a7f0fd002a98e383a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 14:05:07 +0100 Subject: [PATCH 194/226] Use access path for `str.join` model --- .../new/internal/TaintTrackingPrivate.qll | 5 ----- .../ql/lib/semmle/python/frameworks/Stdlib.qll | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 636e65dc088..02c43f874bf 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -150,11 +150,6 @@ predicate stringManipulation(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeT nodeFrom.getNode() = object and method_name in ["partition", "rpartition", "rsplit", "split", "splitlines"] or - // Iterable[str] -> str - // TODO: check if these should be handled differently in regards to content - method_name = "join" and - nodeFrom.getNode() = call.getArg(0) - or // Mapping[str, Any] -> str method_name = "format_map" and nodeFrom.getNode() = call.getArg(0) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 1e0bd846181..6dc66fb2fd4 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4976,6 +4976,23 @@ module StdlibPrivate { } } + /** A flow summary for `str.join`. */ + class StrJoinSummary extends SummarizedCallable::Range { + StrJoinSummary() { this = "str.join" } + + override DataFlow::CallCfgNode getACall() { result.(DataFlow::MethodCallNode).calls(_, "join") } + + override DataFlow::ArgumentNode getACallback() { + result.(DataFlow::AttrRead).getAttributeName() = "join" + } + + override predicate propagatesFlow(string input, string output, boolean preservesValue) { + input = ["Argument[0,iterable:]", "Argument[0,iterable:].ListElement"] and + output = "ReturnValue" and + preservesValue = false + } + } + // --------------------------------------------------------------------------- // asyncio // --------------------------------------------------------------------------- From dede5bc49bcaab2f9bef0b8a0025bf62cbabb85d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 14:18:28 +0100 Subject: [PATCH 195/226] Track flow through `tuple()` with list with tainted elements --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 6dc66fb2fd4..05e7a629de6 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4277,9 +4277,7 @@ module StdlibPrivate { preservesValue = true ) or - // TODO: We need to also translate iterable content such as list element - // but we currently lack TupleElementAny - input = "Argument[0]" and + input = ["Argument[0]", "Argument[0].ListElement"] and output = "ReturnValue" and preservesValue = false } From c3ef1ddd64a2616fba1624132de647c65a00169b Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 16:14:15 +0100 Subject: [PATCH 196/226] Add MaD models for lxml and xml etree.fromstringlist --- python/ql/lib/semmle/python/frameworks/lxml.model.yml | 6 ++++++ python/ql/lib/semmle/python/frameworks/xml.model.yml | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 python/ql/lib/semmle/python/frameworks/lxml.model.yml create mode 100644 python/ql/lib/semmle/python/frameworks/xml.model.yml diff --git a/python/ql/lib/semmle/python/frameworks/lxml.model.yml b/python/ql/lib/semmle/python/frameworks/lxml.model.yml new file mode 100644 index 00000000000..77e69758ae8 --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/lxml.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/python-all + extensible: summaryModel + data: + - ['lxml', 'Member[etree].Member[fromstringlist]', 'Argument[0,strings:].ListElement', 'ReturnValue', 'taint'] diff --git a/python/ql/lib/semmle/python/frameworks/xml.model.yml b/python/ql/lib/semmle/python/frameworks/xml.model.yml new file mode 100644 index 00000000000..96ea8480f93 --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/xml.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/python-all + extensible: summaryModel + data: + - ['xml', 'Member[etree].Member[fromstringlist]', 'Argument[0,strings:].ListElement', 'ReturnValue', 'taint'] From f62ebef9e0c47703e4792492ba13fedfd3abe1f4 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 09:45:50 +0100 Subject: [PATCH 197/226] Adjust expected test output --- .../PromptInjection.expected | 20 +++++++++++++++++++ .../CWE-1427-PromptInjection/openai_test.py | 2 +- .../test_collections.py | 4 ++-- .../frameworks/tornado/taint_test.py | 8 ++++---- .../UnsafeShellCommandConstruction.expected | 10 ++++++++-- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/PromptInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/PromptInjection.expected index fbf4ae3fd98..6e814aac496 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/PromptInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/PromptInjection.expected @@ -13,6 +13,7 @@ | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:18:15:18:19 | ControlFlowNode for query | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:18:15:18:19 | ControlFlowNode for query | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| openai_test.py:23:15:37:9 | ControlFlowNode for List | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:23:15:37:9 | ControlFlowNode for List | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:33:33:33:37 | ControlFlowNode for query | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:33:33:33:37 | ControlFlowNode for query | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | openai_test.py:41:22:41:46 | ControlFlowNode for BinaryExpr | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | openai_test.py:41:22:41:46 | ControlFlowNode for BinaryExpr | This prompt construction depends on a $@. | openai_test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | @@ -31,11 +32,13 @@ edges | agent_instructions.py:7:5:7:9 | ControlFlowNode for input | agent_instructions.py:9:50:9:89 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:11 | | agent_instructions.py:7:13:7:19 | ControlFlowNode for request | agent_instructions.py:7:13:7:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | agent_instructions.py:7:13:7:24 | ControlFlowNode for Attribute | agent_instructions.py:7:13:7:37 | ControlFlowNode for Attribute() | provenance | dict.get | +| agent_instructions.py:7:13:7:24 | ControlFlowNode for Attribute | agent_instructions.py:7:13:7:37 | ControlFlowNode for Attribute() | provenance | dict.get(input) | | agent_instructions.py:7:13:7:37 | ControlFlowNode for Attribute() | agent_instructions.py:7:5:7:9 | ControlFlowNode for input | provenance | | | agent_instructions.py:17:5:17:9 | ControlFlowNode for input | agent_instructions.py:25:28:25:32 | ControlFlowNode for input | provenance | | | agent_instructions.py:17:5:17:9 | ControlFlowNode for input | agent_instructions.py:35:28:35:32 | ControlFlowNode for input | provenance | | | agent_instructions.py:17:13:17:19 | ControlFlowNode for request | agent_instructions.py:17:13:17:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | agent_instructions.py:17:13:17:24 | ControlFlowNode for Attribute | agent_instructions.py:17:13:17:37 | ControlFlowNode for Attribute() | provenance | dict.get | +| agent_instructions.py:17:13:17:24 | ControlFlowNode for Attribute | agent_instructions.py:17:13:17:37 | ControlFlowNode for Attribute() | provenance | dict.get(input) | | agent_instructions.py:17:13:17:37 | ControlFlowNode for Attribute() | agent_instructions.py:17:5:17:9 | ControlFlowNode for input | provenance | | | anthropic_test.py:2:26:2:32 | ControlFlowNode for ImportMember | anthropic_test.py:2:26:2:32 | ControlFlowNode for request | provenance | | | anthropic_test.py:2:26:2:32 | ControlFlowNode for request | anthropic_test.py:11:15:11:21 | ControlFlowNode for request | provenance | | @@ -61,6 +64,7 @@ edges | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:10 | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:10 | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | provenance | | +| openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | provenance | | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:41:22:41:46 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:10 | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:63:28:63:51 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:8 | | openai_test.py:12:5:12:11 | ControlFlowNode for persona | openai_test.py:80:28:80:51 | ControlFlowNode for BinaryExpr | provenance | Sink:MaD:8 | @@ -71,6 +75,7 @@ edges | openai_test.py:12:15:12:41 | ControlFlowNode for Attribute() | openai_test.py:12:5:12:11 | ControlFlowNode for persona | provenance | | | openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:18:15:18:19 | ControlFlowNode for query | provenance | Sink:MaD:9 | | openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:33:33:33:37 | ControlFlowNode for query | provenance | | +| openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:33:33:33:37 | ControlFlowNode for query | provenance | | | openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:42:15:42:19 | ControlFlowNode for query | provenance | Sink:MaD:9 | | openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:53:33:53:37 | ControlFlowNode for query | provenance | | | openai_test.py:13:5:13:9 | ControlFlowNode for query | openai_test.py:67:28:67:32 | ControlFlowNode for query | provenance | Sink:MaD:8 | @@ -79,6 +84,14 @@ edges | openai_test.py:13:13:13:19 | ControlFlowNode for request | openai_test.py:13:13:13:24 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | openai_test.py:13:13:13:24 | ControlFlowNode for Attribute | openai_test.py:13:13:13:37 | ControlFlowNode for Attribute() | provenance | dict.get | | openai_test.py:13:13:13:37 | ControlFlowNode for Attribute() | openai_test.py:13:5:13:9 | ControlFlowNode for query | provenance | | +| openai_test.py:24:13:27:13 | ControlFlowNode for Dict [Dictionary element at key content] | openai_test.py:23:15:37:9 | ControlFlowNode for List | provenance | Sink:MaD:9 Sink:MaD:9 | +| openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | openai_test.py:24:13:27:13 | ControlFlowNode for Dict [Dictionary element at key content] | provenance | | +| openai_test.py:28:13:36:13 | ControlFlowNode for Dict [Dictionary element at key content, List element, Dictionary element at key text] | openai_test.py:23:15:37:9 | ControlFlowNode for List | provenance | Sink:MaD:9 Sink:MaD:9 | +| openai_test.py:28:13:36:13 | ControlFlowNode for Dict [Dictionary element at key content, List element, Dictionary element at key text] | openai_test.py:23:15:37:9 | ControlFlowNode for List | provenance | Sink:MaD:9 Sink:MaD:9 Sink:MaD:9 | +| openai_test.py:28:13:36:13 | ControlFlowNode for Dict [Dictionary element at key content, List element, Dictionary element at key text] | openai_test.py:23:15:37:9 | ControlFlowNode for List | provenance | Sink:MaD:9 Sink:MaD:9 Sink:MaD:9 Sink:MaD:9 | +| openai_test.py:30:28:35:17 | ControlFlowNode for List [List element, Dictionary element at key text] | openai_test.py:28:13:36:13 | ControlFlowNode for Dict [Dictionary element at key content, List element, Dictionary element at key text] | provenance | | +| openai_test.py:31:21:34:21 | ControlFlowNode for Dict [Dictionary element at key text] | openai_test.py:30:28:35:17 | ControlFlowNode for List [List element, Dictionary element at key text] | provenance | | +| openai_test.py:33:33:33:37 | ControlFlowNode for query | openai_test.py:31:21:34:21 | ControlFlowNode for Dict [Dictionary element at key text] | provenance | | models | 1 | Sink: Anthropic; Member[beta].Member[messages].Member[create].Argument[messages:].ListElement.DictionaryElement[content]; prompt-injection | | 2 | Sink: Anthropic; Member[beta].Member[messages].Member[create].Argument[system:]; prompt-injection | @@ -136,7 +149,14 @@ nodes | openai_test.py:17:22:17:46 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | openai_test.py:18:15:18:19 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | openai_test.py:22:22:22:46 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| openai_test.py:23:15:37:9 | ControlFlowNode for List | semmle.label | ControlFlowNode for List | +| openai_test.py:24:13:27:13 | ControlFlowNode for Dict [Dictionary element at key content] | semmle.label | ControlFlowNode for Dict [Dictionary element at key content] | | openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| openai_test.py:26:28:26:51 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| openai_test.py:28:13:36:13 | ControlFlowNode for Dict [Dictionary element at key content, List element, Dictionary element at key text] | semmle.label | ControlFlowNode for Dict [Dictionary element at key content, List element, Dictionary element at key text] | +| openai_test.py:30:28:35:17 | ControlFlowNode for List [List element, Dictionary element at key text] | semmle.label | ControlFlowNode for List [List element, Dictionary element at key text] | +| openai_test.py:31:21:34:21 | ControlFlowNode for Dict [Dictionary element at key text] | semmle.label | ControlFlowNode for Dict [Dictionary element at key text] | +| openai_test.py:33:33:33:37 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | openai_test.py:33:33:33:37 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | openai_test.py:41:22:41:46 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | openai_test.py:42:15:42:19 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/openai_test.py b/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/openai_test.py index 2b25609670c..8ea014c62b4 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/openai_test.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-1427-PromptInjection/openai_test.py @@ -34,7 +34,7 @@ async def get_input_openai(): } ] } - ] + ] # $ Alert[py/prompt-injection] ) response3 = await async_client.responses.create( diff --git a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py index b9fa1ebffd4..fa6087f3ebc 100644 --- a/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py +++ b/python/ql/test/library-tests/dataflow/tainttracking/defaultAdditionalTaintStep/test_collections.py @@ -40,11 +40,11 @@ def test_construction(): dict(k = tainted_string)["k"], # $ tainted dict(dict(k = tainted_string))["k"], # $ tainted dict(["k", tainted_string]), # $ tainted + list(tainted_dict.items()), # $ tainted ) ensure_not_tainted( dict(k = tainted_string)["k1"], - list(tainted_dict.items()), ) @@ -59,7 +59,7 @@ def test_access(x, y, z): sorted(tainted_list), # $ tainted reversed(tainted_list), # $ tainted iter(tainted_list), # $ tainted - next(iter(tainted_list)), # $ MISSING: tainted + next(iter(tainted_list)), # $ tainted [i for i in tainted_list], # $ tainted [tainted_list for _i in [1,2,3]], # $ tainted ) diff --git a/python/ql/test/library-tests/frameworks/tornado/taint_test.py b/python/ql/test/library-tests/frameworks/tornado/taint_test.py index d6dac013fbc..2a683d59d9c 100644 --- a/python/ql/test/library-tests/frameworks/tornado/taint_test.py +++ b/python/ql/test/library-tests/frameworks/tornado/taint_test.py @@ -72,11 +72,11 @@ class TaintTest(tornado.web.RequestHandler): request.cookies["cookie-name"].key, # $ tainted request.cookies["cookie-name"].value, # $ tainted request.cookies["cookie-name"].coded_value, # $ tainted - ) - ensure_not_tainted( - [(k, v) for (k, v) in request.headers.get_all()], # The comprehension is not tainted, only the elements - list([(k, v) for (k, v) in request.headers.get_all()]), # Here, all the elements of the list are tainted, but the list is not. + # The comprehension is not tainted, only the elements, but this passes due to implicit reads at sinks + [(k, v) for (k, v) in request.headers.get_all()], # $ tainted + # The list is not tainted, only the elements, but this passes due to implicit reads at sinks + list([(k, v) for (k, v) in request.headers.get_all()]), # $ tainted ) diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index e53508f61a5..3bc075d618b 100644 --- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -1,10 +1,13 @@ edges | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:5:25:5:28 | ControlFlowNode for name | provenance | | | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:8:23:8:26 | ControlFlowNode for name | provenance | | -| src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:11:25:11:38 | ControlFlowNode for Attribute() | provenance | | -| src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:14:25:14:40 | ControlFlowNode for Attribute() | provenance | | +| src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:11:34:11:37 | ControlFlowNode for name | provenance | | +| src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:14:35:14:38 | ControlFlowNode for name | provenance | | | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:17:32:17:35 | ControlFlowNode for name | provenance | | | src/unsafe_shell_test.py:4:22:4:25 | ControlFlowNode for name | src/unsafe_shell_test.py:20:27:20:30 | ControlFlowNode for name | provenance | | +| src/unsafe_shell_test.py:11:34:11:37 | ControlFlowNode for name | src/unsafe_shell_test.py:11:25:11:38 | ControlFlowNode for Attribute() | provenance | str.join | +| src/unsafe_shell_test.py:14:34:14:39 | ControlFlowNode for List [List element] | src/unsafe_shell_test.py:14:25:14:40 | ControlFlowNode for Attribute() | provenance | str.join | +| src/unsafe_shell_test.py:14:35:14:38 | ControlFlowNode for name | src/unsafe_shell_test.py:14:34:14:39 | ControlFlowNode for List [List element] | provenance | | | src/unsafe_shell_test.py:26:20:26:23 | ControlFlowNode for name | src/unsafe_shell_test.py:29:30:29:33 | ControlFlowNode for name | provenance | | | src/unsafe_shell_test.py:36:22:36:25 | ControlFlowNode for name | src/unsafe_shell_test.py:39:30:39:33 | ControlFlowNode for name | provenance | | | src/unsafe_shell_test.py:36:22:36:25 | ControlFlowNode for name | src/unsafe_shell_test.py:44:20:44:23 | ControlFlowNode for name | provenance | | @@ -15,7 +18,10 @@ nodes | src/unsafe_shell_test.py:5:25:5:28 | ControlFlowNode for name | semmle.label | ControlFlowNode for name | | src/unsafe_shell_test.py:8:23:8:26 | ControlFlowNode for name | semmle.label | ControlFlowNode for name | | src/unsafe_shell_test.py:11:25:11:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| src/unsafe_shell_test.py:11:34:11:37 | ControlFlowNode for name | semmle.label | ControlFlowNode for name | | src/unsafe_shell_test.py:14:25:14:40 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| src/unsafe_shell_test.py:14:34:14:39 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | +| src/unsafe_shell_test.py:14:35:14:38 | ControlFlowNode for name | semmle.label | ControlFlowNode for name | | src/unsafe_shell_test.py:17:32:17:35 | ControlFlowNode for name | semmle.label | ControlFlowNode for name | | src/unsafe_shell_test.py:20:27:20:30 | ControlFlowNode for name | semmle.label | ControlFlowNode for name | | src/unsafe_shell_test.py:26:20:26:23 | ControlFlowNode for name | semmle.label | ControlFlowNode for name | From 20ce679d611a0e4981604307516034e876282ec7 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 09:48:46 +0100 Subject: [PATCH 198/226] Accept changed edges in test output No changes to alerts --- .../Security/CWE-022-TarSlip/TarSlip.expected | 26 ++++++++++++++++--- .../UnsafeUnpack.expected | 3 +++ .../RemoteCommandExecution.expected | 6 ++++- .../XsltInjection.expected | 22 +++++++++++----- .../dataflow/summaries/summaries.expected | 8 +----- .../UntrustedDataToExternalAPI.expected | 2 ++ .../ReflectedXss.expected | 2 ++ .../CleartextStorage.expected | 10 ++++--- .../NoSqlInjection.expected | 1 + 9 files changed, 60 insertions(+), 20 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected index 97527c300db..6de2b27bfa7 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.expected @@ -3,11 +3,15 @@ edges | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:15:1:15:3 | ControlFlowNode for tar | provenance | | | TarSlipImprov.py:17:5:17:10 | ControlFlowNode for member | TarSlipImprov.py:20:19:20:24 | ControlFlowNode for member | provenance | | | TarSlipImprov.py:20:5:20:10 | [post] ControlFlowNode for result | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | provenance | | +| TarSlipImprov.py:20:5:20:10 | [post] ControlFlowNode for result [List element] | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | provenance | | | TarSlipImprov.py:20:19:20:24 | ControlFlowNode for member | TarSlipImprov.py:20:5:20:10 | [post] ControlFlowNode for result | provenance | list.append | +| TarSlipImprov.py:20:19:20:24 | ControlFlowNode for member | TarSlipImprov.py:20:5:20:10 | [post] ControlFlowNode for result [List element] | provenance | list.append | | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:28:9:28:14 | ControlFlowNode for member | provenance | | | TarSlipImprov.py:28:9:28:14 | ControlFlowNode for member | TarSlipImprov.py:35:23:35:28 | ControlFlowNode for member | provenance | | | TarSlipImprov.py:35:9:35:14 | [post] ControlFlowNode for result | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | provenance | | +| TarSlipImprov.py:35:9:35:14 | [post] ControlFlowNode for result [List element] | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result [List element] | provenance | | | TarSlipImprov.py:35:23:35:28 | ControlFlowNode for member | TarSlipImprov.py:35:9:35:14 | [post] ControlFlowNode for result | provenance | list.append | +| TarSlipImprov.py:35:23:35:28 | ControlFlowNode for member | TarSlipImprov.py:35:9:35:14 | [post] ControlFlowNode for result [List element] | provenance | list.append | | TarSlipImprov.py:38:1:38:3 | ControlFlowNode for tar | TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | provenance | | | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:38:1:38:3 | ControlFlowNode for tar | provenance | | | TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | provenance | | @@ -34,16 +38,19 @@ edges | TarSlipImprov.py:142:9:142:13 | ControlFlowNode for entry | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | provenance | | | TarSlipImprov.py:151:14:151:50 | ControlFlowNode for closing() | TarSlipImprov.py:151:55:151:56 | ControlFlowNode for tf | provenance | | | TarSlipImprov.py:151:22:151:49 | ControlFlowNode for Attribute() | TarSlipImprov.py:151:14:151:50 | ControlFlowNode for closing() | provenance | Config | -| TarSlipImprov.py:151:55:151:56 | ControlFlowNode for tf | TarSlipImprov.py:152:13:152:20 | ControlFlowNode for Yield | provenance | | | TarSlipImprov.py:151:55:151:56 | ControlFlowNode for tf | TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf | provenance | | -| TarSlipImprov.py:152:13:152:20 | ControlFlowNode for Yield | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | provenance | | +| TarSlipImprov.py:152:13:152:20 | ControlFlowNode for Yield [List element] | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() [List element] | provenance | | +| TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf | TarSlipImprov.py:152:13:152:20 | ControlFlowNode for Yield [List element] | provenance | | | TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | provenance | | | TarSlipImprov.py:157:9:157:14 | ControlFlowNode for tar_cm | TarSlipImprov.py:162:20:162:23 | ControlFlowNode for tarc | provenance | | +| TarSlipImprov.py:157:9:157:14 | ControlFlowNode for tar_cm [List element] | TarSlipImprov.py:162:20:162:23 | ControlFlowNode for tarc [List element] | provenance | | | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | TarSlipImprov.py:157:9:157:14 | ControlFlowNode for tar_cm | provenance | | +| TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() [List element] | TarSlipImprov.py:157:9:157:14 | ControlFlowNode for tar_cm [List element] | provenance | | | TarSlipImprov.py:159:9:159:14 | ControlFlowNode for tar_cm | TarSlipImprov.py:162:20:162:23 | ControlFlowNode for tarc | provenance | | | TarSlipImprov.py:159:18:159:52 | ControlFlowNode for closing() | TarSlipImprov.py:159:9:159:14 | ControlFlowNode for tar_cm | provenance | | | TarSlipImprov.py:159:26:159:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:159:18:159:52 | ControlFlowNode for closing() | provenance | Config | | TarSlipImprov.py:162:20:162:23 | ControlFlowNode for tarc | TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | provenance | | +| TarSlipImprov.py:162:20:162:23 | ControlFlowNode for tarc [List element] | TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | provenance | | | TarSlipImprov.py:176:6:176:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:176:36:176:38 | ControlFlowNode for tar | provenance | | | TarSlipImprov.py:176:36:176:38 | ControlFlowNode for tar | TarSlipImprov.py:177:9:177:13 | ControlFlowNode for entry | provenance | | | TarSlipImprov.py:177:9:177:13 | ControlFlowNode for entry | TarSlipImprov.py:178:36:178:40 | ControlFlowNode for entry | provenance | | @@ -60,7 +67,9 @@ edges | TarSlipImprov.py:231:43:231:52 | ControlFlowNode for corpus_tar | TarSlipImprov.py:233:9:233:9 | ControlFlowNode for f | provenance | | | TarSlipImprov.py:233:9:233:9 | ControlFlowNode for f | TarSlipImprov.py:235:28:235:28 | ControlFlowNode for f | provenance | | | TarSlipImprov.py:235:13:235:19 | [post] ControlFlowNode for members | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | provenance | | +| TarSlipImprov.py:235:13:235:19 | [post] ControlFlowNode for members [List element] | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | provenance | | | TarSlipImprov.py:235:28:235:28 | ControlFlowNode for f | TarSlipImprov.py:235:13:235:19 | [post] ControlFlowNode for members | provenance | list.append | +| TarSlipImprov.py:235:28:235:28 | ControlFlowNode for f | TarSlipImprov.py:235:13:235:19 | [post] ControlFlowNode for members [List element] | provenance | list.append | | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:258:31:258:33 | ControlFlowNode for tar | provenance | | | TarSlipImprov.py:258:31:258:33 | ControlFlowNode for tar | TarSlipImprov.py:259:9:259:13 | ControlFlowNode for entry | provenance | | | TarSlipImprov.py:259:9:259:13 | ControlFlowNode for entry | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | provenance | | @@ -85,19 +94,24 @@ edges | TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:304:1:304:3 | ControlFlowNode for tar | provenance | | | TarSlipImprov.py:306:5:306:10 | ControlFlowNode for member | TarSlipImprov.py:309:19:309:24 | ControlFlowNode for member | provenance | | | TarSlipImprov.py:309:5:309:10 | [post] ControlFlowNode for result | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | provenance | | +| TarSlipImprov.py:309:5:309:10 | [post] ControlFlowNode for result [List element] | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | provenance | | | TarSlipImprov.py:309:19:309:24 | ControlFlowNode for member | TarSlipImprov.py:309:5:309:10 | [post] ControlFlowNode for result | provenance | list.append | +| TarSlipImprov.py:309:19:309:24 | ControlFlowNode for member | TarSlipImprov.py:309:5:309:10 | [post] ControlFlowNode for result [List element] | provenance | list.append | nodes | TarSlipImprov.py:15:1:15:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:17:5:17:10 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | | TarSlipImprov.py:20:5:20:10 | [post] ControlFlowNode for result | semmle.label | [post] ControlFlowNode for result | +| TarSlipImprov.py:20:5:20:10 | [post] ControlFlowNode for result [List element] | semmle.label | [post] ControlFlowNode for result [List element] | | TarSlipImprov.py:20:19:20:24 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | semmle.label | ControlFlowNode for tarfile | | TarSlipImprov.py:28:9:28:14 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | | TarSlipImprov.py:35:9:35:14 | [post] ControlFlowNode for result | semmle.label | [post] ControlFlowNode for result | +| TarSlipImprov.py:35:9:35:14 | [post] ControlFlowNode for result [List element] | semmle.label | [post] ControlFlowNode for result [List element] | | TarSlipImprov.py:35:23:35:28 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | +| TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result [List element] | semmle.label | ControlFlowNode for result [List element] | | TarSlipImprov.py:38:1:38:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | semmle.label | ControlFlowNode for members_filter1() | @@ -133,14 +147,17 @@ nodes | TarSlipImprov.py:151:14:151:50 | ControlFlowNode for closing() | semmle.label | ControlFlowNode for closing() | | TarSlipImprov.py:151:22:151:49 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:151:55:151:56 | ControlFlowNode for tf | semmle.label | ControlFlowNode for tf | -| TarSlipImprov.py:152:13:152:20 | ControlFlowNode for Yield | semmle.label | ControlFlowNode for Yield | +| TarSlipImprov.py:152:13:152:20 | ControlFlowNode for Yield [List element] | semmle.label | ControlFlowNode for Yield [List element] | | TarSlipImprov.py:152:19:152:20 | ControlFlowNode for tf | semmle.label | ControlFlowNode for tf | | TarSlipImprov.py:157:9:157:14 | ControlFlowNode for tar_cm | semmle.label | ControlFlowNode for tar_cm | +| TarSlipImprov.py:157:9:157:14 | ControlFlowNode for tar_cm [List element] | semmle.label | ControlFlowNode for tar_cm [List element] | | TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() | semmle.label | ControlFlowNode for py2_tarxz() | +| TarSlipImprov.py:157:18:157:40 | ControlFlowNode for py2_tarxz() [List element] | semmle.label | ControlFlowNode for py2_tarxz() [List element] | | TarSlipImprov.py:159:9:159:14 | ControlFlowNode for tar_cm | semmle.label | ControlFlowNode for tar_cm | | TarSlipImprov.py:159:18:159:52 | ControlFlowNode for closing() | semmle.label | ControlFlowNode for closing() | | TarSlipImprov.py:159:26:159:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:162:20:162:23 | ControlFlowNode for tarc | semmle.label | ControlFlowNode for tarc | +| TarSlipImprov.py:162:20:162:23 | ControlFlowNode for tarc [List element] | semmle.label | ControlFlowNode for tarc [List element] | | TarSlipImprov.py:169:9:169:12 | ControlFlowNode for tarc | semmle.label | ControlFlowNode for tarc | | TarSlipImprov.py:176:6:176:31 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:176:36:176:38 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | @@ -163,6 +180,7 @@ nodes | TarSlipImprov.py:231:43:231:52 | ControlFlowNode for corpus_tar | semmle.label | ControlFlowNode for corpus_tar | | TarSlipImprov.py:233:9:233:9 | ControlFlowNode for f | semmle.label | ControlFlowNode for f | | TarSlipImprov.py:235:13:235:19 | [post] ControlFlowNode for members | semmle.label | [post] ControlFlowNode for members | +| TarSlipImprov.py:235:13:235:19 | [post] ControlFlowNode for members [List element] | semmle.label | [post] ControlFlowNode for members [List element] | | TarSlipImprov.py:235:28:235:28 | ControlFlowNode for f | semmle.label | ControlFlowNode for f | | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | semmle.label | ControlFlowNode for members | | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -198,11 +216,13 @@ nodes | TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TarSlipImprov.py:306:5:306:10 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | | TarSlipImprov.py:309:5:309:10 | [post] ControlFlowNode for result | semmle.label | [post] ControlFlowNode for result | +| TarSlipImprov.py:309:5:309:10 | [post] ControlFlowNode for result [List element] | semmle.label | [post] ControlFlowNode for result [List element] | | TarSlipImprov.py:309:19:309:24 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | subpaths | TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | +| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result [List element] | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | #select | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | ControlFlowNode for result | | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | ControlFlowNode for members_filter1() | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected index de8721382bf..ccc2daba50b 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-UnsafeUnpacking/UnsafeUnpack.expected @@ -93,7 +93,9 @@ edges | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | provenance | | | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | provenance | | +| UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result [List element] | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | provenance | | | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | provenance | list.append | +| UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result [List element] | provenance | list.append | | UnsafeUnpack.py:171:1:171:8 | ControlFlowNode for response | UnsafeUnpack.py:174:15:174:22 | ControlFlowNode for response | provenance | | | UnsafeUnpack.py:171:12:171:50 | ControlFlowNode for Attribute() | UnsafeUnpack.py:171:1:171:8 | ControlFlowNode for response | provenance | | | UnsafeUnpack.py:173:11:173:17 | ControlFlowNode for tarpath | UnsafeUnpack.py:176:17:176:23 | ControlFlowNode for tarpath | provenance | | @@ -189,6 +191,7 @@ nodes | UnsafeUnpack.py:163:23:163:28 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | | UnsafeUnpack.py:163:33:163:35 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | | UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result | semmle.label | [post] ControlFlowNode for result | +| UnsafeUnpack.py:166:23:166:28 | [post] ControlFlowNode for result [List element] | semmle.label | [post] ControlFlowNode for result [List element] | | UnsafeUnpack.py:166:37:166:42 | ControlFlowNode for member | semmle.label | ControlFlowNode for member | | UnsafeUnpack.py:167:67:167:72 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | | UnsafeUnpack.py:171:1:171:8 | ControlFlowNode for response | semmle.label | ControlFlowNode for response | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/RemoteCommandExecution.expected b/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/RemoteCommandExecution.expected index 914d6fbbee4..9ae14db9467 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/RemoteCommandExecution.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/RemoteCommandExecution.expected @@ -3,8 +3,10 @@ edges | Netmiko.py:18:16:18:18 | ControlFlowNode for cmd | Netmiko.py:20:45:20:47 | ControlFlowNode for cmd | provenance | | | Netmiko.py:18:16:18:18 | ControlFlowNode for cmd | Netmiko.py:21:52:21:54 | ControlFlowNode for cmd | provenance | | | Netmiko.py:18:16:18:18 | ControlFlowNode for cmd | Netmiko.py:22:52:22:54 | ControlFlowNode for cmd | provenance | | -| Netmiko.py:18:16:18:18 | ControlFlowNode for cmd | Netmiko.py:23:41:23:57 | ControlFlowNode for List | provenance | | +| Netmiko.py:18:16:18:18 | ControlFlowNode for cmd | Netmiko.py:23:43:23:45 | ControlFlowNode for cmd | provenance | | | Netmiko.py:18:16:18:18 | ControlFlowNode for cmd | Netmiko.py:24:48:24:50 | ControlFlowNode for cmd | provenance | | +| Netmiko.py:23:42:23:56 | ControlFlowNode for List [List element] | Netmiko.py:23:41:23:57 | ControlFlowNode for List | provenance | | +| Netmiko.py:23:43:23:45 | ControlFlowNode for cmd | Netmiko.py:23:42:23:56 | ControlFlowNode for List [List element] | provenance | | | Pexpect.py:15:16:15:18 | ControlFlowNode for cmd | Pexpect.py:16:14:16:16 | ControlFlowNode for cmd | provenance | | | Pexpect.py:15:16:15:18 | ControlFlowNode for cmd | Pexpect.py:18:18:18:20 | ControlFlowNode for cmd | provenance | | | Scrapli.py:13:16:13:18 | ControlFlowNode for cmd | Scrapli.py:24:42:24:44 | ControlFlowNode for cmd | provenance | | @@ -32,6 +34,8 @@ nodes | Netmiko.py:21:52:21:54 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | | Netmiko.py:22:52:22:54 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | | Netmiko.py:23:41:23:57 | ControlFlowNode for List | semmle.label | ControlFlowNode for List | +| Netmiko.py:23:42:23:56 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | +| Netmiko.py:23:43:23:45 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | | Netmiko.py:24:48:24:50 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | | Pexpect.py:15:16:15:18 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | | Pexpect.py:16:14:16:16 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected index 64b10ac564d..8c64cccebc1 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected @@ -7,6 +7,7 @@ edges | xslt.py:10:17:10:43 | ControlFlowNode for Attribute() | xslt.py:10:5:10:13 | ControlFlowNode for xsltQuery | provenance | | | xslt.py:11:5:11:13 | ControlFlowNode for xslt_root | xslt.py:14:29:14:37 | ControlFlowNode for xslt_root | provenance | | | xslt.py:11:17:11:36 | ControlFlowNode for Attribute() | xslt.py:11:5:11:13 | ControlFlowNode for xslt_root | provenance | | +| xslt.py:11:27:11:35 | ControlFlowNode for xsltQuery | xslt.py:11:17:11:36 | ControlFlowNode for Attribute() | provenance | | | xslt.py:11:27:11:35 | ControlFlowNode for xsltQuery | xslt.py:11:17:11:36 | ControlFlowNode for Attribute() | provenance | Config | | xslt.py:11:27:11:35 | ControlFlowNode for xsltQuery | xslt.py:11:17:11:36 | ControlFlowNode for Attribute() | provenance | Decoding-XML | | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:3:26:3:32 | ControlFlowNode for request | provenance | | @@ -21,6 +22,7 @@ edges | xsltInjection.py:10:17:10:43 | ControlFlowNode for Attribute() | xsltInjection.py:10:5:10:13 | ControlFlowNode for xsltQuery | provenance | | | xsltInjection.py:11:5:11:13 | ControlFlowNode for xslt_root | xsltInjection.py:12:28:12:36 | ControlFlowNode for xslt_root | provenance | | | xsltInjection.py:11:17:11:36 | ControlFlowNode for Attribute() | xsltInjection.py:11:5:11:13 | ControlFlowNode for xslt_root | provenance | | +| xsltInjection.py:11:27:11:35 | ControlFlowNode for xsltQuery | xsltInjection.py:11:17:11:36 | ControlFlowNode for Attribute() | provenance | | | xsltInjection.py:11:27:11:35 | ControlFlowNode for xsltQuery | xsltInjection.py:11:17:11:36 | ControlFlowNode for Attribute() | provenance | Config | | xsltInjection.py:11:27:11:35 | ControlFlowNode for xsltQuery | xsltInjection.py:11:17:11:36 | ControlFlowNode for Attribute() | provenance | Decoding-XML | | xsltInjection.py:17:5:17:13 | ControlFlowNode for xsltQuery | xsltInjection.py:18:27:18:35 | ControlFlowNode for xsltQuery | provenance | | @@ -29,6 +31,7 @@ edges | xsltInjection.py:17:17:17:43 | ControlFlowNode for Attribute() | xsltInjection.py:17:5:17:13 | ControlFlowNode for xsltQuery | provenance | | | xsltInjection.py:18:5:18:13 | ControlFlowNode for xslt_root | xsltInjection.py:21:29:21:37 | ControlFlowNode for xslt_root | provenance | | | xsltInjection.py:18:17:18:36 | ControlFlowNode for Attribute() | xsltInjection.py:18:5:18:13 | ControlFlowNode for xslt_root | provenance | | +| xsltInjection.py:18:27:18:35 | ControlFlowNode for xsltQuery | xsltInjection.py:18:17:18:36 | ControlFlowNode for Attribute() | provenance | | | xsltInjection.py:18:27:18:35 | ControlFlowNode for xsltQuery | xsltInjection.py:18:17:18:36 | ControlFlowNode for Attribute() | provenance | Config | | xsltInjection.py:18:27:18:35 | ControlFlowNode for xsltQuery | xsltInjection.py:18:17:18:36 | ControlFlowNode for Attribute() | provenance | Decoding-XML | | xsltInjection.py:26:5:26:13 | ControlFlowNode for xsltQuery | xsltInjection.py:27:27:27:35 | ControlFlowNode for xsltQuery | provenance | | @@ -37,6 +40,7 @@ edges | xsltInjection.py:26:17:26:43 | ControlFlowNode for Attribute() | xsltInjection.py:26:5:26:13 | ControlFlowNode for xsltQuery | provenance | | | xsltInjection.py:27:5:27:13 | ControlFlowNode for xslt_root | xsltInjection.py:31:24:31:32 | ControlFlowNode for xslt_root | provenance | | | xsltInjection.py:27:17:27:36 | ControlFlowNode for Attribute() | xsltInjection.py:27:5:27:13 | ControlFlowNode for xslt_root | provenance | | +| xsltInjection.py:27:27:27:35 | ControlFlowNode for xsltQuery | xsltInjection.py:27:17:27:36 | ControlFlowNode for Attribute() | provenance | | | xsltInjection.py:27:27:27:35 | ControlFlowNode for xsltQuery | xsltInjection.py:27:17:27:36 | ControlFlowNode for Attribute() | provenance | Config | | xsltInjection.py:27:27:27:35 | ControlFlowNode for xsltQuery | xsltInjection.py:27:17:27:36 | ControlFlowNode for Attribute() | provenance | Decoding-XML | | xsltInjection.py:35:5:35:13 | ControlFlowNode for xsltQuery | xsltInjection.py:36:34:36:42 | ControlFlowNode for xsltQuery | provenance | | @@ -45,17 +49,21 @@ edges | xsltInjection.py:35:17:35:43 | ControlFlowNode for Attribute() | xsltInjection.py:35:5:35:13 | ControlFlowNode for xsltQuery | provenance | | | xsltInjection.py:36:5:36:13 | ControlFlowNode for xslt_root | xsltInjection.py:40:24:40:32 | ControlFlowNode for xslt_root | provenance | | | xsltInjection.py:36:17:36:43 | ControlFlowNode for Attribute() | xsltInjection.py:36:5:36:13 | ControlFlowNode for xslt_root | provenance | | +| xsltInjection.py:36:34:36:42 | ControlFlowNode for xsltQuery | xsltInjection.py:36:17:36:43 | ControlFlowNode for Attribute() | provenance | | | xsltInjection.py:36:34:36:42 | ControlFlowNode for xsltQuery | xsltInjection.py:36:17:36:43 | ControlFlowNode for Attribute() | provenance | Config | | xsltInjection.py:36:34:36:42 | ControlFlowNode for xsltQuery | xsltInjection.py:36:17:36:43 | ControlFlowNode for Attribute() | provenance | Decoding-XML | -| xsltInjection.py:44:5:44:13 | ControlFlowNode for xsltQuery | xsltInjection.py:45:5:45:15 | ControlFlowNode for xsltStrings | provenance | | +| xsltInjection.py:44:5:44:13 | ControlFlowNode for xsltQuery | xsltInjection.py:45:20:45:28 | ControlFlowNode for xsltQuery | provenance | | | xsltInjection.py:44:17:44:23 | ControlFlowNode for request | xsltInjection.py:44:17:44:28 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | xsltInjection.py:44:17:44:28 | ControlFlowNode for Attribute | xsltInjection.py:44:17:44:43 | ControlFlowNode for Attribute() | provenance | dict.get | | xsltInjection.py:44:17:44:43 | ControlFlowNode for Attribute() | xsltInjection.py:44:5:44:13 | ControlFlowNode for xsltQuery | provenance | | -| xsltInjection.py:45:5:45:15 | ControlFlowNode for xsltStrings | xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings | provenance | | +| xsltInjection.py:45:5:45:15 | ControlFlowNode for xsltStrings [List element] | xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | provenance | | +| xsltInjection.py:45:19:45:44 | ControlFlowNode for List [List element] | xsltInjection.py:45:5:45:15 | ControlFlowNode for xsltStrings [List element] | provenance | | +| xsltInjection.py:45:20:45:28 | ControlFlowNode for xsltQuery | xsltInjection.py:45:19:45:44 | ControlFlowNode for List [List element] | provenance | | | xsltInjection.py:46:5:46:13 | ControlFlowNode for xslt_root | xsltInjection.py:50:24:50:32 | ControlFlowNode for xslt_root | provenance | | | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | xsltInjection.py:46:5:46:13 | ControlFlowNode for xslt_root | provenance | | -| xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | provenance | Config | -| xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | provenance | Decoding-XML | +| xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | provenance | | +| xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | provenance | Config | +| xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | provenance | Decoding-XML | nodes | xslt.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | xslt.py:3:26:3:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | @@ -105,10 +113,12 @@ nodes | xsltInjection.py:44:17:44:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | xsltInjection.py:44:17:44:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | xsltInjection.py:44:17:44:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| xsltInjection.py:45:5:45:15 | ControlFlowNode for xsltStrings | semmle.label | ControlFlowNode for xsltStrings | +| xsltInjection.py:45:5:45:15 | ControlFlowNode for xsltStrings [List element] | semmle.label | ControlFlowNode for xsltStrings [List element] | +| xsltInjection.py:45:19:45:44 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | +| xsltInjection.py:45:20:45:28 | ControlFlowNode for xsltQuery | semmle.label | ControlFlowNode for xsltQuery | | xsltInjection.py:46:5:46:13 | ControlFlowNode for xslt_root | semmle.label | ControlFlowNode for xslt_root | | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings | semmle.label | ControlFlowNode for xsltStrings | +| xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | semmle.label | ControlFlowNode for xsltStrings [List element] | | xsltInjection.py:50:24:50:32 | ControlFlowNode for xslt_root | semmle.label | ControlFlowNode for xslt_root | subpaths #select diff --git a/python/ql/test/library-tests/dataflow/summaries/summaries.expected b/python/ql/test/library-tests/dataflow/summaries/summaries.expected index 4a97116f8cd..fbc09b5fa6e 100644 --- a/python/ql/test/library-tests/dataflow/summaries/summaries.expected +++ b/python/ql/test/library-tests/dataflow/summaries/summaries.expected @@ -7,13 +7,9 @@ edges | summaries.py:36:38:36:38 | ControlFlowNode for x | summaries.py:36:41:36:45 | ControlFlowNode for BinaryExpr | provenance | | | summaries.py:36:48:36:53 | ControlFlowNode for SOURCE | summaries.py:36:18:36:54 | ControlFlowNode for apply_lambda() | provenance | apply_lambda | | summaries.py:36:48:36:53 | ControlFlowNode for SOURCE | summaries.py:36:38:36:38 | ControlFlowNode for x | provenance | apply_lambda | -| summaries.py:44:1:44:12 | ControlFlowNode for tainted_list | summaries.py:45:6:45:20 | ControlFlowNode for Subscript | provenance | | | summaries.py:44:1:44:12 | ControlFlowNode for tainted_list [List element] | summaries.py:45:6:45:17 | ControlFlowNode for tainted_list [List element] | provenance | | -| summaries.py:44:16:44:33 | ControlFlowNode for reversed() | summaries.py:44:1:44:12 | ControlFlowNode for tainted_list | provenance | | | summaries.py:44:16:44:33 | ControlFlowNode for reversed() [List element] | summaries.py:44:1:44:12 | ControlFlowNode for tainted_list [List element] | provenance | | -| summaries.py:44:25:44:32 | ControlFlowNode for List | summaries.py:44:16:44:33 | ControlFlowNode for reversed() | provenance | builtins.reversed | | summaries.py:44:25:44:32 | ControlFlowNode for List [List element] | summaries.py:44:16:44:33 | ControlFlowNode for reversed() [List element] | provenance | builtins.reversed | -| summaries.py:44:26:44:31 | ControlFlowNode for SOURCE | summaries.py:44:25:44:32 | ControlFlowNode for List | provenance | | | summaries.py:44:26:44:31 | ControlFlowNode for SOURCE | summaries.py:44:25:44:32 | ControlFlowNode for List [List element] | provenance | | | summaries.py:45:6:45:17 | ControlFlowNode for tainted_list [List element] | summaries.py:45:6:45:20 | ControlFlowNode for Subscript | provenance | | | summaries.py:48:15:48:15 | ControlFlowNode for x | summaries.py:49:12:49:18 | ControlFlowNode for BinaryExpr | provenance | | @@ -42,6 +38,7 @@ edges | summaries.py:67:1:67:18 | ControlFlowNode for tainted_resultlist | summaries.py:68:6:68:26 | ControlFlowNode for Subscript | provenance | | | summaries.py:67:1:67:18 | ControlFlowNode for tainted_resultlist [List element] | summaries.py:68:6:68:23 | ControlFlowNode for tainted_resultlist [List element] | provenance | | | summaries.py:67:22:67:39 | ControlFlowNode for json_loads() [List element] | summaries.py:67:1:67:18 | ControlFlowNode for tainted_resultlist [List element] | provenance | | +| summaries.py:67:33:67:38 | ControlFlowNode for SOURCE | summaries.py:67:1:67:18 | ControlFlowNode for tainted_resultlist | provenance | | | summaries.py:67:33:67:38 | ControlFlowNode for SOURCE | summaries.py:67:1:67:18 | ControlFlowNode for tainted_resultlist | provenance | Decoding-JSON | | summaries.py:67:33:67:38 | ControlFlowNode for SOURCE | summaries.py:67:22:67:39 | ControlFlowNode for json_loads() [List element] | provenance | json.loads | | summaries.py:68:6:68:23 | ControlFlowNode for tainted_resultlist [List element] | summaries.py:68:6:68:26 | ControlFlowNode for Subscript | provenance | | @@ -56,11 +53,8 @@ nodes | summaries.py:36:41:36:45 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | summaries.py:36:48:36:53 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | summaries.py:37:6:37:19 | ControlFlowNode for tainted_lambda | semmle.label | ControlFlowNode for tainted_lambda | -| summaries.py:44:1:44:12 | ControlFlowNode for tainted_list | semmle.label | ControlFlowNode for tainted_list | | summaries.py:44:1:44:12 | ControlFlowNode for tainted_list [List element] | semmle.label | ControlFlowNode for tainted_list [List element] | -| summaries.py:44:16:44:33 | ControlFlowNode for reversed() | semmle.label | ControlFlowNode for reversed() | | summaries.py:44:16:44:33 | ControlFlowNode for reversed() [List element] | semmle.label | ControlFlowNode for reversed() [List element] | -| summaries.py:44:25:44:32 | ControlFlowNode for List | semmle.label | ControlFlowNode for List | | summaries.py:44:25:44:32 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | | summaries.py:44:26:44:31 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | summaries.py:45:6:45:17 | ControlFlowNode for tainted_list [List element] | semmle.label | ControlFlowNode for tainted_list [List element] | diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected index 08a5b798f71..7f83ceae8fe 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected @@ -5,11 +5,13 @@ edges | test.py:5:26:5:32 | ControlFlowNode for request | test.py:34:12:34:18 | ControlFlowNode for request | provenance | | | test.py:5:26:5:32 | ControlFlowNode for request | test.py:42:12:42:18 | ControlFlowNode for request | provenance | | | test.py:5:26:5:32 | ControlFlowNode for request | test.py:54:12:54:18 | ControlFlowNode for request | provenance | | +| test.py:13:5:13:12 | ControlFlowNode for data_raw | test.py:14:5:14:8 | ControlFlowNode for data | provenance | | | test.py:13:5:13:12 | ControlFlowNode for data_raw | test.py:14:5:14:8 | ControlFlowNode for data | provenance | Decoding-Base64 | | test.py:13:16:13:22 | ControlFlowNode for request | test.py:13:16:13:27 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | test.py:13:16:13:27 | ControlFlowNode for Attribute | test.py:13:16:13:39 | ControlFlowNode for Attribute() | provenance | dict.get | | test.py:13:16:13:39 | ControlFlowNode for Attribute() | test.py:13:5:13:12 | ControlFlowNode for data_raw | provenance | | | test.py:14:5:14:8 | ControlFlowNode for data | test.py:15:36:15:39 | ControlFlowNode for data | provenance | | +| test.py:23:5:23:12 | ControlFlowNode for data_raw | test.py:24:5:24:8 | ControlFlowNode for data | provenance | | | test.py:23:5:23:12 | ControlFlowNode for data_raw | test.py:24:5:24:8 | ControlFlowNode for data | provenance | Decoding-Base64 | | test.py:23:16:23:22 | ControlFlowNode for request | test.py:23:16:23:27 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | test.py:23:16:23:27 | ControlFlowNode for Attribute | test.py:23:16:23:39 | ControlFlowNode for Attribute() | provenance | dict.get | diff --git a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected index 2e6c5c33fbc..d332231e0c9 100644 --- a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected +++ b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected @@ -7,8 +7,10 @@ edges | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | reflected_xss.py:9:18:9:29 | ControlFlowNode for Attribute | reflected_xss.py:9:18:9:45 | ControlFlowNode for Attribute() | provenance | dict.get | | reflected_xss.py:9:18:9:45 | ControlFlowNode for Attribute() | reflected_xss.py:9:5:9:14 | ControlFlowNode for first_name | provenance | | +| reflected_xss.py:21:5:21:8 | ControlFlowNode for data | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | provenance | | | reflected_xss.py:21:5:21:8 | ControlFlowNode for data | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | provenance | AdditionalTaintStep | | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | reflected_xss.py:21:5:21:8 | ControlFlowNode for data | provenance | AdditionalTaintStep | +| reflected_xss.py:27:5:27:8 | ControlFlowNode for data | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | provenance | | | reflected_xss.py:27:5:27:8 | ControlFlowNode for data | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | provenance | AdditionalTaintStep | | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | reflected_xss.py:27:5:27:8 | ControlFlowNode for data | provenance | AdditionalTaintStep | nodes diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected index c3c1206ce92..ea41c1ba651 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected @@ -4,9 +4,11 @@ edges | password_in_cookie.py:14:5:14:12 | ControlFlowNode for password | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | provenance | | | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | password_in_cookie.py:14:5:14:12 | ControlFlowNode for password | provenance | | | test.py:15:5:15:12 | ControlFlowNode for password | test.py:17:20:17:27 | ControlFlowNode for password | provenance | | -| test.py:15:5:15:12 | ControlFlowNode for password | test.py:18:9:18:13 | ControlFlowNode for lines | provenance | | +| test.py:15:5:15:12 | ControlFlowNode for password | test.py:18:18:18:32 | ControlFlowNode for BinaryExpr | provenance | | | test.py:15:16:15:29 | ControlFlowNode for get_password() | test.py:15:5:15:12 | ControlFlowNode for password | provenance | | -| test.py:18:9:18:13 | ControlFlowNode for lines | test.py:19:25:19:29 | ControlFlowNode for lines | provenance | | +| test.py:18:9:18:13 | ControlFlowNode for lines [List element] | test.py:19:25:19:29 | ControlFlowNode for lines | provenance | | +| test.py:18:17:18:33 | ControlFlowNode for List [List element] | test.py:18:9:18:13 | ControlFlowNode for lines [List element] | provenance | | +| test.py:18:18:18:32 | ControlFlowNode for BinaryExpr | test.py:18:17:18:33 | ControlFlowNode for List [List element] | provenance | | nodes | password_in_cookie.py:7:5:7:12 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -17,7 +19,9 @@ nodes | test.py:15:5:15:12 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | | test.py:15:16:15:29 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:17:20:17:27 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | -| test.py:18:9:18:13 | ControlFlowNode for lines | semmle.label | ControlFlowNode for lines | +| test.py:18:9:18:13 | ControlFlowNode for lines [List element] | semmle.label | ControlFlowNode for lines [List element] | +| test.py:18:17:18:33 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] | +| test.py:18:18:18:32 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | test.py:19:25:19:29 | ControlFlowNode for lines | semmle.label | ControlFlowNode for lines | subpaths #select diff --git a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected index 2ff9a0d10b7..fad6762e0f6 100644 --- a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/NoSqlInjection.expected @@ -133,6 +133,7 @@ edges | pymongo_test.py:54:5:54:10 | ControlFlowNode for search [Dictionary element at key body] | pymongo_test.py:59:49:59:54 | ControlFlowNode for search [Dictionary element at key body] | provenance | | | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict | pymongo_test.py:54:5:54:10 | ControlFlowNode for search | provenance | | | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict [Dictionary element at key body] | pymongo_test.py:54:5:54:10 | ControlFlowNode for search [Dictionary element at key body] | provenance | | +| pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict | provenance | | | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict | provenance | Decoding-NoSQL | | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:54:14:58:5 | ControlFlowNode for Dict [Dictionary element at key body] | provenance | | | pymongo_test.py:55:17:55:23 | ControlFlowNode for decoded | pymongo_test.py:61:49:61:55 | ControlFlowNode for decoded | provenance | | From b27d08ee32c678985aa73e73ef00090becd736d0 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 18:29:56 +0100 Subject: [PATCH 199/226] Update edges in expected test output --- .../Security/CWE-091-XsltInjection/XsltInjection.expected | 1 + .../frameworks/gradio/taint_step_test.expected | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected index 8c64cccebc1..8d960a22dfd 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected @@ -64,6 +64,7 @@ edges | xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | provenance | | | xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | provenance | Config | | xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | provenance | Decoding-XML | +| xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | xsltInjection.py:46:17:46:49 | ControlFlowNode for Attribute() | provenance | MaD:58660 | nodes | xslt.py:3:26:3:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | | xslt.py:3:26:3:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | diff --git a/python/ql/test/library-tests/frameworks/gradio/taint_step_test.expected b/python/ql/test/library-tests/frameworks/gradio/taint_step_test.expected index 2ebf825a19b..e617488aac1 100644 --- a/python/ql/test/library-tests/frameworks/gradio/taint_step_test.expected +++ b/python/ql/test/library-tests/frameworks/gradio/taint_step_test.expected @@ -3,10 +3,12 @@ edges | taint_step_test.py:5:12:5:35 | ControlFlowNode for Attribute() | taint_step_test.py:5:5:5:8 | ControlFlowNode for path | provenance | | | taint_step_test.py:6:5:6:8 | ControlFlowNode for file | taint_step_test.py:19:48:19:51 | ControlFlowNode for file | provenance | | | taint_step_test.py:6:12:6:35 | ControlFlowNode for Attribute() | taint_step_test.py:6:5:6:8 | ControlFlowNode for file | provenance | | -| taint_step_test.py:11:18:11:21 | ControlFlowNode for path | taint_step_test.py:12:9:12:16 | ControlFlowNode for filepath | provenance | | | taint_step_test.py:11:18:11:21 | ControlFlowNode for path | taint_step_test.py:12:9:12:16 | ControlFlowNode for filepath | provenance | AdditionalTaintStep | +| taint_step_test.py:11:18:11:21 | ControlFlowNode for path | taint_step_test.py:12:33:12:36 | ControlFlowNode for path | provenance | | | taint_step_test.py:11:24:11:27 | ControlFlowNode for file | taint_step_test.py:12:9:12:16 | ControlFlowNode for filepath | provenance | AdditionalTaintStep | | taint_step_test.py:12:9:12:16 | ControlFlowNode for filepath | taint_step_test.py:13:19:13:26 | ControlFlowNode for filepath | provenance | | +| taint_step_test.py:12:20:12:43 | ControlFlowNode for Attribute() | taint_step_test.py:12:9:12:16 | ControlFlowNode for filepath | provenance | | +| taint_step_test.py:12:33:12:36 | ControlFlowNode for path | taint_step_test.py:12:20:12:43 | ControlFlowNode for Attribute() | provenance | str.join | | taint_step_test.py:19:43:19:46 | ControlFlowNode for path | taint_step_test.py:11:18:11:21 | ControlFlowNode for path | provenance | AdditionalTaintStep | | taint_step_test.py:19:48:19:51 | ControlFlowNode for file | taint_step_test.py:11:24:11:27 | ControlFlowNode for file | provenance | AdditionalTaintStep | nodes @@ -17,6 +19,8 @@ nodes | taint_step_test.py:11:18:11:21 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | taint_step_test.py:11:24:11:27 | ControlFlowNode for file | semmle.label | ControlFlowNode for file | | taint_step_test.py:12:9:12:16 | ControlFlowNode for filepath | semmle.label | ControlFlowNode for filepath | +| taint_step_test.py:12:20:12:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| taint_step_test.py:12:33:12:36 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | taint_step_test.py:13:19:13:26 | ControlFlowNode for filepath | semmle.label | ControlFlowNode for filepath | | taint_step_test.py:19:43:19:46 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | taint_step_test.py:19:48:19:51 | ControlFlowNode for file | semmle.label | ControlFlowNode for file | From af45e53e77ab2a207da0b0f850f48c50410c0637 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 2 Jun 2026 21:18:53 +0200 Subject: [PATCH 200/226] Rust: Rename parameter in DB upgrade script --- .../66a489863649185f4a9770f894505803059a1312/upgrade.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/upgrade.properties b/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/upgrade.properties index 002daf2af7c..518d6277cf5 100644 --- a/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/upgrade.properties +++ b/rust/ql/lib/upgrades/66a489863649185f4a9770f894505803059a1312/upgrade.properties @@ -1,5 +1,5 @@ description: Renamed `impl_traits` to `impl_trait_ties` compatibility: full -impl_trait_ties.rel: reorder impl_traits(@impl id, @type_repr trait_ty) id trait_ty +impl_trait_ties.rel: reorder impl_traits(@impl id, @type_repr trait) id trait impl_traits.rel: delete \ No newline at end of file From 04341c47bdb710c03d6514e886edfd74094ae125 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 21:52:46 +0100 Subject: [PATCH 201/226] Tweak model for str.join --- .../lib/semmle/python/frameworks/Stdlib.qll | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 05e7a629de6..30e27934a29 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4277,9 +4277,14 @@ module StdlibPrivate { preservesValue = true ) or - input = ["Argument[0]", "Argument[0].ListElement"] and - output = "ReturnValue" and - preservesValue = false + ( + input = "Argument[0]" and + preservesValue = false + or + input = "Argument[0].ListElement" and + preservesValue = true + ) and + output = "ReturnValue" } } @@ -4985,9 +4990,16 @@ module StdlibPrivate { } override predicate propagatesFlow(string input, string output, boolean preservesValue) { - input = ["Argument[0,iterable:]", "Argument[0,iterable:].ListElement"] and - output = "ReturnValue" and - preservesValue = false + ( + // For code like `" ".join([name])` + input = "Argument[0,iterable:].ListElement" and + preservesValue = true + or + // For code like `" ".join(name)` + input = "Argument[0,iterable:]" and + preservesValue = false + ) and + output = "ReturnValue" } } From 5042fdee8494763812de02252948d26884f4429a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 21:53:14 +0100 Subject: [PATCH 202/226] Remove imprecise model for `list()` --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 30e27934a29..d41b656c6d5 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4244,15 +4244,9 @@ module StdlibPrivate { ) // TODO: Once we have DictKeyContent, we need to transform that into ListElementContent ) and - ( - // Element content is mutated into list element content - output = "ReturnValue.ListElement" and - preservesValue = true - or - // Since list content is imprecise, we also taint the list. - output = "ReturnValue" and - preservesValue = false - ) + // Element content is mutated into list element content + output = "ReturnValue.ListElement" and + preservesValue = true or input = "Argument[0]" and output = "ReturnValue" and From 6f2cc43f32bd6e1a8822425542fc199a534cd41d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 2 Jun 2026 21:55:58 +0100 Subject: [PATCH 203/226] Remove imprecise model for `tuple()` --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index d41b656c6d5..014ef4e9f64 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4271,14 +4271,9 @@ module StdlibPrivate { preservesValue = true ) or - ( - input = "Argument[0]" and - preservesValue = false - or - input = "Argument[0].ListElement" and - preservesValue = true - ) and - output = "ReturnValue" + input = "Argument[0].ListElement" and + output = "ReturnValue" and + preservesValue = true } } From 0a801440b98382688b642fb0476be56e3383fb88 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Wed, 3 Jun 2026 10:48:50 +0200 Subject: [PATCH 204/226] review comments --- .../lib/semmle/code/csharp/dataflow/Bound.qll | 26 ++++++++++++--- .../internal/rangeanalysis/BoundSpecific.qll | 30 ----------------- .../lib/semmle/code/java/dataflow/Bound.qll | 27 ++++++++++++++-- .../internal/rangeanalysis/BoundSpecific.qll | 32 ------------------- .../codeql/rangeanalysis/Bound.qll | 2 +- 5 files changed, 47 insertions(+), 70 deletions(-) delete mode 100644 csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll delete mode 100644 java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll index c08e2e1c0d4..85bfcd54bdc 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll @@ -5,10 +5,28 @@ overlay[local?] module; private import csharp as CS -private import internal.rangeanalysis.BoundSpecific -private import internal.rangeanalysis.BoundSpecific as BoundSpecific +private import semmle.code.csharp.dataflow.SSA::Ssa as Ssa +private import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils as CU +private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU +private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU private import codeql.rangeanalysis.Bound as SharedBound -private module BoundImpl = SharedBound::Bound; +/** Provides C#-specific definitions for bounds. */ +private module BoundDefs implements SharedBound::BoundDefinitions { + class Type = CS::Type; -import BoundImpl + class SsaVariable = SU::SsaVariable; + + class SsaSourceVariable = Ssa::SourceVariable; + + class Expr = CS::ControlFlowNodes::ExprNode; + + class IntegralType = CS::IntegralType; + + class ConstantIntegerExpr = CU::ConstantIntegerExpr; + + /** Holds if `e` is a bound expression and it is not an SSA variable read. */ + predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.getExpr()) } +} + +import SharedBound::Bound diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll deleted file mode 100644 index cbf395c24f4..00000000000 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Provides C#-specific definitions for bounds. - */ -overlay[local?] -module; - -private import csharp as CS -private import semmle.code.csharp.dataflow.SSA::Ssa as Ssa -private import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils as CU -private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU -private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU -private import codeql.rangeanalysis.Bound as SharedBound - -/** Provides C#-specific definitions for bounds. */ -module BoundDefs implements SharedBound::BoundDefinitions { - class Type = CS::Type; - - class SsaVariable = SU::SsaVariable; - - class SsaSourceVariable = Ssa::SourceVariable; - - class Expr = CS::ControlFlowNodes::ExprNode; - - class IntegralType = CS::IntegralType; - - class ConstantIntegerExpr = CU::ConstantIntegerExpr; - - /** Holds if `e` is a bound expression and it is not an SSA variable read. */ - predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.getExpr()) } -} diff --git a/java/ql/lib/semmle/code/java/dataflow/Bound.qll b/java/ql/lib/semmle/code/java/dataflow/Bound.qll index f82afcd17e4..37ce764c8e3 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Bound.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Bound.qll @@ -5,9 +5,30 @@ overlay[local?] module; private import java as J -private import internal.rangeanalysis.BoundSpecific as BoundSpecific +private import semmle.code.java.dataflow.SSA as Ssa +private import semmle.code.java.dataflow.RangeUtils as RU private import codeql.rangeanalysis.Bound as SharedBound -private module BoundImpl = SharedBound::Bound; +private module BoundDefs implements SharedBound::BoundDefinitions { + class SsaVariable extends Ssa::SsaDefinition { + /** Gets a use of this variable. */ + Expr getAUse() { result = super.getARead() } + } -import BoundImpl + class SsaSourceVariable = Ssa::SourceVariable; + + class Type = J::Type; + + class Expr = J::Expr; + + class IntegralType = J::IntegralType; + + class ConstantIntegerExpr = RU::ConstantIntegerExpr; + + /** Holds if `e` is a bound expression and it is not an SSA variable read. */ + predicate interestingExprBound(Expr e) { + e.(J::FieldRead).getField() instanceof J::ArrayLengthField + } +} + +import SharedBound::Bound diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll deleted file mode 100644 index 5435eeb4492..00000000000 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Provides Java-specific definitions for bounds. - */ -overlay[local?] -module; - -private import java as J -private import semmle.code.java.dataflow.SSA as Ssa -private import semmle.code.java.dataflow.RangeUtils as RU -private import codeql.rangeanalysis.Bound as SharedBound - -module BoundDefs implements SharedBound::BoundDefinitions { - class SsaVariable extends Ssa::SsaDefinition { - /** Gets a use of this variable. */ - Expr getAUse() { result = super.getARead() } - } - - class SsaSourceVariable = Ssa::SourceVariable; - - class Type = J::Type; - - class Expr = J::Expr; - - class IntegralType = J::IntegralType; - - class ConstantIntegerExpr = RU::ConstantIntegerExpr; - - /** Holds if `e` is a bound expression and it is not an SSA variable read. */ - predicate interestingExprBound(Expr e) { - e.(J::FieldRead).getField() instanceof J::ArrayLengthField - } -} diff --git a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll index 353cb94064b..5bb1723fd0a 100644 --- a/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll +++ b/shared/rangeanalysis/codeql/rangeanalysis/Bound.qll @@ -40,7 +40,7 @@ signature module BoundDefinitions { /** * Provides classes for representing abstract bounds for use in, for example, range analysis. - * This is a generic implementation of bounds that relies on language specific modules to provide language-specific definitions of expressions, SSA variables, etc. + * This is a generic implementation of bounds that relies on language specific modules to provide language-specific definitions of expressions, SSA variables, etc. */ overlay[local?] module Bound Defs> { From f34275636ccc592699d18db2e8c401b6aaa791af Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Wed, 3 Jun 2026 11:54:24 +0200 Subject: [PATCH 205/226] No duplicate Ssa and remove release changenot --- csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll | 4 ++-- java/ql/lib/semmle/code/java/dataflow/Bound.qll | 2 +- shared/rangeanalysis/change-notes/released/1.0.52.md | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) delete mode 100644 shared/rangeanalysis/change-notes/released/1.0.52.md diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll index 85bfcd54bdc..c3dcc6525a4 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll @@ -5,7 +5,7 @@ overlay[local?] module; private import csharp as CS -private import semmle.code.csharp.dataflow.SSA::Ssa as Ssa +private import semmle.code.csharp.dataflow.SSA::Ssa private import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils as CU private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU @@ -17,7 +17,7 @@ private module BoundDefs implements SharedBound::BoundDefinitions class SsaVariable = SU::SsaVariable; - class SsaSourceVariable = Ssa::SourceVariable; + class SsaSourceVariable = SourceVariable; class Expr = CS::ControlFlowNodes::ExprNode; diff --git a/java/ql/lib/semmle/code/java/dataflow/Bound.qll b/java/ql/lib/semmle/code/java/dataflow/Bound.qll index 37ce764c8e3..df816ba6461 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Bound.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Bound.qll @@ -5,7 +5,7 @@ overlay[local?] module; private import java as J -private import semmle.code.java.dataflow.SSA as Ssa +private import semmle.code.java.dataflow.SSA private import semmle.code.java.dataflow.RangeUtils as RU private import codeql.rangeanalysis.Bound as SharedBound diff --git a/shared/rangeanalysis/change-notes/released/1.0.52.md b/shared/rangeanalysis/change-notes/released/1.0.52.md deleted file mode 100644 index a91f5a8025d..00000000000 --- a/shared/rangeanalysis/change-notes/released/1.0.52.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.52 - -No user-facing changes. From da999ee440f951e82b0c776c0c8c025f2ed8fc1d Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 3 Jun 2026 21:24:16 +0100 Subject: [PATCH 206/226] Address review comments --- .../python/dataflow/new/internal/TaintTrackingPrivate.qll | 4 +++- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 02c43f874bf..2213ff35b1b 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -188,7 +188,9 @@ predicate containerStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { exists(DataFlow::Content c | c = contentSet.getAReadContent() | c instanceof DataFlow::TupleElementContent or c instanceof DataFlow::DictionaryElementContent or - c instanceof DataFlow::DictionaryElementAnyContent + c instanceof DataFlow::DictionaryElementAnyContent or + c instanceof DataFlow::ListElementContent or + c instanceof DataFlow::SetElementContent ) ) } diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 014ef4e9f64..9364203436d 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4983,10 +4983,6 @@ module StdlibPrivate { // For code like `" ".join([name])` input = "Argument[0,iterable:].ListElement" and preservesValue = true - or - // For code like `" ".join(name)` - input = "Argument[0,iterable:]" and - preservesValue = false ) and output = "ReturnValue" } From 5576d307808a1be0f9b0651df432d4e81cb3787c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2026 01:04:50 +0000 Subject: [PATCH 207/226] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 2 +- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index bf78940aabc..389a84f1d16 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -194,7 +194,7 @@ org.apache.hc.core5.http,73,2,45,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,72,,,,,,,,,,, org.apache.hc.core5.net,,,18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18, org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 org.apache.hive.hcatalog.templeton,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,, -org.apache.http,48,3,95,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,46,,,,,,,,,,,,,,,,3,86,9 +org.apache.http,53,3,117,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,51,,,,,,,,,,,,,,,,3,108,9 org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,57, org.apache.ibatis.mapping,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, org.apache.log4j,11,,,,,,,,,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 6b02a86a3c9..14a5286295f 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -13,7 +13,7 @@ Java framework & library support `Apache Commons IO `_,``org.apache.commons.io``,,570,124,105,,,,,15 `Apache Commons Lang `_,``org.apache.commons.lang3``,,425,7,,,,,, `Apache Commons Text `_,``org.apache.commons.text``,,272,,,,,,, - `Apache HttpComponents `_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,183,122,,3,,,,119 + `Apache HttpComponents `_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,205,127,,3,,,,124 `Apache Log4j 2 `_,``org.apache.logging.log4j``,,8,359,,,,,, `Apache Struts `_,"``org.apache.struts2``, ``org.apache.struts.beanvalidation.validation.interceptor``",,3877,14,,,,,, `Apache Velocity `_,"``org.apache.velocity.app``, ``org.apache.velocity.runtime``",,,8,,,,,, @@ -41,5 +41,5 @@ Java framework & library support `Thymeleaf `_,``org.thymeleaf``,,2,2,,,,,, `jOOQ `_,``org.jooq``,,,1,,,1,,, Others,"``actions.osgi``, ``antlr``, ``ch.ethz.ssh2``, ``cn.hutool.core.codec``, ``com.alibaba.com.caucho.hessian.io``, ``com.alibaba.druid.sql``, ``com.alibaba.fastjson2``, ``com.amazonaws.auth``, ``com.auth0.jwt.algorithms``, ``com.azure.identity``, ``com.caucho.burlap.io``, ``com.caucho.hessian.io``, ``com.cedarsoftware.util.io``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.esotericsoftware.yamlbeans``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.microsoft.sqlserver.jdbc``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2``, ``com.sshtools.j2ssh.authentication``, ``com.sun.crypto.provider``, ``com.sun.jndi.ldap``, ``com.sun.net.httpserver``, ``com.sun.net.ssl``, ``com.sun.rowset``, ``com.sun.security.auth.module``, ``com.sun.security.ntlm``, ``com.sun.security.sasl.digest``, ``com.thoughtworks.xstream``, ``com.trilead.ssh2``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``hudson``, ``io.jsonwebtoken``, ``io.undertow.server.handlers.resource``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``liquibase.database.jvm``, ``liquibase.statement.core``, ``net.lingala.zip4j``, ``net.schmizz.sshj``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.avro``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.exec``, ``org.apache.commons.fileupload``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.lang``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.cxf.catalog``, ``org.apache.cxf.common.classloader``, ``org.apache.cxf.common.jaxb``, ``org.apache.cxf.common.logging``, ``org.apache.cxf.configuration.jsse``, ``org.apache.cxf.helpers``, ``org.apache.cxf.resource``, ``org.apache.cxf.staxutils``, ``org.apache.cxf.tools.corba.utils``, ``org.apache.cxf.tools.util``, ``org.apache.cxf.transform``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hadoop.hive.ql.exec``, ``org.apache.hadoop.hive.ql.metadata``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.ibatis.mapping``, ``org.apache.log4j``, ``org.apache.shiro.authc``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.shiro.mgt``, ``org.apache.sshd.client.session``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.codehaus.cargo.container.installer``, ``org.dom4j``, ``org.exolab.castor.xml``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.gradle.api.file``, ``org.ho.yaml``, ``org.influxdb``, ``org.jabsorb``, ``org.jboss.vfs``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.keycloak.models.map.storage``, ``org.kohsuke.stapler``, ``org.lastaflute.web``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.owasp.esapi``, ``org.pac4j.jwt.config.encryption``, ``org.pac4j.jwt.config.signature``, ``org.scijava.log``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``software.amazon.awssdk.transfer.s3.model``, ``sun.jvmstat.perfdata.monitor.protocol.local``, ``sun.jvmstat.perfdata.monitor.protocol.rmi``, ``sun.misc``, ``sun.net.ftp``, ``sun.net.www.protocol.http``, ``sun.security.acl``, ``sun.security.jgss.krb5``, ``sun.security.krb5``, ``sun.security.pkcs``, ``sun.security.pkcs11``, ``sun.security.provider``, ``sun.security.ssl``, ``sun.security.x509``, ``sun.tools.jconsole``",127,6034,775,148,6,14,18,,186 - Totals,,382,26381,2702,421,16,137,33,1,410 + Totals,,382,26403,2707,421,16,137,33,1,415 From d2972cb53f90f34ab9458835bf64833a7a91d7ec Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Thu, 4 Jun 2026 11:08:49 +0200 Subject: [PATCH 208/226] Add back alias for module --- csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll | 4 +++- java/ql/lib/semmle/code/java/dataflow/Bound.qll | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll index c3dcc6525a4..4f03a735a69 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll @@ -29,4 +29,6 @@ private module BoundDefs implements SharedBound::BoundDefinitions predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.getExpr()) } } -import SharedBound::Bound +module BoundImpl = SharedBound::Bound; + +import BoundImpl diff --git a/java/ql/lib/semmle/code/java/dataflow/Bound.qll b/java/ql/lib/semmle/code/java/dataflow/Bound.qll index df816ba6461..4780b9cacca 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Bound.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Bound.qll @@ -31,4 +31,6 @@ private module BoundDefs implements SharedBound::BoundDefinitions { } } -import SharedBound::Bound +module BoundImpl = SharedBound::Bound; + +import BoundImpl From b32573b0603476b66d604f2ba6632d7d88f6b926 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 Jun 2026 14:57:38 +0000 Subject: [PATCH 209/226] update codeql documentation --- .../codeql-changelog/codeql-cli-2.25.6.rst | 139 ++++++++++++++++++ .../codeql-changelog/index.rst | 1 + 2 files changed, 140 insertions(+) create mode 100644 docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.6.rst diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.6.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.6.rst new file mode 100644 index 00000000000..7ab4ffb0db9 --- /dev/null +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.6.rst @@ -0,0 +1,139 @@ +.. _codeql-cli-2.25.6: + +========================== +CodeQL 2.25.6 (2026-06-04) +========================== + +.. contents:: Contents + :depth: 2 + :local: + :backlinks: none + +This is an overview of changes in the CodeQL CLI and relevant CodeQL query and library packs. For additional updates on changes to the CodeQL code scanning experience, check out the `code scanning section on the GitHub blog `__, `relevant GitHub Changelog updates `__, `changes in the CodeQL extension for Visual Studio Code `__, and the `CodeQL Action changelog `__. + +Security Coverage +----------------- + +CodeQL 2.25.6 runs a total of 496 security queries when configured with the Default suite (covering 169 CWE). The Extended suite enables an additional 131 queries (covering 32 more CWE). + +CodeQL CLI +---------- + +Improvements +~~~~~~~~~~~~ + +* When the :code:`git` executable is available, CodeQL can now obtain configuration and queries from SHA-256 Git repositories, and infer Git metadata about them. + +Miscellaneous +~~~~~~~~~~~~~ + +* The build of Eclipse Temurin OpenJDK that is used to run the CodeQL CLI has been updated to version 21.0.11. + +Query Packs +----------- + +Bug Fixes +~~~~~~~~~ + +GitHub Actions +"""""""""""""" + +* Adjusted (minor) help file descriptions for queries: :code:`actions/untrusted-checkout/critical`, :code:`actions/untrusted-checkout/high`, :code:`actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. + +Major Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +GitHub Actions +"""""""""""""" + +* Adjusted :code:`actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query. + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +GitHub Actions +"""""""""""""" + +* Altered the alert message for clarity for queries: :code:`actions/untrusted-checkout/critical`, :code:`actions/untrusted-checkout/high`. +* The :code:`actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes. + +Query Metadata Changes +~~~~~~~~~~~~~~~~~~~~~~ + +GitHub Actions +"""""""""""""" + +* Reversed adjustment of the name of :code:`actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in :code:`actions/untrusted-checkout/high` and :code:`actions/untrusted-checkout/medium`. + +Language Libraries +------------------ + +Major Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Swift +""""" + +* Upgraded to allow analysis of Swift 6.3.2. + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* Added flow source models for :code:`scanf_s` and related functions. +* Added a :code:`Call` column to :code:`LocalFlowSourceFunction::hasLocalFlowSource` and :code:`RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a :code:`Call` column continue to be supported. + +C# +"" + +* Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime. +* C# 14: Added support for user-defined instance increment/decrement operators. + +Java/Kotlin +""""""""""" + +* Added LLM-generated source and sink models for :code:`org.apache.avro`. + +JavaScript/TypeScript +""""""""""""""""""""" + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example :code:`js/clear-text-logging`) may find more correct results and fewer false positive results after these changes. + +Python +"""""" + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example :code:`py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes. + +Swift +""""" + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example :code:`swift/cleartext-logging`) may find more correct results and fewer false positive results after these changes. + +GitHub Actions +"""""""""""""" + +* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like :code:`^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. + +Rust +"""" + +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example :code:`rust/cleartext-logging`) may find more correct results and fewer false positive results after these changes. + +Deprecated APIs +~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* The :code:`UsingAliasTypedefType` class has been deprecated. Use :code:`TypeAliasType` instead. + +New Features +~~~~~~~~~~~~ + +C/C++ +""""" + +* Added a :code:`getOriginalTemplate` predicate to :code:`TemplateClass`, :code:`TemplateFunction`, :code:`TemplateVariable`, and :code:`AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations. +* Added :code:`AliasTemplateType` and :code:`AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations. diff --git a/docs/codeql/codeql-overview/codeql-changelog/index.rst b/docs/codeql/codeql-overview/codeql-changelog/index.rst index 3ed98bad8d1..ac4a8041faa 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/index.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/index.rst @@ -11,6 +11,7 @@ A list of queries for each suite and language `is available here Date: Thu, 4 Jun 2026 19:36:45 +0000 Subject: [PATCH 210/226] update codeql documentation --- .../codeql-overview/codeql-changelog/codeql-cli-2.25.6.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.6.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.6.rst index 7ab4ffb0db9..21d67e16229 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.6.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.6.rst @@ -38,7 +38,7 @@ Bug Fixes GitHub Actions """""""""""""" -* Adjusted (minor) help file descriptions for queries: :code:`actions/untrusted-checkout/critical`, :code:`actions/untrusted-checkout/high`, :code:`actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check. +* Adjusted (minor) help file descriptions for queries: :code:`actions/untrusted-checkout/critical`, :code:`actions/untrusted-checkout/high`, :code:`actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check. Major Analysis Improvements ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -104,7 +104,7 @@ JavaScript/TypeScript Python """""" -* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example :code:`py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes. +* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example :code:`py/clear-text-logging-sensitive-data`) may find more correct results and fewer false positive results after these changes. Swift """"" @@ -114,7 +114,7 @@ Swift GitHub Actions """""""""""""" -* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like :code:`^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. +* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like :code:`^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used. Rust """" From ef29d22c75ed9f70a7e07cb68eb655e21dc39bd9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 6 Jun 2026 01:03:44 +0000 Subject: [PATCH 211/226] Update Go version workflow to include patch numbers in messages --- .github/workflows/go-version-update.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/go-version-update.yml b/.github/workflows/go-version-update.yml index 3cd8f72690f..1007e9f1ba3 100644 --- a/.github/workflows/go-version-update.yml +++ b/.github/workflows/go-version-update.yml @@ -163,7 +163,7 @@ jobs: # Stage and commit changes git add MODULE.bazel go/extractor/go.mod go/extractor/autobuilder/build-environment.go go/actions/test/action.yml - git commit -m "Go: Update to $LATEST_MAJOR_MINOR" + git commit -m "Go: Update to $LATEST_VERSION_NUM" # Push changes git push -f origin "$BRANCH_NAME" @@ -174,13 +174,13 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | BRANCH_NAME="workflow/go-version-update" - LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}" - CURRENT_MAJOR_MINOR="${{ steps.current-version.outputs.major_minor }}" + LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}" + CURRENT_VERSION="${{ steps.current-version.outputs.version }}" - PR_TITLE="Go: Update to $LATEST_MAJOR_MINOR" + PR_TITLE="Go: Update to $LATEST_VERSION_NUM" PR_BODY=$(cat < Date: Sat, 6 Jun 2026 02:31:16 +0100 Subject: [PATCH 212/226] Minor improvement to PR text --- .github/workflows/go-version-update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go-version-update.yml b/.github/workflows/go-version-update.yml index 1007e9f1ba3..2adf2b90549 100644 --- a/.github/workflows/go-version-update.yml +++ b/.github/workflows/go-version-update.yml @@ -185,7 +185,7 @@ jobs: Updated files: - \`MODULE.bazel\` - go_sdk.download version - \`go/extractor/go.mod\` - go directive and toolchain - - \`go/extractor/autobuilder/build-environment.go\` - maxGoVersion + - \`go/extractor/autobuilder/build-environment.go\` - maxGoVersion (only if MAJOR.MINOR changes) - \`go/actions/test/action.yml\` - default go-test-version This PR was automatically created by the [Go version update workflow](https://github.com/${{ github.repository }}/blob/main/.github/workflows/go-version-update.yml). From a1759d983472421b5ac966d6b909c0efdcfb36b3 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Sat, 6 Jun 2026 02:51:36 +0100 Subject: [PATCH 213/226] Use --force-with-lease for slightly improved safety Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .github/workflows/go-version-update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go-version-update.yml b/.github/workflows/go-version-update.yml index 2adf2b90549..b7581bdf09e 100644 --- a/.github/workflows/go-version-update.yml +++ b/.github/workflows/go-version-update.yml @@ -166,7 +166,7 @@ jobs: git commit -m "Go: Update to $LATEST_VERSION_NUM" # Push changes - git push -f origin "$BRANCH_NAME" + git push --force-with-lease origin "$BRANCH_NAME" - name: Create or update PR if: steps.check-changes.outputs.has_changes == 'true' From 292fc8b7778eac54fb969519ec649add6662a14b Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Sat, 6 Jun 2026 02:52:21 +0100 Subject: [PATCH 214/226] Fix detection of failed text replacement I checked and the comment seems to be correct. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .github/workflows/go-version-update.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go-version-update.yml b/.github/workflows/go-version-update.yml index b7581bdf09e..6c22f344510 100644 --- a/.github/workflows/go-version-update.yml +++ b/.github/workflows/go-version-update.yml @@ -96,8 +96,10 @@ jobs: CURRENT_MAJOR_MINOR_ESCAPED=$(echo "$CURRENT_MAJOR_MINOR" | sed 's/\./\\./g') # Update MODULE.bazel - if ! sed -i "s/go_sdk\.download(version = \"$CURRENT_VERSION_ESCAPED\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel; then - echo "Warning: Failed to update MODULE.bazel" + sed -i "s/go_sdk\.download(version = \"$CURRENT_VERSION_ESCAPED\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel + if ! grep -q "go_sdk.download(version = \"$LATEST_VERSION_NUM\")" MODULE.bazel; then + echo "Error: Failed to update MODULE.bazel" + exit 1 fi # Update go/extractor/go.mod From e93bc11f6f9e0f2887b6189db4b2f331927d92eb Mon Sep 17 00:00:00 2001 From: tonghuaroot <23011166+tonghuaroot@users.noreply.github.com> Date: Sat, 6 Jun 2026 21:47:24 +0800 Subject: [PATCH 215/226] Add experimental JS query for SSRF guards missing IPv6-transition unwrap Add javascript/ssrf-ipv6-transition-incomplete-guard, an experimental @kind problem query that flags hand-rolled SSRF host guards which reject private/loopback IPv4 ranges but never unwrap IPv6-transition forms (IPv4-mapped ::ffff:, NAT64 64:ff9b::, 6to4 2002::). Such guards can be bypassed by wrapping an internal IPv4 address in a transition literal. Includes a .qhelp with good/bad examples, a change note, and a test pack with two true-positive fixtures (private-ip package guard and a hand-written RFC 1918 denylist) and two negative-control fixtures (ipaddr.js range classifier and an explicit ::ffff: unwrap). Signed-off-by: tonghuaroot <23011166+tonghuaroot@users.noreply.github.com> --- ...6-ssrf-ipv6-transition-incomplete-guard.md | 4 + .../SsrfIpv6TransitionIncompleteGuard.qhelp | 59 ++++++++ .../SsrfIpv6TransitionIncompleteGuard.ql | 129 ++++++++++++++++++ .../SsrfIpv6TransitionIncompleteGuardBad.js | 14 ++ .../SsrfIpv6TransitionIncompleteGuardGood.js | 16 +++ ...SsrfIpv6TransitionIncompleteGuard.expected | 2 + .../SsrfIpv6TransitionIncompleteGuard.qlref | 1 + .../bad-private-ip-pkg.js | 13 ++ .../bad-rfc1918-regex.js | 18 +++ .../good-explicit-unwrap.js | 32 +++++ .../good-ipaddr.js | 16 +++ 11 files changed, 304 insertions(+) create mode 100644 javascript/ql/src/change-notes/2026-06-06-ssrf-ipv6-transition-incomplete-guard.md create mode 100644 javascript/ql/src/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.qhelp create mode 100644 javascript/ql/src/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql create mode 100644 javascript/ql/src/experimental/Security/CWE-918/examples/SsrfIpv6TransitionIncompleteGuardBad.js create mode 100644 javascript/ql/src/experimental/Security/CWE-918/examples/SsrfIpv6TransitionIncompleteGuardGood.js create mode 100644 javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/SsrfIpv6TransitionIncompleteGuard.expected create mode 100644 javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/SsrfIpv6TransitionIncompleteGuard.qlref create mode 100644 javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/bad-private-ip-pkg.js create mode 100644 javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/bad-rfc1918-regex.js create mode 100644 javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/good-explicit-unwrap.js create mode 100644 javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/good-ipaddr.js diff --git a/javascript/ql/src/change-notes/2026-06-06-ssrf-ipv6-transition-incomplete-guard.md b/javascript/ql/src/change-notes/2026-06-06-ssrf-ipv6-transition-incomplete-guard.md new file mode 100644 index 00000000000..35bd19acf46 --- /dev/null +++ b/javascript/ql/src/change-notes/2026-06-06-ssrf-ipv6-transition-incomplete-guard.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new experimental query, `javascript/ssrf-ipv6-transition-incomplete-guard`, to detect SSRF host-validation guards that reject private IPv4 ranges but fail to unwrap IPv6-transition forms (IPv4-mapped `::ffff:`, NAT64 `64:ff9b::`, 6to4 `2002::`), allowing the guard to be bypassed by wrapping an internal IPv4 address in a transition literal. diff --git a/javascript/ql/src/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.qhelp b/javascript/ql/src/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.qhelp new file mode 100644 index 00000000000..79230285f51 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.qhelp @@ -0,0 +1,59 @@ + + + + +

+ Server-side request forgery (SSRF) guards frequently reject requests to internal + addresses by checking the request host against a denylist of private, loopback and + cloud-metadata IPv4 ranges. When such a guard inspects only the dotted-quad IPv4 form + and never unwraps IPv6-transition representations, it can be bypassed: the host + validator classifies the address as public, but the operating system routes the + connection to the embedded internal IPv4 endpoint. +

+

+ The affected forms include IPv4-mapped IPv6 (::ffff:169.254.169.254), + NAT64 (64:ff9b::a9fe:a9fe) and 6to4 (2002::). A URL such as + http://[::ffff:169.254.169.254]/ passes a dotted-quad denylist unchanged + while still reaching the internal address. +

+
+ + +

+ Normalize the host before validating it: parse the address with a transition-aware + library and unwrap IPv4-mapped, NAT64 and 6to4 forms to their embedded IPv4 address, + then apply the private-range check to the normalized value. Libraries such as + ipaddr.js classify these forms correctly via their range API, and + SSRF-protection libraries such as request-filtering-agent apply the check + after DNS resolution. Validate the resolved address rather than the textual host. +

+
+ + +

+ The following guard rejects private IPv4 ranges using the private-ip + package, which inspects the textual IPv4 form only. An attacker supplies + ::ffff:169.254.169.254, which the guard classifies as public, but the + request still reaches the internal metadata endpoint. +

+ + + +

+ The following guard parses the host with a transition-aware classifier, so the + embedded internal IPv4 address is detected regardless of the transition form used. +

+ + +
+ + + +
  • OWASP: Server-Side Request Forgery.
  • +
  • Common Weakness Enumeration: CWE-918.
  • +
  • Common Weakness Enumeration: CWE-1389.
  • + +
    +
    diff --git a/javascript/ql/src/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql b/javascript/ql/src/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql new file mode 100644 index 00000000000..14e0766d796 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql @@ -0,0 +1,129 @@ +/** + * @name SSRF host guard does not reject IPv6-transition forms + * @description An SSRF host guard that rejects private or loopback IPv4 ranges but never + * unwraps IPv6-transition forms (IPv4-mapped `::ffff:`, NAT64 `64:ff9b::`, + * 6to4 `2002::`) can be bypassed by wrapping an internal IPv4 address in a + * transition literal, allowing requests to reach internal endpoints. + * @kind problem + * @problem.severity warning + * @id javascript/ssrf-ipv6-transition-incomplete-guard + * @tags security + * experimental + * external/cwe/cwe-918 + * external/cwe/cwe-1389 + */ + +import javascript + +/** + * Holds if `f` imports a dotted-quad-oriented private-IP guard package whose + * classification is performed on the textual IPv4 form and therefore returns + * `false` for an internal address wrapped in an IPv6-transition literal. + */ +predicate importsHandRolledIpGuard(File f) { + exists(DataFlow::SourceNode mod | + mod.getFile() = f and + mod = DataFlow::moduleImport(["private-ip", "is-ip", "ip", "ip-range-check"]) + ) +} + +/** + * Holds if `f` contains a call to an `isPrivate`-style host classifier, the + * common name for a hand-rolled SSRF guard. + */ +predicate hasIsPrivateCall(File f) { + exists(DataFlow::CallNode c | + c.getFile() = f and + c.getCalleeName().regexpMatch("(?i)^is_?private(ip|address|host)?$") + ) + or + exists(DataFlow::MethodCallNode m | + m.getFile() = f and + m.getMethodName().regexpMatch("(?i)^is_?private(ip|address|host)?$") + ) +} + +/** + * Holds if `f` contains a hand-written RFC 1918, loopback or cloud-metadata IPv4 + * literal used as a denylist entry. + */ +predicate hasRfc1918Literal(File f) { + exists(StringLiteral s | + s.getFile() = f and + s.getValue() + .regexpMatch("(?i).*(127\\.0\\.0\\.1|169\\.254\\.169\\.254|10\\.|192\\.168|172\\.1[6-9]|::1|fc00|fd00|metadata\\.google).*") + ) +} + +/** Holds if `f` carries any hand-rolled, dotted-quad-oriented SSRF guard signal. */ +predicate hasUnsafeGuardSignal(File f) { + importsHandRolledIpGuard(f) or + hasIsPrivateCall(f) or + hasRfc1918Literal(f) +} + +/** Holds if `func` has a name that reads as an SSRF host or URL validator. */ +predicate isSsrfValidatorFunction(Function func) { + func.getName() + .regexpMatch("(?i).*(validate|check|guard|reject|deny|block|allow|is_?safe|sanitiz)e?_?.*(url|host|ip|address|target|endpoint|webhook|origin).*") + or + func.getName() + .regexpMatch("(?i).*(is_?)?(private|internal|loopback|reserved|external)_?(ip|address|host|url).*") + or + func.getName().regexpMatch("(?i).*(ssrf|metadata).*") +} + +/** + * Holds if `f` imports a maturity-hardened, transition-aware address classifier + * or SSRF-protection library that does unwrap IPv6-transition forms. + */ +predicate importsSafeClassifier(File f) { + exists(DataFlow::SourceNode mod | + mod.getFile() = f and + mod = + DataFlow::moduleImport([ + "ipaddr.js", "ssrf-req-filter", "request-filtering-agent", "ssrf-agent", "netmask", + "ip-cidr", "cidr-matcher", "blocked-at" + ]) + ) +} + +/** + * Holds if `f` already performs an explicit IPv6-transition unwrap or + * canonicalization, so the guard does see the embedded IPv4 address. + */ +predicate hasTransitionUnwrap(File f) { + exists(StringLiteral s | + s.getFile() = f and + ( + s.getValue().matches("%64:ff9b%") or + s.getValue().matches("%::ffff%") or + s.getValue().matches("%2002:%") or + s.getValue().matches("%2001:%") + ) + ) + or + exists(Identifier id | + id.getFile() = f and + id.getName() + .regexpMatch("(?i).*(ipv4mapped|v4mapped|mappedipv4|ipv4inipv6|embeddedipv4|unwrap.*ip|toipv4|canonicaliz|isipv4compat).*") + ) + or + exists(DataFlow::MethodCallNode m | m.getFile() = f and m.getMethodName() = ["range", "kind"]) +} + +/** Holds if `f` is treated as safe (transition-aware), suppressing the alert. */ +predicate isSafe(File f) { importsSafeClassifier(f) or hasTransitionUnwrap(f) } + +from Function guard, File f +where + guard.getFile() = f and + isSsrfValidatorFunction(guard) and + hasUnsafeGuardSignal(f) and + not isSafe(f) and + not f.getRelativePath() + .regexpMatch("(?i).*/(tests?|specs?|examples?|__tests__|e2e|node_modules)/.*") +select guard, + "This SSRF host guard rejects private IPv4 ranges but never unwraps IPv6-transition forms " + + "(IPv4-mapped '::ffff:', NAT64 '64:ff9b::', 6to4 '2002::'); an attacker can wrap an internal " + + "IPv4 address in a transition literal to bypass it and reach internal endpoints." diff --git a/javascript/ql/src/experimental/Security/CWE-918/examples/SsrfIpv6TransitionIncompleteGuardBad.js b/javascript/ql/src/experimental/Security/CWE-918/examples/SsrfIpv6TransitionIncompleteGuardBad.js new file mode 100644 index 00000000000..0f0eabe1ce1 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-918/examples/SsrfIpv6TransitionIncompleteGuardBad.js @@ -0,0 +1,14 @@ +const isPrivate = require('private-ip'); +const fetch = require('node-fetch'); + +// BAD: `private-ip` classifies the textual IPv4 form only, so it returns false +// for `::ffff:169.254.169.254`. The guard treats the wrapped internal address as +// public, but the request still reaches the metadata endpoint. +async function validateUrlHost(host) { + if (isPrivate(host)) { + throw new Error('blocked private host'); + } + return fetch('http://' + host + '/'); +} + +module.exports = { validateUrlHost }; diff --git a/javascript/ql/src/experimental/Security/CWE-918/examples/SsrfIpv6TransitionIncompleteGuardGood.js b/javascript/ql/src/experimental/Security/CWE-918/examples/SsrfIpv6TransitionIncompleteGuardGood.js new file mode 100644 index 00000000000..0d4a9820fd6 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-918/examples/SsrfIpv6TransitionIncompleteGuardGood.js @@ -0,0 +1,16 @@ +const ipaddr = require('ipaddr.js'); +const fetch = require('node-fetch'); + +// GOOD: ipaddr.js parses the host and classifies it with `.range()`, which is +// transition-aware. `::ffff:169.254.169.254` parses as an IPv4-mapped address and +// is reported in the `linkLocal` range, so the guard is complete. +async function validateTargetHost(host) { + const addr = ipaddr.parse(host); + const range = addr.range(); + if (range === 'private' || range === 'loopback' || range === 'linkLocal') { + throw new Error('blocked internal host'); + } + return fetch('http://' + host + '/'); +} + +module.exports = { validateTargetHost }; diff --git a/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/SsrfIpv6TransitionIncompleteGuard.expected b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/SsrfIpv6TransitionIncompleteGuard.expected new file mode 100644 index 00000000000..e488048f9af --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/SsrfIpv6TransitionIncompleteGuard.expected @@ -0,0 +1,2 @@ +| bad-private-ip-pkg.js:6:1:11:1 | async f ... '/');\\n} | This SSRF host guard rejects private IPv4 ranges but never unwraps IPv6-transition forms (IPv4-mapped '::ffff:', NAT64 '64:ff9b::', 6to4 '2002::'); an attacker can wrap an internal IPv4 address in a transition literal to bypass it and reach internal endpoints. | +| bad-rfc1918-regex.js:5:1:16:1 | functio ... '/');\\n} | This SSRF host guard rejects private IPv4 ranges but never unwraps IPv6-transition forms (IPv4-mapped '::ffff:', NAT64 '64:ff9b::', 6to4 '2002::'); an attacker can wrap an internal IPv4 address in a transition literal to bypass it and reach internal endpoints. | diff --git a/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/SsrfIpv6TransitionIncompleteGuard.qlref b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/SsrfIpv6TransitionIncompleteGuard.qlref new file mode 100644 index 00000000000..50159ab72fe --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/SsrfIpv6TransitionIncompleteGuard.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql \ No newline at end of file diff --git a/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/bad-private-ip-pkg.js b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/bad-private-ip-pkg.js new file mode 100644 index 00000000000..972d7aad9b7 --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/bad-private-ip-pkg.js @@ -0,0 +1,13 @@ +const isPrivate = require('private-ip'); +const fetch = require('node-fetch'); + +// BAD: `private-ip` classifies the textual IPv4 form only. It returns false for +// `::ffff:169.254.169.254`, so a transition-wrapped internal address slips past. +async function validateUrlHost(host) { // NOT OK + if (isPrivate(host)) { + throw new Error('blocked private host'); + } + return fetch('http://' + host + '/'); +} + +module.exports = { validateUrlHost }; diff --git a/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/bad-rfc1918-regex.js b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/bad-rfc1918-regex.js new file mode 100644 index 00000000000..be70a4a5e5d --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/bad-rfc1918-regex.js @@ -0,0 +1,18 @@ +const http = require('http'); + +// BAD: a hand-written RFC 1918 / loopback / metadata denylist matched against the +// host string. The embedded IPv4 inside `::ffff:10.0.0.1` is never seen. +function checkTargetHost(host) { // NOT OK + if ( + host === '127.0.0.1' || + host === '169.254.169.254' || + host.startsWith('10.') || + host.startsWith('192.168') || + host.startsWith('172.16') + ) { + throw new Error('blocked internal host'); + } + return http.get('http://' + host + '/'); +} + +module.exports = { checkTargetHost }; diff --git a/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/good-explicit-unwrap.js b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/good-explicit-unwrap.js new file mode 100644 index 00000000000..d7bc0707914 --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/good-explicit-unwrap.js @@ -0,0 +1,32 @@ +const http = require('http'); + +const IPV4_MAPPED_PREFIX = '::ffff:'; + +// OK: this guard uses a hand-rolled denylist, but it first unwraps the +// IPv6-transition form, so the embedded IPv4 is normalized before the check. +function unwrapMapped(host) { + // strip an IPv4-mapped `::ffff:` prefix down to the embedded dotted quad + if (host.toLowerCase().startsWith(IPV4_MAPPED_PREFIX)) { + return host.slice(IPV4_MAPPED_PREFIX.length); + } + return host; +} + +function isPrivateAddress(host) { // OK + const h = unwrapMapped(host); + return ( + h === '127.0.0.1' || + h === '169.254.169.254' || + h.startsWith('10.') || + h.startsWith('192.168') + ); +} + +function validateHost(host) { // OK + if (isPrivateAddress(host)) { + throw new Error('blocked internal host'); + } + return http.get('http://' + host + '/'); +} + +module.exports = { validateHost }; diff --git a/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/good-ipaddr.js b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/good-ipaddr.js new file mode 100644 index 00000000000..9994eba44c3 --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard/good-ipaddr.js @@ -0,0 +1,16 @@ +const ipaddr = require('ipaddr.js'); +const fetch = require('node-fetch'); + +// OK: ipaddr.js parses the address and classifies it with `.range()`, which is +// transition-aware. `::ffff:10.0.0.1` parses as an IPv4-mapped address and is +// reported in the `private` range, so the guard is complete. +async function validateTargetHost(host) { // OK + const addr = ipaddr.parse(host); + const range = addr.range(); + if (range === 'private' || range === 'loopback' || range === 'linkLocal') { + throw new Error('blocked internal host'); + } + return fetch('http://' + host + '/'); +} + +module.exports = { validateTargetHost }; From 5a38cbd5d50fe35e88653051d0f34b5f6f05b64d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 04:30:10 +0000 Subject: [PATCH 216/226] Go: Update to 1.26.4 --- MODULE.bazel | 2 +- go/actions/test/action.yml | 2 +- go/extractor/go.mod | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index fd923a32e62..8bdc850e327 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -273,7 +273,7 @@ use_repo( ) go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") -go_sdk.download(version = "1.26.0") +go_sdk.download(version = "1.26.4") go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") go_deps.from_file(go_mod = "//go/extractor:go.mod") diff --git a/go/actions/test/action.yml b/go/actions/test/action.yml index bec48ef4bff..3cc3334d39e 100644 --- a/go/actions/test/action.yml +++ b/go/actions/test/action.yml @@ -4,7 +4,7 @@ inputs: go-test-version: description: Which Go version to use for running the tests required: false - default: "~1.26.0" + default: "~1.26.4" run-code-checks: description: Whether to run formatting, code and qhelp generation checks required: false diff --git a/go/extractor/go.mod b/go/extractor/go.mod index 25c8e3d0e5d..1db6ad2f5de 100644 --- a/go/extractor/go.mod +++ b/go/extractor/go.mod @@ -2,7 +2,7 @@ module github.com/github/codeql-go/extractor go 1.26 -toolchain go1.26.0 +toolchain go1.26.4 // when updating this, run // bazel run @rules_go//go -- mod tidy From cc1ea258560702f6b0fa32e320c5628afc36b550 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 4 Jun 2026 15:13:25 +0200 Subject: [PATCH 217/226] Python: Implement `ContentApprox` --- .../dataflow/new/internal/DataFlowPrivate.qll | 59 ++++++++++++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 1ea5765dc37..897248d0a5d 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -1249,12 +1249,65 @@ predicate allowParameterReturnInSelf(ParameterNode p) { ) } +bindingset[s] +private string getFirstChar(string s) { + result = + min(int i, string c | + c = s.charAt(i) and c != "_" + or + c = "" and i = s.length() + | + c order by i + ) +} + +private string getAttributeContentFirstChar(AttributeContent ac) { + result = getFirstChar(ac.getAttribute()) +} + +private string getDictionaryElementContentKeyFirstChar(DictionaryElementContent dec) { + result = getFirstChar(dec.getKey()) +} + +private newtype TContentApprox = + TListElementContentApprox() or + TSetElementContentApprox() or + TTupleElementContentApprox() or + TDictionaryElementContentApprox(string first) { + first = "" // for `TDictionaryElementAnyContent` + or + first = getDictionaryElementContentKeyFirstChar(_) + } or + TAttributeContentApprox(string first) { first = getAttributeContentFirstChar(_) } or + TCapturedVariableContentApprox() + /** An approximated `Content`. */ -class ContentApprox = Unit; +class ContentApprox extends TContentApprox { + /** Gets a textual representation of this element. */ + string toString() { result = "" } +} /** Gets an approximated value for content `c`. */ -pragma[inline] -ContentApprox getContentApprox(Content c) { any() } +ContentApprox getContentApprox(Content c) { + c = TListElementContent() and + result = TListElementContentApprox() + or + c = TSetElementContent() and + result = TSetElementContentApprox() + or + c = TTupleElementContent(_) and + result = TTupleElementContentApprox() + or + result = TDictionaryElementContentApprox(getDictionaryElementContentKeyFirstChar(c)) + or + c = TDictionaryElementAnyContent() and + result = TDictionaryElementContentApprox("") + or + result = TAttributeContentApprox(getAttributeContentFirstChar(c)) + or + c = TCapturedVariableContent(_) and + result = TCapturedVariableContentApprox() +} /** Helper for `.getEnclosingCallable`. */ DataFlowCallable getCallableScope(Scope s) { From c47135a40b2c0a2e6d9c11f826655de27e8f61d3 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 8 Jun 2026 13:40:33 +0200 Subject: [PATCH 218/226] Cfg: Add consistency check for relevant child indices. --- .../codeql/controlflow/ControlFlowGraph.qll | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index fff877b9fcd..e917d772886 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -2090,6 +2090,12 @@ module Make0 Ast> { module Consistency { /** Holds if the consistency query `query` has `results` results. */ query predicate consistencyOverview(string query, int results) { + query = "siblingsWithSameIndexInDefaultCfg" and + results = + strictcount(AstNode parent, AstNode child1, AstNode child2, int i | + siblingsWithSameIndexInDefaultCfg(parent, child1, child2, i) + ) + or query = "deadEnd" and results = strictcount(ControlFlowNode node | deadEnd(node)) or query = "nonUniqueEnclosingCallable" and @@ -2135,6 +2141,20 @@ module Make0 Ast> { results = strictcount(ControlFlowNode node, SuccessorType t | selfLoop(node, t)) } + /** + * Holds if `parent` uses default left-to-right control flow and has + * two different children `child1` and `child2` at the same index + * `i`. + */ + query predicate siblingsWithSameIndexInDefaultCfg( + AstNode parent, AstNode child1, AstNode child2, int i + ) { + defaultCfg(parent) and + getChild(parent, i) = child1 and + getChild(parent, i) = child2 and + child1 != child2 + } + /** * Holds if `node` is lacking a successor. * From 72fcf27d1a6a7a5634253258f1b316e648191084 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 03:03:37 +0000 Subject: [PATCH 219/226] Bump golang.org/x/mod Bumps the extractor-dependencies group in /go/extractor with 1 update: [golang.org/x/mod](https://github.com/golang/mod). Updates `golang.org/x/mod` from 0.36.0 to 0.37.0 - [Commits](https://github.com/golang/mod/compare/v0.36.0...v0.37.0) --- updated-dependencies: - dependency-name: golang.org/x/mod dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: extractor-dependencies ... Signed-off-by: dependabot[bot] --- go/extractor/go.mod | 2 +- go/extractor/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/extractor/go.mod b/go/extractor/go.mod index 1db6ad2f5de..04abf5cdbe5 100644 --- a/go/extractor/go.mod +++ b/go/extractor/go.mod @@ -9,7 +9,7 @@ toolchain go1.26.4 // when adding or removing dependencies, run // bazel mod tidy require ( - golang.org/x/mod v0.36.0 + golang.org/x/mod v0.37.0 golang.org/x/tools v0.45.0 ) diff --git a/go/extractor/go.sum b/go/extractor/go.sum index 660ae874a65..86c3e7b5f11 100644 --- a/go/extractor/go.sum +++ b/go/extractor/go.sum @@ -6,8 +6,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= -golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8= From 4c1a0058bf39a8413b8e4f10c1bc883511a6aa4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?tonghuaroot=20=28=E7=AB=A5=E8=AF=9D=29?= Date: Wed, 10 Jun 2026 08:42:42 +0800 Subject: [PATCH 220/226] Add SsrfIpv6TransitionIncompleteGuard.ql to not_included_in_qls.expected Fix the JS integration test failure flagged in review by listing the new experimental CWE-918 query in the expected not-included-in-qls suite, in sorted order. --- .../integration-tests/query-suite/not_included_in_qls.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/ql/integration-tests/query-suite/not_included_in_qls.expected b/javascript/ql/integration-tests/query-suite/not_included_in_qls.expected index 46317e8800f..4eb34a847e2 100644 --- a/javascript/ql/integration-tests/query-suite/not_included_in_qls.expected +++ b/javascript/ql/integration-tests/query-suite/not_included_in_qls.expected @@ -63,6 +63,7 @@ ql/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerificationL ql/javascript/ql/src/experimental/Security/CWE-444/InsecureHttpParser.ql ql/javascript/ql/src/experimental/Security/CWE-522-DecompressionBombs/DecompressionBombs.ql ql/javascript/ql/src/experimental/Security/CWE-918/SSRF.ql +ql/javascript/ql/src/experimental/Security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql ql/javascript/ql/src/experimental/StandardLibrary/MultipleArgumentsToSetConstructor.ql ql/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-020/UntrustedDataToExternalAPI.ql ql/javascript/ql/src/experimental/heuristics/ql/src/Security/CWE-078/CommandInjection.ql From 98f147556a4a811c53dddb3d1f9103bc0dc89908 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 10 Jun 2026 14:27:56 +0200 Subject: [PATCH 221/226] C++: Add namequalifier test with inconsistency While where the remove the file restriction in QL. --- .../library-tests/name_qualifiers/DB-CHECK.expected | 5 +++++ .../name_qualifiers/NameQualifiers1.expected | 4 ++++ .../library-tests/name_qualifiers/NameQualifiers1.ql | 4 +--- .../library-tests/name_qualifiers/inconsistency.cpp | 4 ++-- .../library-tests/name_qualifiers/inconsistency2.cpp | 12 ++++++++++++ 5 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 cpp/ql/test/library-tests/name_qualifiers/DB-CHECK.expected create mode 100644 cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp diff --git a/cpp/ql/test/library-tests/name_qualifiers/DB-CHECK.expected b/cpp/ql/test/library-tests/name_qualifiers/DB-CHECK.expected new file mode 100644 index 00000000000..e27957d308d --- /dev/null +++ b/cpp/ql/test/library-tests/name_qualifiers/DB-CHECK.expected @@ -0,0 +1,5 @@ +[VALUE_NOT_IN_TYPE] predicate namequalifiers(@namequalifier id, @namequalifiableelement qualifiableelement, @namequalifyingelement qualifyingelement, @location_default location): Value 272 of field qualifyingelement is not in type @namequalifyingelement. The value is however in the following types: @type_with_specifiers. Appears in tuple (-16777185,-16777184,272,307) + Relevant element: qualifyingelement=272 + Full ID for 272: @"typeref_const(216)". The ID may expand to @"typeref_const{@"type_decl_s_nonproto[struct_complete]_{@"namespace_decl_(namespace line:1, {@"/Users/jketema/development/semmle-code/ql/cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp;sourcefile"}){@"not_inline"}"}_321bfec50edc"}" + Relevant element: location=307 + Full ID for 307: @"loc,(212),3,3,3,11". The ID may expand to @"loc,{@"/Users/jketema/development/semmle-code/ql/cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp;sourcefile"},3,3,3,11" diff --git a/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.expected b/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.expected index 72d7d615c81..d9419b833a1 100644 --- a/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.expected +++ b/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.expected @@ -1,3 +1,7 @@ +| inconsistency2.cpp:3:3:3:5 | T:: | inconsistency2.cpp:3:3:3:6 | x | inconsistency2.cpp:2:20:2:20 | T | +| inconsistency2.cpp:3:3:3:11 | (no string representation) | inconsistency2.cpp:3:3:3:6 | x | file://:0:0:0:0 | const s | +| inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | (int)... | inconsistency.cpp:4:8:4:8 | S | +| inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | A | inconsistency.cpp:4:8:4:8 | S | | name_qualifiers.cpp:29:7:29:8 | :: | name_qualifiers.cpp:29:7:29:9 | x | file://:0:0:0:0 | (global namespace) | | name_qualifiers.cpp:31:7:31:10 | N1:: | name_qualifiers.cpp:31:7:31:12 | nx | name_qualifiers.cpp:4:11:4:12 | N1 | | name_qualifiers.cpp:34:7:34:8 | :: | name_qualifiers.cpp:34:9:34:12 | N1:: | file://:0:0:0:0 | (global namespace) | diff --git a/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.ql b/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.ql index 77a8e195ebe..b5b40e35caa 100644 --- a/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.ql +++ b/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.ql @@ -1,7 +1,5 @@ import cpp from NameQualifier nq, Location l -where - l = nq.getQualifiedElement().getLocation() and - l.getFile().getShortName() = "name_qualifiers" +where l = nq.getQualifiedElement().getLocation() select nq, nq.getQualifiedElement(), nq.getQualifyingElement() diff --git a/cpp/ql/test/library-tests/name_qualifiers/inconsistency.cpp b/cpp/ql/test/library-tests/name_qualifiers/inconsistency.cpp index caa5a6817c1..94c61bf8e23 100644 --- a/cpp/ql/test/library-tests/name_qualifiers/inconsistency.cpp +++ b/cpp/ql/test/library-tests/name_qualifiers/inconsistency.cpp @@ -1,8 +1,8 @@ // This file is present to test whether name-qualifying an enum constant leads to a database inconsistency. -// As such, there is no QL part of the test. + struct S { enum E { A }; }; -static int f() { +static void f() { switch(0) { case S::A: break; } } diff --git a/cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp b/cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp new file mode 100644 index 00000000000..d1fec43cb84 --- /dev/null +++ b/cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp @@ -0,0 +1,12 @@ +namespace { +template T f() { + T::x; + return {}; +} +struct s { + static int x; +}; +struct t { + s x = f(); +}; +} From 6d0968744b21998070623e3942baf204fb3365ed Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 10 Jun 2026 14:35:36 +0200 Subject: [PATCH 222/226] C++: Fix `NameQualifyingElement` db inconsistency --- cpp/ql/lib/semmle/code/cpp/Type.qll | 2 +- cpp/ql/lib/semmlecode.cpp.dbscheme | 3 ++- cpp/ql/test/library-tests/name_qualifiers/DB-CHECK.expected | 5 ----- .../library-tests/name_qualifiers/NameQualifiers1.expected | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) delete mode 100644 cpp/ql/test/library-tests/name_qualifiers/DB-CHECK.expected diff --git a/cpp/ql/lib/semmle/code/cpp/Type.qll b/cpp/ql/lib/semmle/code/cpp/Type.qll index fa2d2d605d8..4069b58134b 100644 --- a/cpp/ql/lib/semmle/code/cpp/Type.qll +++ b/cpp/ql/lib/semmle/code/cpp/Type.qll @@ -1071,7 +1071,7 @@ class NullPointerType extends BuiltInType { * const float fa[40]; * ``` */ -class DerivedType extends Type, @derivedtype { +class DerivedType extends Type, NameQualifyingElement, @derivedtype { override string toString() { result = this.getName() } override string getName() { derivedtypes(underlyingElement(this), result, _, _) } diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index ef8d209a22e..0853f43dc8c 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1430,7 +1430,8 @@ specialnamequalifyingelements( @namequalifyingelement = @namespace | @specialnamequalifyingelement | @usertype - | @decltype; + | @decltype + | @derivedtype; namequalifiers( unique int id: @namequalifier, diff --git a/cpp/ql/test/library-tests/name_qualifiers/DB-CHECK.expected b/cpp/ql/test/library-tests/name_qualifiers/DB-CHECK.expected deleted file mode 100644 index e27957d308d..00000000000 --- a/cpp/ql/test/library-tests/name_qualifiers/DB-CHECK.expected +++ /dev/null @@ -1,5 +0,0 @@ -[VALUE_NOT_IN_TYPE] predicate namequalifiers(@namequalifier id, @namequalifiableelement qualifiableelement, @namequalifyingelement qualifyingelement, @location_default location): Value 272 of field qualifyingelement is not in type @namequalifyingelement. The value is however in the following types: @type_with_specifiers. Appears in tuple (-16777185,-16777184,272,307) - Relevant element: qualifyingelement=272 - Full ID for 272: @"typeref_const(216)". The ID may expand to @"typeref_const{@"type_decl_s_nonproto[struct_complete]_{@"namespace_decl_(namespace line:1, {@"/Users/jketema/development/semmle-code/ql/cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp;sourcefile"}){@"not_inline"}"}_321bfec50edc"}" - Relevant element: location=307 - Full ID for 307: @"loc,(212),3,3,3,11". The ID may expand to @"loc,{@"/Users/jketema/development/semmle-code/ql/cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp;sourcefile"},3,3,3,11" diff --git a/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.expected b/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.expected index d9419b833a1..b5f2fe8dd74 100644 --- a/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.expected +++ b/cpp/ql/test/library-tests/name_qualifiers/NameQualifiers1.expected @@ -1,5 +1,5 @@ | inconsistency2.cpp:3:3:3:5 | T:: | inconsistency2.cpp:3:3:3:6 | x | inconsistency2.cpp:2:20:2:20 | T | -| inconsistency2.cpp:3:3:3:11 | (no string representation) | inconsistency2.cpp:3:3:3:6 | x | file://:0:0:0:0 | const s | +| inconsistency2.cpp:3:3:3:11 | const s:: | inconsistency2.cpp:3:3:3:6 | x | file://:0:0:0:0 | const s | | inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | (int)... | inconsistency.cpp:4:8:4:8 | S | | inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | A | inconsistency.cpp:4:8:4:8 | S | | name_qualifiers.cpp:29:7:29:8 | :: | name_qualifiers.cpp:29:7:29:9 | x | file://:0:0:0:0 | (global namespace) | From ef00aa2567f55a90c3aaf041be4c85d7ee4ae388 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 10 Jun 2026 14:38:15 +0200 Subject: [PATCH 223/226] C++: Add upgrade and downgrade scripts --- .../old.dbscheme | 2578 +++++++++++++++++ .../semmlecode.cpp.dbscheme | 2577 ++++++++++++++++ .../upgrade.properties | 2 + .../old.dbscheme | 2577 ++++++++++++++++ .../semmlecode.cpp.dbscheme | 2578 +++++++++++++++++ .../upgrade.properties | 2 + 6 files changed, 10314 insertions(+) create mode 100644 cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme create mode 100644 cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/semmlecode.cpp.dbscheme create mode 100644 cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/upgrade.properties create mode 100644 cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/old.dbscheme create mode 100644 cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/semmlecode.cpp.dbscheme create mode 100644 cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/upgrade.properties diff --git a/cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme b/cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme new file mode 100644 index 00000000000..0853f43dc8c --- /dev/null +++ b/cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme @@ -0,0 +1,2578 @@ + +/*- Compilations -*/ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * Optionally, record the build mode for each compilation. + */ +compilation_build_mode( + unique int id : @compilation ref, + int mode : int ref +); + +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +*/ + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/*- External data -*/ + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- C++ dbscheme -*/ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +/** + * Gives the TRAP filename that `trap` is associated with. + * For debugging only. + */ +trap_filename( + int trap: @trap, + string filename: string ref +); + +/** + * Gives the tag name for `tag`. + * For debugging only. + */ +tag_name( + int tag: @tag, + string name: string ref +); + +@trap_or_tag = @tag | @trap; + +/** + * Gives the name for the source file. + */ +source_file_name( + int sf: @source_file, + string name: string ref +); + +/** + * In `build-mode: none` overlay mode, indicates that `source_file` + * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the + * TRAP file corresponding to `foo.c`, something it transitively + * includes, or a template instantiation it transitively uses. + */ +source_file_uses_trap( + int source_file: @source_file ref, + int trap_file: @trap ref +); + +/** + * In `build-mode: none` overlay mode, indicates that the TRAP file + * `trap_file` uses tag `tag`. + */ +trap_uses_tag( + int trap_file: @trap ref, + int tag: @tag ref +); + +/** + * Holds if there is a definition of `element` in TRAP file or tag `t`. + */ +in_trap_or_tag( + int element: @element ref, + int t: @trap_or_tag ref +); + +pch_uses( + int pch: @pch ref, + int compilation: @compilation ref, + int id: @file ref +) + +#keyset[pch, compilation] +pch_creations( + int pch: @pch, + int compilation: @compilation ref, + int from: @file ref +) + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location_default ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +case @function.kind of + 0 = @unknown_function +| 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +builtin_functions( + int id: @function ref +) + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +/* +case @fun_requires.kind of + 1 = @template_attached +| 2 = @function_attached +; +*/ + +fun_requires( + int id: @fun_decl ref, + int kind: int ref, + int constraint: @expr ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_specialized(int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); +var_requires( + int id: @var_decl ref, + int constraint: @expr ref +); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); +type_requires( + int id: @type_decl ref, + int constraint: @expr ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +// ... 40 _Decimal32 +// ... 41 _Decimal64 +// ... 42 _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +| 62 = @mfp8 // __mfp8 +| 63 = @scalable_vector_count // __SVCount_t +| 64 = @complex_fp16 // _Complex __fp16 +| 65 = @complex_std_bfloat16 // _Complex __bf16 +| 66 = @complex_std_float16 // _Complex std::float16_t +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +| 11 = @scalable_vector // Arm SVE +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +tupleelements( + unique int id: @derivedtype ref, + int num_elements: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual` + * operator taking an expression as its argument. For example: + * ``` + * int a; + * decltype(1+a) b; + * typeof(1+a) c; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * changes the semantics of the decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ + +/* +case @decltype.kind of +| 0 = @decltype +| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual +; +*/ + +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int kind: int ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +case @type_operator.kind of + 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual +| 1 = @underlying_type +| 2 = @bases +| 3 = @direct_bases +| 4 = @add_lvalue_reference +| 5 = @add_pointer +| 6 = @add_rvalue_reference +| 7 = @decay +| 8 = @make_signed +| 9 = @make_unsigned +| 10 = @remove_all_extents +| 11 = @remove_const +| 12 = @remove_cv +| 13 = @remove_cvref +| 14 = @remove_extent +| 15 = @remove_pointer +| 16 = @remove_reference_t +| 17 = @remove_restrict +| 18 = @remove_volatile +| 19 = @remove_reference +; + +type_operators( + unique int id: @type_operator, + int arg_type: @type ref, + int kind: int ref, + int base_type: @type ref +) + +case @usertype.kind of + 0 = @unknown_usertype +| 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +// ... 5 = @typedef deprecated // classic C: typedef typedef type name +// ... 6 = @template deprecated +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +// ... 14 = @using_alias deprecated // a using name = type style typedef +| 15 = @template_struct +| 16 = @template_class +| 17 = @template_union +| 18 = @alias +; + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +/* +case @usertype.alias_kind of +| 0 = @typedef +| 1 = @alias +*/ + +usertype_alias_kind( + int id: @usertype ref, + int alias_kind: int ref +) + +nontype_template_parameters( + int id: @expr ref +); + +type_template_type_constraint( + int id: @usertype ref, + int constraint: @expr ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); +class_template_generated_from( + unique int template: @usertype ref, + int from: @usertype ref +) + +@user_or_decltype = @usertype | @decltype; + +is_proxy_class_for( + unique int id: @usertype ref, + int templ_param_id: @user_or_decltype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location_default ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); +function_template_generated_from( + unique int template: @function ref, + int from: @function ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); +variable_template_generated_from( + unique int template: @variable ref, + int from: @variable ref +); + +is_alias_template(unique int id: @usertype ref); +alias_instantiation( + unique int to: @usertype ref, + int from: @usertype ref +); +alias_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +alias_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); +alias_template_generated_from( + unique int template: @usertype ref, + int from: @usertype ref +); + +template_template_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +template_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +template_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +@concept = @concept_template | @concept_id; + +concept_templates( + unique int concept_id: @concept_template, + string name: string ref, + int location: @location_default ref +); +concept_instantiation( + unique int to: @concept_id ref, + int from: @concept_template ref +); +is_type_constraint(int concept_id: @concept_id ref); +concept_template_argument( + int concept_id: @concept ref, + int index: int ref, + int arg_type: @type ref +); +concept_template_argument_value( + int concept_id: @concept ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +namespaceattributes( + int namespace_id: @namespace ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + | @routinetype + | @ptrtomember + | @decltype + | @type_operator; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl + | @concept_template; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype + | @decltype + | @derivedtype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_default ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_default ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +| 394 = @isinvocable +| 395 = @isnothrowinvocable +| 396 = @isbitwisecloneable +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + | @isinvocable + | @isnothrowinvocable + | @isbitwisecloneable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +param_ref_to_this( + int expr: @param_ref ref +) + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref, + boolean is_designated: boolean ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref, + boolean is_designated: boolean ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack; + +sizeof_bind( + unique int expr: @sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref, + boolean has_explicit_parameter_list: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_default ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +| 38 = @stmt_consteval_if +| 39 = @stmt_not_consteval_if +| 40 = @stmt_leave +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +type_is_vla(unique int type_id: @derivedtype ref) + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if; + +consteval_if_then( + unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref, + int then_id: @stmt ref +); + +consteval_if_else( + unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 14 = @ppd_ms_import +| 15 = @ppd_elifdef +| 16 = @ppd_elifndef +| 17 = @ppd_embed +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +embeds( + unique int id: @ppd_embed ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/*- Database metadata -*/ + +/** + * The CLI will automatically emit applicable tuples for this table, + * such as `databaseMetadata("isOverlay", "true")` when building an + * overlay database. + */ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Overlay support -*/ + +/** + * The CLI will automatically emit tuples for each new/modified/deleted file + * when building an overlay database. + */ +overlayChangedFiles( + string path: string ref +); + +/*- XML Files -*/ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; diff --git a/cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/semmlecode.cpp.dbscheme b/cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..ef8d209a22e --- /dev/null +++ b/cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/semmlecode.cpp.dbscheme @@ -0,0 +1,2577 @@ + +/*- Compilations -*/ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * Optionally, record the build mode for each compilation. + */ +compilation_build_mode( + unique int id : @compilation ref, + int mode : int ref +); + +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +*/ + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/*- External data -*/ + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- C++ dbscheme -*/ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +/** + * Gives the TRAP filename that `trap` is associated with. + * For debugging only. + */ +trap_filename( + int trap: @trap, + string filename: string ref +); + +/** + * Gives the tag name for `tag`. + * For debugging only. + */ +tag_name( + int tag: @tag, + string name: string ref +); + +@trap_or_tag = @tag | @trap; + +/** + * Gives the name for the source file. + */ +source_file_name( + int sf: @source_file, + string name: string ref +); + +/** + * In `build-mode: none` overlay mode, indicates that `source_file` + * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the + * TRAP file corresponding to `foo.c`, something it transitively + * includes, or a template instantiation it transitively uses. + */ +source_file_uses_trap( + int source_file: @source_file ref, + int trap_file: @trap ref +); + +/** + * In `build-mode: none` overlay mode, indicates that the TRAP file + * `trap_file` uses tag `tag`. + */ +trap_uses_tag( + int trap_file: @trap ref, + int tag: @tag ref +); + +/** + * Holds if there is a definition of `element` in TRAP file or tag `t`. + */ +in_trap_or_tag( + int element: @element ref, + int t: @trap_or_tag ref +); + +pch_uses( + int pch: @pch ref, + int compilation: @compilation ref, + int id: @file ref +) + +#keyset[pch, compilation] +pch_creations( + int pch: @pch, + int compilation: @compilation ref, + int from: @file ref +) + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location_default ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +case @function.kind of + 0 = @unknown_function +| 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +builtin_functions( + int id: @function ref +) + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +/* +case @fun_requires.kind of + 1 = @template_attached +| 2 = @function_attached +; +*/ + +fun_requires( + int id: @fun_decl ref, + int kind: int ref, + int constraint: @expr ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_specialized(int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); +var_requires( + int id: @var_decl ref, + int constraint: @expr ref +); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); +type_requires( + int id: @type_decl ref, + int constraint: @expr ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +// ... 40 _Decimal32 +// ... 41 _Decimal64 +// ... 42 _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +| 62 = @mfp8 // __mfp8 +| 63 = @scalable_vector_count // __SVCount_t +| 64 = @complex_fp16 // _Complex __fp16 +| 65 = @complex_std_bfloat16 // _Complex __bf16 +| 66 = @complex_std_float16 // _Complex std::float16_t +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +| 11 = @scalable_vector // Arm SVE +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +tupleelements( + unique int id: @derivedtype ref, + int num_elements: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual` + * operator taking an expression as its argument. For example: + * ``` + * int a; + * decltype(1+a) b; + * typeof(1+a) c; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * changes the semantics of the decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ + +/* +case @decltype.kind of +| 0 = @decltype +| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual +; +*/ + +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int kind: int ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +case @type_operator.kind of + 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual +| 1 = @underlying_type +| 2 = @bases +| 3 = @direct_bases +| 4 = @add_lvalue_reference +| 5 = @add_pointer +| 6 = @add_rvalue_reference +| 7 = @decay +| 8 = @make_signed +| 9 = @make_unsigned +| 10 = @remove_all_extents +| 11 = @remove_const +| 12 = @remove_cv +| 13 = @remove_cvref +| 14 = @remove_extent +| 15 = @remove_pointer +| 16 = @remove_reference_t +| 17 = @remove_restrict +| 18 = @remove_volatile +| 19 = @remove_reference +; + +type_operators( + unique int id: @type_operator, + int arg_type: @type ref, + int kind: int ref, + int base_type: @type ref +) + +case @usertype.kind of + 0 = @unknown_usertype +| 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +// ... 5 = @typedef deprecated // classic C: typedef typedef type name +// ... 6 = @template deprecated +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +// ... 14 = @using_alias deprecated // a using name = type style typedef +| 15 = @template_struct +| 16 = @template_class +| 17 = @template_union +| 18 = @alias +; + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +/* +case @usertype.alias_kind of +| 0 = @typedef +| 1 = @alias +*/ + +usertype_alias_kind( + int id: @usertype ref, + int alias_kind: int ref +) + +nontype_template_parameters( + int id: @expr ref +); + +type_template_type_constraint( + int id: @usertype ref, + int constraint: @expr ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); +class_template_generated_from( + unique int template: @usertype ref, + int from: @usertype ref +) + +@user_or_decltype = @usertype | @decltype; + +is_proxy_class_for( + unique int id: @usertype ref, + int templ_param_id: @user_or_decltype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location_default ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); +function_template_generated_from( + unique int template: @function ref, + int from: @function ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); +variable_template_generated_from( + unique int template: @variable ref, + int from: @variable ref +); + +is_alias_template(unique int id: @usertype ref); +alias_instantiation( + unique int to: @usertype ref, + int from: @usertype ref +); +alias_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +alias_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); +alias_template_generated_from( + unique int template: @usertype ref, + int from: @usertype ref +); + +template_template_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +template_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +template_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +@concept = @concept_template | @concept_id; + +concept_templates( + unique int concept_id: @concept_template, + string name: string ref, + int location: @location_default ref +); +concept_instantiation( + unique int to: @concept_id ref, + int from: @concept_template ref +); +is_type_constraint(int concept_id: @concept_id ref); +concept_template_argument( + int concept_id: @concept ref, + int index: int ref, + int arg_type: @type ref +); +concept_template_argument_value( + int concept_id: @concept ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +namespaceattributes( + int namespace_id: @namespace ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + | @routinetype + | @ptrtomember + | @decltype + | @type_operator; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl + | @concept_template; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype + | @decltype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_default ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_default ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +| 394 = @isinvocable +| 395 = @isnothrowinvocable +| 396 = @isbitwisecloneable +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + | @isinvocable + | @isnothrowinvocable + | @isbitwisecloneable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +param_ref_to_this( + int expr: @param_ref ref +) + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref, + boolean is_designated: boolean ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref, + boolean is_designated: boolean ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack; + +sizeof_bind( + unique int expr: @sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref, + boolean has_explicit_parameter_list: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_default ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +| 38 = @stmt_consteval_if +| 39 = @stmt_not_consteval_if +| 40 = @stmt_leave +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +type_is_vla(unique int type_id: @derivedtype ref) + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if; + +consteval_if_then( + unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref, + int then_id: @stmt ref +); + +consteval_if_else( + unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 14 = @ppd_ms_import +| 15 = @ppd_elifdef +| 16 = @ppd_elifndef +| 17 = @ppd_embed +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +embeds( + unique int id: @ppd_embed ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/*- Database metadata -*/ + +/** + * The CLI will automatically emit applicable tuples for this table, + * such as `databaseMetadata("isOverlay", "true")` when building an + * overlay database. + */ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Overlay support -*/ + +/** + * The CLI will automatically emit tuples for each new/modified/deleted file + * when building an overlay database. + */ +overlayChangedFiles( + string path: string ref +); + +/*- XML Files -*/ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; diff --git a/cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/upgrade.properties b/cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/upgrade.properties new file mode 100644 index 00000000000..d3a842d2cbb --- /dev/null +++ b/cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/upgrade.properties @@ -0,0 +1,2 @@ +description: Fix NameQualifier inconsistency +compatibility: full diff --git a/cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/old.dbscheme b/cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/old.dbscheme new file mode 100644 index 00000000000..ef8d209a22e --- /dev/null +++ b/cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/old.dbscheme @@ -0,0 +1,2577 @@ + +/*- Compilations -*/ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * Optionally, record the build mode for each compilation. + */ +compilation_build_mode( + unique int id : @compilation ref, + int mode : int ref +); + +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +*/ + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/*- External data -*/ + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- C++ dbscheme -*/ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +/** + * Gives the TRAP filename that `trap` is associated with. + * For debugging only. + */ +trap_filename( + int trap: @trap, + string filename: string ref +); + +/** + * Gives the tag name for `tag`. + * For debugging only. + */ +tag_name( + int tag: @tag, + string name: string ref +); + +@trap_or_tag = @tag | @trap; + +/** + * Gives the name for the source file. + */ +source_file_name( + int sf: @source_file, + string name: string ref +); + +/** + * In `build-mode: none` overlay mode, indicates that `source_file` + * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the + * TRAP file corresponding to `foo.c`, something it transitively + * includes, or a template instantiation it transitively uses. + */ +source_file_uses_trap( + int source_file: @source_file ref, + int trap_file: @trap ref +); + +/** + * In `build-mode: none` overlay mode, indicates that the TRAP file + * `trap_file` uses tag `tag`. + */ +trap_uses_tag( + int trap_file: @trap ref, + int tag: @tag ref +); + +/** + * Holds if there is a definition of `element` in TRAP file or tag `t`. + */ +in_trap_or_tag( + int element: @element ref, + int t: @trap_or_tag ref +); + +pch_uses( + int pch: @pch ref, + int compilation: @compilation ref, + int id: @file ref +) + +#keyset[pch, compilation] +pch_creations( + int pch: @pch, + int compilation: @compilation ref, + int from: @file ref +) + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location_default ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +case @function.kind of + 0 = @unknown_function +| 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +builtin_functions( + int id: @function ref +) + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +/* +case @fun_requires.kind of + 1 = @template_attached +| 2 = @function_attached +; +*/ + +fun_requires( + int id: @fun_decl ref, + int kind: int ref, + int constraint: @expr ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_specialized(int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); +var_requires( + int id: @var_decl ref, + int constraint: @expr ref +); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); +type_requires( + int id: @type_decl ref, + int constraint: @expr ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +// ... 40 _Decimal32 +// ... 41 _Decimal64 +// ... 42 _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +| 62 = @mfp8 // __mfp8 +| 63 = @scalable_vector_count // __SVCount_t +| 64 = @complex_fp16 // _Complex __fp16 +| 65 = @complex_std_bfloat16 // _Complex __bf16 +| 66 = @complex_std_float16 // _Complex std::float16_t +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +| 11 = @scalable_vector // Arm SVE +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +tupleelements( + unique int id: @derivedtype ref, + int num_elements: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual` + * operator taking an expression as its argument. For example: + * ``` + * int a; + * decltype(1+a) b; + * typeof(1+a) c; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * changes the semantics of the decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ + +/* +case @decltype.kind of +| 0 = @decltype +| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual +; +*/ + +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int kind: int ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +case @type_operator.kind of + 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual +| 1 = @underlying_type +| 2 = @bases +| 3 = @direct_bases +| 4 = @add_lvalue_reference +| 5 = @add_pointer +| 6 = @add_rvalue_reference +| 7 = @decay +| 8 = @make_signed +| 9 = @make_unsigned +| 10 = @remove_all_extents +| 11 = @remove_const +| 12 = @remove_cv +| 13 = @remove_cvref +| 14 = @remove_extent +| 15 = @remove_pointer +| 16 = @remove_reference_t +| 17 = @remove_restrict +| 18 = @remove_volatile +| 19 = @remove_reference +; + +type_operators( + unique int id: @type_operator, + int arg_type: @type ref, + int kind: int ref, + int base_type: @type ref +) + +case @usertype.kind of + 0 = @unknown_usertype +| 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +// ... 5 = @typedef deprecated // classic C: typedef typedef type name +// ... 6 = @template deprecated +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +// ... 14 = @using_alias deprecated // a using name = type style typedef +| 15 = @template_struct +| 16 = @template_class +| 17 = @template_union +| 18 = @alias +; + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +/* +case @usertype.alias_kind of +| 0 = @typedef +| 1 = @alias +*/ + +usertype_alias_kind( + int id: @usertype ref, + int alias_kind: int ref +) + +nontype_template_parameters( + int id: @expr ref +); + +type_template_type_constraint( + int id: @usertype ref, + int constraint: @expr ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); +class_template_generated_from( + unique int template: @usertype ref, + int from: @usertype ref +) + +@user_or_decltype = @usertype | @decltype; + +is_proxy_class_for( + unique int id: @usertype ref, + int templ_param_id: @user_or_decltype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location_default ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); +function_template_generated_from( + unique int template: @function ref, + int from: @function ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); +variable_template_generated_from( + unique int template: @variable ref, + int from: @variable ref +); + +is_alias_template(unique int id: @usertype ref); +alias_instantiation( + unique int to: @usertype ref, + int from: @usertype ref +); +alias_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +alias_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); +alias_template_generated_from( + unique int template: @usertype ref, + int from: @usertype ref +); + +template_template_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +template_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +template_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +@concept = @concept_template | @concept_id; + +concept_templates( + unique int concept_id: @concept_template, + string name: string ref, + int location: @location_default ref +); +concept_instantiation( + unique int to: @concept_id ref, + int from: @concept_template ref +); +is_type_constraint(int concept_id: @concept_id ref); +concept_template_argument( + int concept_id: @concept ref, + int index: int ref, + int arg_type: @type ref +); +concept_template_argument_value( + int concept_id: @concept ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +namespaceattributes( + int namespace_id: @namespace ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + | @routinetype + | @ptrtomember + | @decltype + | @type_operator; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl + | @concept_template; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype + | @decltype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_default ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_default ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +| 394 = @isinvocable +| 395 = @isnothrowinvocable +| 396 = @isbitwisecloneable +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + | @isinvocable + | @isnothrowinvocable + | @isbitwisecloneable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +param_ref_to_this( + int expr: @param_ref ref +) + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref, + boolean is_designated: boolean ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref, + boolean is_designated: boolean ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack; + +sizeof_bind( + unique int expr: @sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref, + boolean has_explicit_parameter_list: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_default ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +| 38 = @stmt_consteval_if +| 39 = @stmt_not_consteval_if +| 40 = @stmt_leave +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +type_is_vla(unique int type_id: @derivedtype ref) + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if; + +consteval_if_then( + unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref, + int then_id: @stmt ref +); + +consteval_if_else( + unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 14 = @ppd_ms_import +| 15 = @ppd_elifdef +| 16 = @ppd_elifndef +| 17 = @ppd_embed +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +embeds( + unique int id: @ppd_embed ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/*- Database metadata -*/ + +/** + * The CLI will automatically emit applicable tuples for this table, + * such as `databaseMetadata("isOverlay", "true")` when building an + * overlay database. + */ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Overlay support -*/ + +/** + * The CLI will automatically emit tuples for each new/modified/deleted file + * when building an overlay database. + */ +overlayChangedFiles( + string path: string ref +); + +/*- XML Files -*/ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..0853f43dc8c --- /dev/null +++ b/cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/semmlecode.cpp.dbscheme @@ -0,0 +1,2578 @@ + +/*- Compilations -*/ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The expanded arguments that were passed to the extractor for a + * compiler invocation. This is similar to `compilation_args`, but + * for a `@someFile` argument, it includes the arguments from that + * file, rather than just taking the argument literally. + */ +#keyset[id, num] +compilation_expanded_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * Optionally, record the build mode for each compilation. + */ +compilation_build_mode( + unique int id : @compilation ref, + int mode : int ref +); + +/* +case @compilation_build_mode.mode of + 0 = @build_mode_none +| 1 = @build_mode_manual +| 2 = @build_mode_auto +; +*/ + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/*- External data -*/ + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- C++ dbscheme -*/ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +/** + * Gives the TRAP filename that `trap` is associated with. + * For debugging only. + */ +trap_filename( + int trap: @trap, + string filename: string ref +); + +/** + * Gives the tag name for `tag`. + * For debugging only. + */ +tag_name( + int tag: @tag, + string name: string ref +); + +@trap_or_tag = @tag | @trap; + +/** + * Gives the name for the source file. + */ +source_file_name( + int sf: @source_file, + string name: string ref +); + +/** + * In `build-mode: none` overlay mode, indicates that `source_file` + * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the + * TRAP file corresponding to `foo.c`, something it transitively + * includes, or a template instantiation it transitively uses. + */ +source_file_uses_trap( + int source_file: @source_file ref, + int trap_file: @trap ref +); + +/** + * In `build-mode: none` overlay mode, indicates that the TRAP file + * `trap_file` uses tag `tag`. + */ +trap_uses_tag( + int trap_file: @trap ref, + int tag: @tag ref +); + +/** + * Holds if there is a definition of `element` in TRAP file or tag `t`. + */ +in_trap_or_tag( + int element: @element ref, + int t: @trap_or_tag ref +); + +pch_uses( + int pch: @pch ref, + int compilation: @compilation ref, + int id: @file ref +) + +#keyset[pch, compilation] +pch_creations( + int pch: @pch, + int compilation: @compilation ref, + int from: @file ref +) + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location_default ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +case @function.kind of + 0 = @unknown_function +| 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +builtin_functions( + int id: @function ref +) + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref +); + +/* +case @coroutine_placeholder_variable.kind of + 1 = @handle +| 2 = @promise +| 3 = @init_await_resume +; +*/ + +coroutine_placeholder_variable( + unique int placeholder_variable: @variable ref, + int kind: int ref, + int function: @function ref +) + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +/* +case @fun_requires.kind of + 1 = @template_attached +| 2 = @function_attached +; +*/ + +fun_requires( + int id: @fun_decl ref, + int kind: int ref, + int constraint: @expr ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_specialized(int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); +var_requires( + int id: @var_decl ref, + int constraint: @expr ref +); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); +type_requires( + int id: @type_decl ref, + int constraint: @expr ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @parameterized_element ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +// ... 40 _Decimal32 +// ... 41 _Decimal64 +// ... 42 _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +| 62 = @mfp8 // __mfp8 +| 63 = @scalable_vector_count // __SVCount_t +| 64 = @complex_fp16 // _Complex __fp16 +| 65 = @complex_std_bfloat16 // _Complex __bf16 +| 66 = @complex_std_float16 // _Complex std::float16_t +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +| 11 = @scalable_vector // Arm SVE +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +tupleelements( + unique int id: @derivedtype ref, + int num_elements: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual` + * operator taking an expression as its argument. For example: + * ``` + * int a; + * decltype(1+a) b; + * typeof(1+a) c; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * changes the semantics of the decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ + +/* +case @decltype.kind of +| 0 = @decltype +| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual +; +*/ + +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int kind: int ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +case @type_operator.kind of + 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual +| 1 = @underlying_type +| 2 = @bases +| 3 = @direct_bases +| 4 = @add_lvalue_reference +| 5 = @add_pointer +| 6 = @add_rvalue_reference +| 7 = @decay +| 8 = @make_signed +| 9 = @make_unsigned +| 10 = @remove_all_extents +| 11 = @remove_const +| 12 = @remove_cv +| 13 = @remove_cvref +| 14 = @remove_extent +| 15 = @remove_pointer +| 16 = @remove_reference_t +| 17 = @remove_restrict +| 18 = @remove_volatile +| 19 = @remove_reference +; + +type_operators( + unique int id: @type_operator, + int arg_type: @type ref, + int kind: int ref, + int base_type: @type ref +) + +case @usertype.kind of + 0 = @unknown_usertype +| 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +// ... 5 = @typedef deprecated // classic C: typedef typedef type name +// ... 6 = @template deprecated +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +// ... 14 = @using_alias deprecated // a using name = type style typedef +| 15 = @template_struct +| 16 = @template_class +| 17 = @template_union +| 18 = @alias +; + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +/* +case @usertype.alias_kind of +| 0 = @typedef +| 1 = @alias +*/ + +usertype_alias_kind( + int id: @usertype ref, + int alias_kind: int ref +) + +nontype_template_parameters( + int id: @expr ref +); + +type_template_type_constraint( + int id: @usertype ref, + int constraint: @expr ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); +class_template_generated_from( + unique int template: @usertype ref, + int from: @usertype ref +) + +@user_or_decltype = @usertype | @decltype; + +is_proxy_class_for( + unique int id: @usertype ref, + int templ_param_id: @user_or_decltype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location_default ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); +function_template_generated_from( + unique int template: @function ref, + int from: @function ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); +variable_template_generated_from( + unique int template: @variable ref, + int from: @variable ref +); + +is_alias_template(unique int id: @usertype ref); +alias_instantiation( + unique int to: @usertype ref, + int from: @usertype ref +); +alias_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +alias_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); +alias_template_generated_from( + unique int template: @usertype ref, + int from: @usertype ref +); + +template_template_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +template_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +template_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +@concept = @concept_template | @concept_id; + +concept_templates( + unique int concept_id: @concept_template, + string name: string ref, + int location: @location_default ref +); +concept_instantiation( + unique int to: @concept_id ref, + int from: @concept_template ref +); +is_type_constraint(int concept_id: @concept_id ref); +concept_template_argument( + int concept_id: @concept ref, + int index: int ref, + int arg_type: @type ref +); +concept_template_argument_value( + int concept_id: @concept ref, + int index: int ref, + int arg_value: @expr ref +); + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +namespaceattributes( + int namespace_id: @namespace ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + | @routinetype + | @ptrtomember + | @decltype + | @type_operator; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl + | @concept_template; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype + | @decltype + | @derivedtype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_default ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_default ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +| 390 = @requires_expr +| 391 = @nested_requirement +| 392 = @compound_requirement +| 393 = @concept_id +| 394 = @isinvocable +| 395 = @isnothrowinvocable +| 396 = @isbitwisecloneable +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + | @isinvocable + | @isnothrowinvocable + | @isbitwisecloneable + ; + +compound_requirement_is_noexcept( + int expr: @compound_requirement ref +); + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +param_ref_to_this( + int expr: @param_ref ref +) + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref, + boolean is_designated: boolean ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref, + boolean is_designated: boolean ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack; + +sizeof_bind( + unique int expr: @sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref, + boolean has_explicit_parameter_list: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_default ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +| 38 = @stmt_consteval_if +| 39 = @stmt_not_consteval_if +| 40 = @stmt_leave +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +type_is_vla(unique int type_id: @derivedtype ref) + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if; + +consteval_if_then( + unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref, + int then_id: @stmt ref +); + +consteval_if_else( + unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@parameterized_element = @function | @stmt_block | @requires_expr; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @parameterized_element ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 14 = @ppd_ms_import +| 15 = @ppd_elifdef +| 16 = @ppd_elifndef +| 17 = @ppd_embed +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +embeds( + unique int id: @ppd_embed ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/*- Database metadata -*/ + +/** + * The CLI will automatically emit applicable tuples for this table, + * such as `databaseMetadata("isOverlay", "true")` when building an + * overlay database. + */ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +/*- Overlay support -*/ + +/** + * The CLI will automatically emit tuples for each new/modified/deleted file + * when building an overlay database. + */ +overlayChangedFiles( + string path: string ref +); + +/*- XML Files -*/ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/upgrade.properties b/cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/upgrade.properties new file mode 100644 index 00000000000..d3a842d2cbb --- /dev/null +++ b/cpp/ql/lib/upgrades/ef8d209a22e27413aaaeff4446f0ecb9fa2c227b/upgrade.properties @@ -0,0 +1,2 @@ +description: Fix NameQualifier inconsistency +compatibility: full From 4c411bbcb5de03da4d852d742aa1da6777b095c8 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 10 Jun 2026 07:07:49 +0200 Subject: [PATCH 224/226] Convert hand-rolled inline expectations test --- .../go/frameworks/Twirp/RequestForgery.qlref | 4 +- .../semmle/go/frameworks/Twirp/client/main.go | 2 +- .../frameworks/Twirp/rpc/notes/service.pb.go | 10 +- .../Twirp/rpc/notes/service.twirp.go | 36 +-- .../semmle/go/frameworks/Twirp/server/main.go | 10 +- .../semmle/go/frameworks/Twirp/tests.expected | 32 +-- .../semmle/go/frameworks/Twirp/tests.ql | 229 +++++------------- 7 files changed, 95 insertions(+), 228 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.qlref index 061679da228..760862973f1 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.qlref @@ -1,2 +1,4 @@ query: Security/CWE-918/RequestForgery.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/client/main.go b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/client/main.go index 76abd1a0a9c..e5b4cd2351d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/client/main.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/client/main.go @@ -9,7 +9,7 @@ import ( ) func main() { - client := notes.NewNotesServiceProtobufClient("http://localhost:8000", &http.Client{}) // test: ssrfSink + client := notes.NewNotesServiceProtobufClient("http://localhost:8000", &http.Client{}) // $ ssrfSink ctx := context.Background() diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/rpc/notes/service.pb.go b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/rpc/notes/service.pb.go index f0c3e4910d9..e91168f43a9 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/rpc/notes/service.pb.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/rpc/notes/service.pb.go @@ -20,7 +20,7 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type Note struct { // test: message +type Note struct { // $ message state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -83,7 +83,7 @@ func (x *Note) GetCreatedAt() int64 { return 0 } -type CreateNoteParams struct { // test: message +type CreateNoteParams struct { // $ message state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -130,7 +130,7 @@ func (x *CreateNoteParams) GetText() string { return "" } -type GetAllNotesParams struct { // test: message +type GetAllNotesParams struct { // $ message state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -168,7 +168,7 @@ func (*GetAllNotesParams) Descriptor() ([]byte, []int) { return file_rpc_notes_service_proto_rawDescGZIP(), []int{2} } -type GetAllNotesResult struct { // test: message +type GetAllNotesResult struct { // $ message state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -340,7 +340,7 @@ func file_rpc_notes_service_proto_init() { } } } - type x struct{} + type x struct{} // $ SPURIOUS: message // not message out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/rpc/notes/service.twirp.go b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/rpc/notes/service.twirp.go index 19bcc56f261..6b34dcf08ea 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/rpc/notes/service.twirp.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/rpc/notes/service.twirp.go @@ -31,7 +31,7 @@ const _ = twirp.TwirpPackageMinVersion_8_1_0 // NotesService Interface // ====================== -type NotesService interface { // test: serviceInterface +type NotesService interface { // $ serviceInterface CreateNote(context.Context, *CreateNoteParams) (*Note, error) GetAllNotes(context.Context, *GetAllNotesParams) (*GetAllNotesResult, error) @@ -41,7 +41,7 @@ type NotesService interface { // test: serviceInterface // NotesService Protobuf Client // ============================ -type notesServiceProtobufClient struct { // test: serviceClient +type notesServiceProtobufClient struct { // $ serviceClient client HTTPClient urls [2]string interceptor twirp.Interceptor @@ -50,7 +50,7 @@ type notesServiceProtobufClient struct { // test: serviceClient // NewNotesServiceProtobufClient creates a Protobuf client that implements the NotesService interface. // It communicates using Protobuf and can be configured with a custom HTTPClient. -func NewNotesServiceProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) NotesService { // test: clientConstructor +func NewNotesServiceProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) NotesService { // $ clientConstructor if c, ok := client.(*http.Client); ok { client = withoutRedirects(c) } @@ -84,7 +84,7 @@ func NewNotesServiceProtobufClient(baseURL string, client HTTPClient, opts ...tw } } -func (c *notesServiceProtobufClient) CreateNote(ctx context.Context, in *CreateNoteParams) (*Note, error) { // test: !handler +func (c *notesServiceProtobufClient) CreateNote(ctx context.Context, in *CreateNoteParams) (*Note, error) { // not handler ctx = ctxsetters.WithPackageName(ctx, "gotwirprpcexample.rpc.notes") ctx = ctxsetters.WithServiceName(ctx, "NotesService") ctx = ctxsetters.WithMethodName(ctx, "CreateNote") @@ -113,7 +113,7 @@ func (c *notesServiceProtobufClient) CreateNote(ctx context.Context, in *CreateN return caller(ctx, in) } -func (c *notesServiceProtobufClient) callCreateNote(ctx context.Context, in *CreateNoteParams) (*Note, error) { // test: !handler +func (c *notesServiceProtobufClient) callCreateNote(ctx context.Context, in *CreateNoteParams) (*Note, error) { // not handler out := new(Note) ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) if err != nil { @@ -130,7 +130,7 @@ func (c *notesServiceProtobufClient) callCreateNote(ctx context.Context, in *Cre return out, nil } -func (c *notesServiceProtobufClient) GetAllNotes(ctx context.Context, in *GetAllNotesParams) (*GetAllNotesResult, error) { // test: !handler +func (c *notesServiceProtobufClient) GetAllNotes(ctx context.Context, in *GetAllNotesParams) (*GetAllNotesResult, error) { // not handler ctx = ctxsetters.WithPackageName(ctx, "gotwirprpcexample.rpc.notes") ctx = ctxsetters.WithServiceName(ctx, "NotesService") ctx = ctxsetters.WithMethodName(ctx, "GetAllNotes") @@ -159,7 +159,7 @@ func (c *notesServiceProtobufClient) GetAllNotes(ctx context.Context, in *GetAll return caller(ctx, in) } -func (c *notesServiceProtobufClient) callGetAllNotes(ctx context.Context, in *GetAllNotesParams) (*GetAllNotesResult, error) { // test: !handler +func (c *notesServiceProtobufClient) callGetAllNotes(ctx context.Context, in *GetAllNotesParams) (*GetAllNotesResult, error) { // not handler out := new(GetAllNotesResult) ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out) if err != nil { @@ -180,7 +180,7 @@ func (c *notesServiceProtobufClient) callGetAllNotes(ctx context.Context, in *Ge // NotesService JSON Client // ======================== -type notesServiceJSONClient struct { // test: serviceClient +type notesServiceJSONClient struct { // $ serviceClient client HTTPClient urls [2]string interceptor twirp.Interceptor @@ -189,7 +189,7 @@ type notesServiceJSONClient struct { // test: serviceClient // NewNotesServiceJSONClient creates a JSON client that implements the NotesService interface. // It communicates using JSON and can be configured with a custom HTTPClient. -func NewNotesServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) NotesService { // test: clientConstructor +func NewNotesServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) NotesService { // $ clientConstructor if c, ok := client.(*http.Client); ok { client = withoutRedirects(c) } @@ -223,7 +223,7 @@ func NewNotesServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp. } } -func (c *notesServiceJSONClient) CreateNote(ctx context.Context, in *CreateNoteParams) (*Note, error) { // test: !handler +func (c *notesServiceJSONClient) CreateNote(ctx context.Context, in *CreateNoteParams) (*Note, error) { // not handler ctx = ctxsetters.WithPackageName(ctx, "gotwirprpcexample.rpc.notes") ctx = ctxsetters.WithServiceName(ctx, "NotesService") ctx = ctxsetters.WithMethodName(ctx, "CreateNote") @@ -252,7 +252,7 @@ func (c *notesServiceJSONClient) CreateNote(ctx context.Context, in *CreateNoteP return caller(ctx, in) } -func (c *notesServiceJSONClient) callCreateNote(ctx context.Context, in *CreateNoteParams) (*Note, error) { // test: !handler +func (c *notesServiceJSONClient) callCreateNote(ctx context.Context, in *CreateNoteParams) (*Note, error) { // not handler out := new(Note) ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) if err != nil { @@ -269,7 +269,7 @@ func (c *notesServiceJSONClient) callCreateNote(ctx context.Context, in *CreateN return out, nil } -func (c *notesServiceJSONClient) GetAllNotes(ctx context.Context, in *GetAllNotesParams) (*GetAllNotesResult, error) { // test: !handler +func (c *notesServiceJSONClient) GetAllNotes(ctx context.Context, in *GetAllNotesParams) (*GetAllNotesResult, error) { // not handler ctx = ctxsetters.WithPackageName(ctx, "gotwirprpcexample.rpc.notes") ctx = ctxsetters.WithServiceName(ctx, "NotesService") ctx = ctxsetters.WithMethodName(ctx, "GetAllNotes") @@ -298,7 +298,7 @@ func (c *notesServiceJSONClient) GetAllNotes(ctx context.Context, in *GetAllNote return caller(ctx, in) } -func (c *notesServiceJSONClient) callGetAllNotes(ctx context.Context, in *GetAllNotesParams) (*GetAllNotesResult, error) { // test: !handler +func (c *notesServiceJSONClient) callGetAllNotes(ctx context.Context, in *GetAllNotesParams) (*GetAllNotesResult, error) { // not handler out := new(GetAllNotesResult) ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out) if err != nil { @@ -319,7 +319,7 @@ func (c *notesServiceJSONClient) callGetAllNotes(ctx context.Context, in *GetAll // NotesService Server Handler // =========================== -type notesServiceServer struct { // test: serviceServer +type notesServiceServer struct { // $ serviceServer NotesService interceptor twirp.Interceptor hooks *twirp.ServerHooks @@ -331,7 +331,7 @@ type notesServiceServer struct { // test: serviceServer // NewNotesServiceServer builds a TwirpServer that can be used as an http.Handler to handle // HTTP requests that are routed to the right method in the provided svc implementation. // The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks). -func NewNotesServiceServer(svc NotesService, opts ...interface{}) TwirpServer { // test: serverConstructor +func NewNotesServiceServer(svc NotesService, opts ...interface{}) TwirpServer { // $ serverConstructor serverOpts := newServerOpts(opts) // Using ReadOpt allows backwards and forwards compatibility with new options in the future @@ -535,7 +535,7 @@ func (s *notesServiceServer) serveCreateNoteProtobuf(ctx context.Context, resp h return } - buf, err := io.ReadAll(req.Body) + buf, err := io.ReadAll(req.Body) // $ Source if err != nil { s.handleRequestBodyError(ctx, resp, "failed to read request body", err) return @@ -812,7 +812,7 @@ func (s *notesServiceServer) PathPrefix() string { // automatically disabled if *(net/http).Client is passed to client // constructors. See the withoutRedirects function in this file for more // details. -type HTTPClient interface { +type HTTPClient interface { // $ SPURIOUS: serviceInterface // not serviceInterface Do(req *http.Request) (*http.Response, error) } @@ -820,7 +820,7 @@ type HTTPClient interface { // HTTP handlers with additional methods for accessing metadata about the // service. Those accessors are a low-level API for building reflection tools. // Most people can think of TwirpServers as just http.Handlers. -type TwirpServer interface { +type TwirpServer interface { // $ SPURIOUS: serviceInterface // not serviceInterface http.Handler // ServiceDescriptor returns gzipped bytes describing the .proto file that diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/server/main.go b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/server/main.go index 203b3af1736..7499e79f827 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/server/main.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/server/main.go @@ -16,7 +16,7 @@ type notesService struct { CurrentId int32 } -func (s *notesService) CreateNote(ctx context.Context, params *notes.CreateNoteParams) (*notes.Note, error) { // test: routeHandler, request +func (s *notesService) CreateNote(ctx context.Context, params *notes.CreateNoteParams) (*notes.Note, error) { // $ Source request handler // route handler if len(params.Text) < 4 { return nil, twirp.InvalidArgument.Error("Text should be min 4 characters.") } @@ -27,8 +27,8 @@ func (s *notesService) CreateNote(ctx context.Context, params *notes.CreateNoteP CreatedAt: time.Now().UnixMilli(), } - notes.NewNotesServiceProtobufClient(params.Text, &http.Client{}) // test: ssrfSink, ssrf - notes.NewNotesServiceProtobufClient(strconv.FormatInt(int64(s.CurrentId), 10), &http.Client{}) // test: ssrfSink, !ssrf + notes.NewNotesServiceProtobufClient(params.Text, &http.Client{}) // $ Alert ssrfSink ssrf + notes.NewNotesServiceProtobufClient(strconv.FormatInt(int64(s.CurrentId), 10), &http.Client{}) // $ ssrfSink // not ssrf s.Notes = append(s.Notes, note) @@ -37,7 +37,7 @@ func (s *notesService) CreateNote(ctx context.Context, params *notes.CreateNoteP return ¬e, nil } -func (s *notesService) GetAllNotes(ctx context.Context, params *notes.GetAllNotesParams) (*notes.GetAllNotesResult, error) { // test: routeHandler, request +func (s *notesService) GetAllNotes(ctx context.Context, params *notes.GetAllNotesParams) (*notes.GetAllNotesResult, error) { // $ request handler // route handler allNotes := make([]*notes.Note, 0) fmt.Println(params) @@ -57,7 +57,7 @@ func main() { mux := http.NewServeMux() mux.Handle(notesServer.PathPrefix(), notesServer) - err := http.ListenAndServe(":8000", notesServer) // test: !ssrfSink + err := http.ListenAndServe(":8000", notesServer) // not ssrfSink if err != nil { panic(err) } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/tests.expected b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/tests.expected index 4b0a2d917e7..42831abaf15 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/tests.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/tests.expected @@ -1,32 +1,2 @@ invalidModelRow -passingPositiveTests -| PASSED | clientConstructor | rpc/notes/service.twirp.go:53:114:53:139 | comment | -| PASSED | clientConstructor | rpc/notes/service.twirp.go:192:110:192:135 | comment | -| PASSED | message | rpc/notes/service.pb.go:23:20:23:35 | comment | -| PASSED | message | rpc/notes/service.pb.go:86:32:86:47 | comment | -| PASSED | message | rpc/notes/service.pb.go:133:33:133:48 | comment | -| PASSED | message | rpc/notes/service.pb.go:171:33:171:48 | comment | -| PASSED | request | server/main.go:19:111:19:140 | comment | -| PASSED | request | server/main.go:40:126:40:155 | comment | -| PASSED | serverConstructor | rpc/notes/service.twirp.go:334:81:334:106 | comment | -| PASSED | serviceClient | rpc/notes/service.twirp.go:44:42:44:63 | comment | -| PASSED | serviceClient | rpc/notes/service.twirp.go:183:38:183:59 | comment | -| PASSED | serviceInterface | rpc/notes/service.twirp.go:34:31:34:55 | comment | -| PASSED | serviceServer | rpc/notes/service.twirp.go:322:34:322:55 | comment | -| PASSED | ssrf | server/main.go:30:97:30:119 | comment | -| PASSED | ssrfSink | client/main.go:12:89:12:105 | comment | -| PASSED | ssrfSink | server/main.go:30:97:30:119 | comment | -| PASSED | ssrfSink | server/main.go:31:97:31:120 | comment | -failingPositiveTests -passingNegativeTests -| PASSED | !handler | rpc/notes/service.twirp.go:87:109:87:125 | comment | -| PASSED | !handler | rpc/notes/service.twirp.go:116:113:116:129 | comment | -| PASSED | !handler | rpc/notes/service.twirp.go:133:124:133:140 | comment | -| PASSED | !handler | rpc/notes/service.twirp.go:162:128:162:144 | comment | -| PASSED | !handler | rpc/notes/service.twirp.go:226:105:226:121 | comment | -| PASSED | !handler | rpc/notes/service.twirp.go:255:109:255:125 | comment | -| PASSED | !handler | rpc/notes/service.twirp.go:272:120:272:136 | comment | -| PASSED | !handler | rpc/notes/service.twirp.go:301:124:301:140 | comment | -| PASSED | !ssrf | server/main.go:31:97:31:120 | comment | -| PASSED | !ssrfSink | server/main.go:60:51:60:68 | comment | -failingNegativeTests +testFailures diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/tests.ql b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/tests.ql index 5866b6ff3ed..2b445ce4d86 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/tests.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/tests.ql @@ -2,181 +2,76 @@ import go import semmle.go.dataflow.ExternalFlow import ModelValidation import semmle.go.security.RequestForgery +import utils.test.InlineExpectationsTest -class InlineTest extends LineComment { - string tests; - - InlineTest() { tests = this.getText().regexpCapture("\\s*test:(.*)", 1) } - - string getPositiveTest() { - result = tests.trim().splitAt(",").trim() and not result.matches("!%") +module TwirpTest implements TestSig { + string getARelevantTag() { + result = + [ + "handler", "request", "ssrfSink", "message", "serviceInterface", "serviceClient", + "serviceServer", "clientConstructor", "serverConstructor", "ssrf" + ] } - string getNegativeTest() { result = tests.trim().splitAt(",").trim() and result.matches("!%") } - - predicate hasPositiveTest(string test) { test = this.getPositiveTest() } - - predicate hasNegativeTest(string test) { test = this.getNegativeTest() } - - predicate inNode(DataFlow::Node n) { - this.getLocation().getFile() = n.getFile() and - this.getLocation().getStartLine() = n.getStartLine() + additional predicate hasEntityResult(Location location, string element, Entity entity) { + location = entity.getDeclaration().getLocation() and + element = entity.toString() } - predicate inEntity(Entity e) { - this.getLocation().getFile() = e.getDeclaration().getFile() and - this.getLocation().getStartLine() = e.getDeclaration().getLocation().getStartLine() + additional predicate hasTypeResult(Location location, string element, Type goType) { + exists(TypeEntity typeEntity | + typeEntity.getType() = goType and + location = typeEntity.getDeclaration().getLocation() and + element = goType.toString() + ) } - predicate inType(Type t) { - exists(TypeEntity te | - te.getType() = t and - this.getLocation().getFile() = te.getDeclaration().getFile() and - this.getLocation().getStartLine() = te.getDeclaration().getLocation().getStartLine() + predicate hasActualResult(Location location, string element, string tag, string value) { + value = "" and + ( + tag = "handler" and + exists(Twirp::ServiceHandler handler | hasEntityResult(location, element, handler)) + or + tag = "request" and + exists(Twirp::Request request | + location = request.getLocation() and + element = request.toString() + ) + or + tag = "ssrfSink" and + exists(RequestForgery::Sink sink | + location = sink.getLocation() and + element = sink.toString() + ) + or + tag = "message" and + exists(Twirp::ProtobufMessageType message | hasTypeResult(location, element, message)) + or + tag = "serviceInterface" and + exists(Twirp::ServiceInterfaceType serviceInterface | + hasTypeResult(location, element, serviceInterface.getDefinedType()) + ) + or + tag = "serviceClient" and + exists(Twirp::ServiceClientType client | hasTypeResult(location, element, client)) + or + tag = "serviceServer" and + exists(Twirp::ServiceServerType server | hasTypeResult(location, element, server)) + or + tag = "clientConstructor" and + exists(Twirp::ClientConstructor constructor | hasEntityResult(location, element, constructor)) + or + tag = "serverConstructor" and + exists(Twirp::ServerConstructor constructor | hasEntityResult(location, element, constructor)) + or + tag = "ssrf" and + exists(DataFlow::Node sink | + RequestForgery::Flow::flowTo(sink) and + location = sink.getLocation() and + element = sink.toString() + ) ) } } -query predicate passingPositiveTests(string res, string expectation, InlineTest t) { - res = "PASSED" and - t.hasPositiveTest(expectation) and - ( - expectation = "handler" and - exists(Twirp::ServiceHandler n | t.inEntity(n)) - or - expectation = "request" and - exists(Twirp::Request n | t.inNode(n)) - or - expectation = "ssrfSink" and - exists(RequestForgery::Sink n | t.inNode(n)) - or - expectation = "message" and - exists(Twirp::ProtobufMessageType n | t.inType(n)) - or - expectation = "serviceInterface" and - exists(Twirp::ServiceInterfaceType n | t.inType(n.getDefinedType())) - or - expectation = "serviceClient" and - exists(Twirp::ServiceClientType n | t.inType(n)) - or - expectation = "serviceServer" and - exists(Twirp::ServiceServerType n | t.inType(n)) - or - expectation = "clientConstructor" and - exists(Twirp::ClientConstructor n | t.inEntity(n)) - or - expectation = "serverConstructor" and - exists(Twirp::ServerConstructor n | t.inEntity(n)) - or - expectation = "ssrf" and - exists(DataFlow::Node sink | RequestForgery::Flow::flowTo(sink) and t.inNode(sink)) - ) -} - -query predicate failingPositiveTests(string res, string expectation, InlineTest t) { - res = "FAILED" and - t.hasPositiveTest(expectation) and - ( - expectation = "handler" and - not exists(Twirp::ServiceHandler n | t.inEntity(n)) - or - expectation = "request" and - not exists(Twirp::Request n | t.inNode(n)) - or - expectation = "ssrfSink" and - not exists(RequestForgery::Sink n | t.inNode(n)) - or - expectation = "message" and - not exists(Twirp::ProtobufMessageType n | t.inType(n)) - or - expectation = "serviceInterface" and - not exists(Twirp::ServiceInterfaceType n | t.inType(n.getDefinedType())) - or - expectation = "serviceClient" and - not exists(Twirp::ServiceClientType n | t.inType(n)) - or - expectation = "serviceServer" and - not exists(Twirp::ServiceServerType n | t.inType(n)) - or - expectation = "clientConstructor" and - not exists(Twirp::ClientConstructor n | t.inEntity(n)) - or - expectation = "serverConstructor" and - not exists(Twirp::ServerConstructor n | t.inEntity(n)) - or - expectation = "ssrf" and - not exists(DataFlow::Node sink | RequestForgery::Flow::flowTo(sink) and t.inNode(sink)) - ) -} - -query predicate passingNegativeTests(string res, string expectation, InlineTest t) { - res = "PASSED" and - t.hasNegativeTest(expectation) and - ( - expectation = "!handler" and - not exists(Twirp::ServiceHandler n | t.inEntity(n)) - or - expectation = "!request" and - not exists(Twirp::Request n | t.inNode(n)) - or - expectation = "!ssrfSink" and - not exists(RequestForgery::Sink n | t.inNode(n)) - or - expectation = "!message" and - not exists(Twirp::ProtobufMessageType n | t.inType(n)) - or - expectation = "!serviceInterface" and - not exists(Twirp::ServiceInterfaceType n | t.inType(n)) - or - expectation = "!serviceClient" and - not exists(Twirp::ServiceClientType n | t.inType(n)) - or - expectation = "!serviceServer" and - not exists(Twirp::ServiceServerType n | t.inType(n)) - or - expectation = "!clientConstructor" and - not exists(Twirp::ClientConstructor n | t.inEntity(n)) - or - expectation = "!serverConstructor" and - not exists(Twirp::ServerConstructor n | t.inEntity(n)) - or - expectation = "!ssrf" and - not exists(DataFlow::Node sink | RequestForgery::Flow::flowTo(sink) and t.inNode(sink)) - ) -} - -query predicate failingNegativeTests(string res, string expectation, InlineTest t) { - res = "FAILED" and - t.hasNegativeTest(expectation) and - ( - expectation = "!handler" and - exists(Twirp::ServiceHandler n | t.inEntity(n)) - or - expectation = "!request" and - exists(Twirp::Request n | t.inNode(n)) - or - expectation = "!ssrfSink" and - exists(RequestForgery::Sink n | t.inNode(n)) - or - expectation = "!message" and - exists(Twirp::ProtobufMessageType n | t.inType(n)) - or - expectation = "!serviceInterface" and - exists(Twirp::ServiceInterfaceType n | t.inType(n)) - or - expectation = "!serviceClient" and - exists(Twirp::ServiceClientType n | t.inType(n)) - or - expectation = "!serviceServer" and - exists(Twirp::ServiceServerType n | t.inType(n)) - or - expectation = "!clientConstructor" and - exists(Twirp::ClientConstructor n | t.inEntity(n)) - or - expectation = "!serverConstructor" and - exists(Twirp::ServerConstructor n | t.inEntity(n)) - or - expectation = "!ssrf" and - exists(DataFlow::Node sink | RequestForgery::Flow::flowTo(sink) and t.inNode(sink)) - ) -} +import MakeTest From 6a8e20a0c87d3e8cc027db59db5afd985e48d74a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 10 Jun 2026 07:12:08 +0200 Subject: [PATCH 225/226] Fix pre-existing whitespace issues in go test files --- .../WhitespaceContradictsPrecedence/main.go | 2 +- .../Security/CWE-089/StringBreak.expected | 40 +++++++++---------- .../Security/CWE-089/StringBreak.go | 1 + .../Security/CWE-089/StringBreakMismatched.go | 3 +- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/go/ql/test/query-tests/InconsistentCode/WhitespaceContradictsPrecedence/main.go b/go/ql/test/query-tests/InconsistentCode/WhitespaceContradictsPrecedence/main.go index faf23f9f1cf..dc1bf222aec 100644 --- a/go/ql/test/query-tests/InconsistentCode/WhitespaceContradictsPrecedence/main.go +++ b/go/ql/test/query-tests/InconsistentCode/WhitespaceContradictsPrecedence/main.go @@ -21,7 +21,7 @@ func ok3(x int) int { func ok4(x int, y int, z int) int { return x + y + z; } - + func ok5(x int, y int, z int) int { return x + y+z; } diff --git a/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected b/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected index 5deab249337..63caa73d596 100644 --- a/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected +++ b/go/ql/test/query-tests/Security/CWE-089/StringBreak.expected @@ -1,26 +1,26 @@ #select -| StringBreak.go:14:47:14:57 | versionJSON | StringBreak.go:10:2:10:40 | ... := ...[0] | StringBreak.go:14:47:14:57 | versionJSON | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreak.go:10:2:10:40 | ... := ...[0] | JSON value | -| StringBreakMismatched.go:17:26:17:32 | escaped | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | StringBreakMismatched.go:17:26:17:32 | escaped | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | JSON value | -| StringBreakMismatched.go:29:27:29:33 | escaped | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | StringBreakMismatched.go:29:27:29:33 | escaped | If this $@ contains a double quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | JSON value | +| StringBreak.go:15:47:15:57 | versionJSON | StringBreak.go:11:2:11:40 | ... := ...[0] | StringBreak.go:15:47:15:57 | versionJSON | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreak.go:11:2:11:40 | ... := ...[0] | JSON value | +| StringBreakMismatched.go:18:26:18:32 | escaped | StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | StringBreakMismatched.go:18:26:18:32 | escaped | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | JSON value | +| StringBreakMismatched.go:30:27:30:33 | escaped | StringBreakMismatched.go:25:2:25:40 | ... := ...[0] | StringBreakMismatched.go:30:27:30:33 | escaped | If this $@ contains a double quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:25:2:25:40 | ... := ...[0] | JSON value | edges -| StringBreak.go:10:2:10:40 | ... := ...[0] | StringBreak.go:14:47:14:57 | versionJSON | provenance | | -| StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | StringBreakMismatched.go:13:29:13:47 | type conversion | provenance | | -| StringBreakMismatched.go:13:13:13:62 | call to Replace | StringBreakMismatched.go:17:26:17:32 | escaped | provenance | | -| StringBreakMismatched.go:13:29:13:47 | type conversion | StringBreakMismatched.go:13:13:13:62 | call to Replace | provenance | MaD:1 | -| StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | StringBreakMismatched.go:25:29:25:47 | type conversion | provenance | | -| StringBreakMismatched.go:25:13:25:61 | call to Replace | StringBreakMismatched.go:29:27:29:33 | escaped | provenance | | -| StringBreakMismatched.go:25:29:25:47 | type conversion | StringBreakMismatched.go:25:13:25:61 | call to Replace | provenance | MaD:1 | +| StringBreak.go:11:2:11:40 | ... := ...[0] | StringBreak.go:15:47:15:57 | versionJSON | provenance | | +| StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | StringBreakMismatched.go:14:29:14:47 | type conversion | provenance | | +| StringBreakMismatched.go:14:13:14:62 | call to Replace | StringBreakMismatched.go:18:26:18:32 | escaped | provenance | | +| StringBreakMismatched.go:14:29:14:47 | type conversion | StringBreakMismatched.go:14:13:14:62 | call to Replace | provenance | MaD:1 | +| StringBreakMismatched.go:25:2:25:40 | ... := ...[0] | StringBreakMismatched.go:26:29:26:47 | type conversion | provenance | | +| StringBreakMismatched.go:26:13:26:61 | call to Replace | StringBreakMismatched.go:30:27:30:33 | escaped | provenance | | +| StringBreakMismatched.go:26:29:26:47 | type conversion | StringBreakMismatched.go:26:13:26:61 | call to Replace | provenance | MaD:1 | models | 1 | Summary: strings; ; false; Replace; ; ; Argument[0]; ReturnValue; taint; manual | nodes -| StringBreak.go:10:2:10:40 | ... := ...[0] | semmle.label | ... := ...[0] | -| StringBreak.go:14:47:14:57 | versionJSON | semmle.label | versionJSON | -| StringBreakMismatched.go:12:2:12:40 | ... := ...[0] | semmle.label | ... := ...[0] | -| StringBreakMismatched.go:13:13:13:62 | call to Replace | semmle.label | call to Replace | -| StringBreakMismatched.go:13:29:13:47 | type conversion | semmle.label | type conversion | -| StringBreakMismatched.go:17:26:17:32 | escaped | semmle.label | escaped | -| StringBreakMismatched.go:24:2:24:40 | ... := ...[0] | semmle.label | ... := ...[0] | -| StringBreakMismatched.go:25:13:25:61 | call to Replace | semmle.label | call to Replace | -| StringBreakMismatched.go:25:29:25:47 | type conversion | semmle.label | type conversion | -| StringBreakMismatched.go:29:27:29:33 | escaped | semmle.label | escaped | +| StringBreak.go:11:2:11:40 | ... := ...[0] | semmle.label | ... := ...[0] | +| StringBreak.go:15:47:15:57 | versionJSON | semmle.label | versionJSON | +| StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | semmle.label | ... := ...[0] | +| StringBreakMismatched.go:14:13:14:62 | call to Replace | semmle.label | call to Replace | +| StringBreakMismatched.go:14:29:14:47 | type conversion | semmle.label | type conversion | +| StringBreakMismatched.go:18:26:18:32 | escaped | semmle.label | escaped | +| StringBreakMismatched.go:25:2:25:40 | ... := ...[0] | semmle.label | ... := ...[0] | +| StringBreakMismatched.go:26:13:26:61 | call to Replace | semmle.label | call to Replace | +| StringBreakMismatched.go:26:29:26:47 | type conversion | semmle.label | type conversion | +| StringBreakMismatched.go:30:27:30:33 | escaped | semmle.label | escaped | subpaths diff --git a/go/ql/test/query-tests/Security/CWE-089/StringBreak.go b/go/ql/test/query-tests/Security/CWE-089/StringBreak.go index d5aec9777d4..5667ca35035 100644 --- a/go/ql/test/query-tests/Security/CWE-089/StringBreak.go +++ b/go/ql/test/query-tests/Security/CWE-089/StringBreak.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + sq "github.com/Masterminds/squirrel" ) diff --git a/go/ql/test/query-tests/Security/CWE-089/StringBreakMismatched.go b/go/ql/test/query-tests/Security/CWE-089/StringBreakMismatched.go index ba8ee72d0fa..c838d5f6b7d 100644 --- a/go/ql/test/query-tests/Security/CWE-089/StringBreakMismatched.go +++ b/go/ql/test/query-tests/Security/CWE-089/StringBreakMismatched.go @@ -2,8 +2,9 @@ package main import ( "encoding/json" - sq "github.com/Masterminds/squirrel" "strings" + + sq "github.com/Masterminds/squirrel" ) // Bad because quote characters are removed before concatenation, From b4a9689341383f94ec8979d381e59ec7d460e849 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 10 Jun 2026 06:43:10 +0200 Subject: [PATCH 226/226] Convert .qlref test to inline expectations --- .../experimental/CWE-525/WebCacheDeception.ql | 2 +- .../experimental/CWE-090/LDAPInjection.go | 24 +-- .../experimental/CWE-090/LDAPInjection.qlref | 4 +- go/ql/test/experimental/CWE-203/Timing.qlref | 4 +- go/ql/test/experimental/CWE-203/timing.go | 12 +- .../experimental/CWE-285/PamAuthBypass.qlref | 3 +- go/ql/test/experimental/CWE-285/main.go | 2 +- .../experimental/CWE-287/ImproperLdapAuth.go | 8 +- .../CWE-287/ImproperLdapAuth.qlref | 4 +- .../CWE-321-V2/HardCodedKeys.expected | 6 +- .../CWE-321-V2/HardCodedKeys.qlref | 3 +- .../experimental/CWE-321-V2/go-jose.v3.go | 4 +- .../experimental/CWE-321-V2/golang-jwt-v5.go | 4 +- .../test/experimental/CWE-369/DivideByZero.go | 24 +-- .../experimental/CWE-369/DivideByZero.qlref | 4 +- .../CWE-400/DatabaseCallInLoop.expected | 8 +- .../CWE-400/DatabaseCallInLoop.go | 4 +- .../CWE-400/DatabaseCallInLoop.qlref | 3 +- go/ql/test/experimental/CWE-400/test.go | 6 +- .../DecompressionBombs.qlref | 4 +- .../CWE-522-DecompressionBombs/test.go | 104 +++++------ .../CWE-525/WebCacheDeception.qlref | 3 +- .../CWE-525/WebCacheDeceptionBad.go | 2 +- .../CWE-525/WebCacheDeceptionFiber.go | 4 +- .../CWE-525/WebCacheDeceptionGoChi.go | 2 +- .../CWE-525/WebCacheDeceptionHTTPRouter.go | 2 +- go/ql/test/experimental/CWE-74/Dsn.go | 12 +- .../experimental/CWE-74/DsnInjection.qlref | 4 +- .../CWE-74/DsnInjectionLocal.qlref | 4 +- .../CWE-807/SensitiveConditionBypass.qlref | 3 +- .../CWE-807/SensitiveConditionBypassBad.go | 2 +- go/ql/test/experimental/CWE-807/condition.go | 6 +- .../CWE-840/ConditionalBypass.qlref | 3 +- .../CWE-840/ConditionalBypassBad.go | 2 +- go/ql/test/experimental/CWE-840/condition.go | 4 +- .../InconsistentCode/DeferInLoop.go | 2 +- .../InconsistentCode/DeferInLoop.qlref | 3 +- .../InconsistentCode/GORMErrorNotChecked.go | 2 +- .../GORMErrorNotChecked.qlref | 3 +- .../experimental/InconsistentCode/test.go | 10 +- .../Unsafe/WrongUsageOfUnsafe.expected | 24 +-- .../experimental/Unsafe/WrongUsageOfUnsafe.go | 24 +-- .../Unsafe/WrongUsageOfUnsafe.qlref | 3 +- .../go/frameworks/BeegoOrm/SqlInjection.qlref | 4 +- .../go/frameworks/BeegoOrm/StoredXss.qlref | 4 +- .../semmle/go/frameworks/BeegoOrm/test.go | 164 +++++++++--------- .../go/frameworks/Chi/ReflectedXss.qlref | 4 +- .../semmle/go/frameworks/Chi/test.go | 10 +- .../go/frameworks/Echo/OpenRedirect.qlref | 4 +- .../go/frameworks/Echo/ReflectedXss.qlref | 4 +- .../go/frameworks/Echo/TaintedPath.qlref | 4 +- .../semmle/go/frameworks/Echo/test.go | 92 +++++----- .../frameworks/GoMicro/LogInjection.expected | 4 +- .../go/frameworks/GoMicro/LogInjection.qlref | 3 +- .../semmle/go/frameworks/GoMicro/main.go | 4 +- .../CONSISTENCY/DataFlowConsistency.expected | 48 ++--- .../semmle/go/frameworks/Revel/EndToEnd.go | 17 +- .../go/frameworks/Revel/OpenRedirect.expected | 24 +-- .../go/frameworks/Revel/OpenRedirect.qlref | 4 +- .../go/frameworks/Revel/ReflectedXss.expected | 32 ++-- .../go/frameworks/Revel/ReflectedXss.qlref | 4 +- .../semmle/go/frameworks/Revel/Revel.go | 2 +- .../go/frameworks/Revel/TaintedPath.expected | 24 +-- .../go/frameworks/Revel/TaintedPath.qlref | 4 +- .../Revel/examples/booking/app/init.go | 4 +- .../go/frameworks/XNetHtml/ReflectedXss.qlref | 4 +- .../go/frameworks/XNetHtml/SqlInjection.qlref | 4 +- .../semmle/go/frameworks/XNetHtml/test.go | 50 +++--- .../ConstantLengthComparison.go | 2 +- .../ConstantLengthComparison.qlref | 3 +- .../InconsistentLoopOrientation.go | 2 +- .../InconsistentLoopOrientation.qlref | 3 +- .../InconsistentLoopOrientation/main.go | 6 +- .../LengthComparisonOffByOne.go | 4 +- .../LengthComparisonOffByOne.qlref | 3 +- .../LengthComparisonOffByOne/main.go | 8 +- .../MissingErrorCheck/MissingErrorCheck.qlref | 3 +- .../MissingErrorCheck/tests.go | 4 +- .../MistypedExponentiation.go | 2 +- .../MistypedExponentiation.qlref | 3 +- .../MistypedExponentiation/main.go | 10 +- .../WhitespaceContradictsPrecedence.go | 2 +- .../WhitespaceContradictsPrecedence.qlref | 3 +- .../WhitespaceContradictsPrecedence/main.go | 2 +- .../WrappedErrorAlwaysNil.go | 8 +- .../WrappedErrorAlwaysNil.qlref | 3 +- .../CompareIdenticalValues.go | 2 +- .../CompareIdenticalValues.qlref | 3 +- .../CompareIdenticalValues/tst.go | 4 +- .../CompareIdenticalValues/vp.go | 2 +- .../DeadStoreOfField/DeadStoreOfField.go | 2 +- .../DeadStoreOfField/DeadStoreOfField.qlref | 3 +- .../DeadStoreOfLocal/DeadStoreOfLocal.qlref | 3 +- .../RedundantCode/DeadStoreOfLocal/main.go | 2 +- .../DeadStoreOfLocal/testdata.go | 58 +++---- .../DuplicateBranches/DuplicateBranches.go | 2 +- .../DuplicateBranches/DuplicateBranches.qlref | 3 +- .../RedundantCode/DuplicateBranches/main.go | 2 +- .../DuplicateCondition/DuplicateCondition.go | 4 +- .../DuplicateCondition.qlref | 3 +- .../RedundantCode/DuplicateCondition/tst.go | 4 +- .../DuplicateSwitchCase.go | 2 +- .../DuplicateSwitchCase.qlref | 3 +- .../RedundantCode/DuplicateSwitchCase/tst.go | 2 +- .../ExprHasNoEffect/ExprHasNoEffect.go | 2 +- .../ExprHasNoEffect/ExprHasNoEffect.qlref | 3 +- .../RedundantCode/ExprHasNoEffect/main.go | 6 +- .../ImpossibleInterfaceNilCheck.go | 2 +- .../ImpossibleInterfaceNilCheck.qlref | 3 +- .../ImpossibleInterfaceNilCheck/tst.go | 2 +- .../NegativeLengthCheck.go | 2 +- .../NegativeLengthCheck.qlref | 3 +- .../RedundantCode/NegativeLengthCheck/main.go | 10 +- .../RedundantExpr/RedundantExpr.go | 2 +- .../RedundantExpr/RedundantExpr.qlref | 3 +- .../RedundantCode/RedundantExpr/tst.go | 4 +- .../RedundantRecover/RedundantRecover.qlref | 3 +- .../RedundantRecover/RedundantRecover1.go | 2 +- .../RedundantRecover/RedundantRecover2.go | 2 +- .../RedundantCode/RedundantRecover/tst.go | 2 +- .../SelfAssignment/SelfAssignment.go | 2 +- .../SelfAssignment/SelfAssignment.qlref | 3 +- .../RedundantCode/SelfAssignment/tst.go | 2 +- .../ShiftOutOfRange/ShiftOutOfRange.go | 2 +- .../ShiftOutOfRange/ShiftOutOfRange.qlref | 3 +- .../RedundantCode/ShiftOutOfRange/main.go | 6 +- .../UnreachableStatement.go | 2 +- .../UnreachableStatement.qlref | 3 +- .../UnreachableStatement/main.go | 22 +-- .../IncompleteHostnameRegexp.go | 4 +- .../IncompleteHostnameRegexp.qlref | 4 +- .../CWE-020/IncompleteHostnameRegexp/main.go | 14 +- .../IncompleteUrlSchemeCheck.go | 2 +- .../IncompleteUrlSchemeCheck.qlref | 3 +- .../CWE-020/IncompleteUrlSchemeCheck/main.go | 2 +- .../MissingRegexpAnchor.go | 2 +- .../MissingRegexpAnchor.qlref | 3 +- .../CWE-020/MissingRegexpAnchor/main.go | 20 +-- .../SuspiciousCharacterInRegexp.go | 2 +- .../SuspiciousCharacterInRegexp.qlref | 3 +- .../SuspiciousCharacterInRegexp/test.go | 20 +-- .../GorillaMuxDefault/TaintedPath.qlref | 4 +- .../CWE-022/GorillaMuxSkipClean/MuxClean.go | 4 +- .../GorillaMuxSkipClean/TaintedPath.qlref | 4 +- .../Security/CWE-022/TaintedPath.go | 8 +- .../Security/CWE-022/TaintedPath.qlref | 4 +- .../Security/CWE-022/UnsafeUnzipSymlink.go | 8 +- .../Security/CWE-022/UnsafeUnzipSymlink.qlref | 4 +- .../CWE-022/UnsafeUnzipSymlinkGood.go | 4 +- .../query-tests/Security/CWE-022/ZipSlip.go | 4 +- .../Security/CWE-022/ZipSlip.qlref | 4 +- .../query-tests/Security/CWE-022/tarslip.go | 4 +- .../test/query-tests/Security/CWE-022/tst.go | 4 +- .../Security/CWE-078/ArgumentInjection.go | 4 +- .../Security/CWE-078/CommandInjection.go | 4 +- .../Security/CWE-078/CommandInjection.qlref | 4 +- .../Security/CWE-078/CommandInjection2.go | 8 +- .../Security/CWE-078/GitSubcommands.go | 16 +- .../Security/CWE-078/SanitizingDoubleDash.go | 36 ++-- .../Security/CWE-078/StoredCommand.go | 4 +- .../Security/CWE-078/StoredCommand.qlref | 4 +- .../Security/CWE-089/SqlInjection.go | 4 +- .../Security/CWE-089/SqlInjection.qlref | 4 +- .../Security/CWE-089/StringBreak.go | 4 +- .../Security/CWE-089/StringBreak.qlref | 4 +- .../Security/CWE-089/StringBreakMismatched.go | 8 +- .../query-tests/Security/CWE-089/issue48.go | 12 +- .../test/query-tests/Security/CWE-089/main.go | 22 +-- .../query-tests/Security/CWE-089/mongoDB.go | 30 ++-- .../CWE-190/AllocationSizeOverflow.go | 4 +- .../CWE-190/AllocationSizeOverflow.qlref | 4 +- .../test/query-tests/Security/CWE-190/tst.go | 16 +- .../test/query-tests/Security/CWE-190/tst2.go | 8 +- .../test/query-tests/Security/CWE-190/tst3.go | 8 +- .../Security/CWE-209/StackTraceExposure.qlref | 3 +- .../test/query-tests/Security/CWE-209/test.go | 4 +- .../DisabledCertificateCheck.go | 2 +- .../DisabledCertificateCheck.qlref | 3 +- .../CWE-295/DisabledCertificateCheck/main.go | 6 +- .../CWE-322/InsecureHostKeyCallback.expected | 10 +- .../CWE-322/InsecureHostKeyCallback.qlref | 3 +- .../CWE-322/InsecureHostKeyCallbackExample.go | 12 +- .../Security/CWE-326/InsufficientKeySize.go | 22 +-- .../CWE-326/InsufficientKeySize.qlref | 3 +- .../query-tests/Security/CWE-327/UnsafeTLS.go | 94 +++++----- .../Security/CWE-327/UnsafeTLS.qlref | 4 +- .../InsecureRandomness/InsecureRandomness.go | 2 +- .../InsecureRandomness.qlref | 4 +- .../CWE-338/InsecureRandomness/sample.go | 14 +- .../CWE-347/MissingJwtSignatureCheck.qlref | 4 +- .../Security/CWE-347/go-jose.v3.go | 4 +- .../Security/CWE-347/golang-jwt-v5.go | 4 +- .../Security/CWE-352/ConstantOauth2State.go | 16 +- .../CWE-352/ConstantOauth2State.qlref | 3 +- .../BadRedirectCheck/BadRedirectCheck.go | 4 +- .../BadRedirectCheck/BadRedirectCheck.qlref | 4 +- .../Security/CWE-601/BadRedirectCheck/cves.go | 18 +- .../Security/CWE-601/BadRedirectCheck/main.go | 24 +-- .../Security/CWE-643/XPathInjection.go | 4 +- .../Security/CWE-643/XPathInjection.qlref | 4 +- .../test/query-tests/Security/CWE-643/tst.go | 90 +++++----- .../CWE-798/AlertSuppressionExample.go | 2 +- .../Security/CWE-798/HardcodedCredentials.go | 2 +- .../Security/CWE-798/HardcodedKeysBad.go | 2 +- .../test/query-tests/Security/CWE-798/jwt.go | 38 ++-- .../test/query-tests/Security/CWE-798/main.go | 2 +- .../query-tests/Security/CWE-798/sanitizer.go | 2 +- 207 files changed, 1009 insertions(+), 901 deletions(-) diff --git a/go/ql/src/experimental/CWE-525/WebCacheDeception.ql b/go/ql/src/experimental/CWE-525/WebCacheDeception.ql index eb488b0b0d1..04faa7c29e1 100644 --- a/go/ql/src/experimental/CWE-525/WebCacheDeception.ql +++ b/go/ql/src/experimental/CWE-525/WebCacheDeception.ql @@ -1,4 +1,4 @@ -/* +/** * @name Web Cache Deception * @description A caching system has been detected on the application and is vulnerable to web cache deception. By manipulating the URL it is possible to force the application to cache pages that are only accessible by an authenticated user. Once cached, these pages can be accessed by an unauthenticated user. * @kind problem diff --git a/go/ql/test/experimental/CWE-090/LDAPInjection.go b/go/ql/test/experimental/CWE-090/LDAPInjection.go index 87741a08d28..0acae7c0617 100644 --- a/go/ql/test/experimental/CWE-090/LDAPInjection.go +++ b/go/ql/test/experimental/CWE-090/LDAPInjection.go @@ -54,31 +54,31 @@ func main() {} // bad is an example of a bad implementation func (ld *Ldap) bad(req *http.Request) { // ... - untrusted := req.UserAgent() + untrusted := req.UserAgent() // $ Source goldap.NewSearchRequest( - untrusted, // BAD: untrusted dn + untrusted, // $ Alert // BAD: untrusted dn goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false, - "(&(objectClass=organizationalPerson))"+untrusted, // BAD: untrusted filter - []string{"dn", "cn", untrusted}, // BAD: untrusted attribute + "(&(objectClass=organizationalPerson))"+untrusted, // $ Alert // BAD: untrusted filter + []string{"dn", "cn", untrusted}, // $ Alert // BAD: untrusted attribute nil, ) goldapv3.NewSearchRequest( - untrusted, // BAD: untrusted dn + untrusted, // $ Alert // BAD: untrusted dn goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false, - "(&(objectClass=organizationalPerson))"+untrusted, // BAD: untrusted filter - []string{"dn", "cn", untrusted}, // BAD: untrusted attribute + "(&(objectClass=organizationalPerson))"+untrusted, // $ Alert // BAD: untrusted filter + []string{"dn", "cn", untrusted}, // $ Alert // BAD: untrusted attribute nil, ) gopkgldapv2.NewSearchRequest( - untrusted, // BAD: untrusted dn + untrusted, // $ Alert // BAD: untrusted dn goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false, - "(&(objectClass=organizationalPerson))"+untrusted, // BAD: untrusted filter - []string{"dn", "cn", untrusted}, // BAD: untrusted attribute + "(&(objectClass=organizationalPerson))"+untrusted, // $ Alert // BAD: untrusted filter + []string{"dn", "cn", untrusted}, // $ Alert // BAD: untrusted attribute nil, ) client := &ldapclient.LDAPClient{} - client.Authenticate(untrusted, "123456") // BAD: untrusted filter - client.GetGroupsOfUser(untrusted) // BAD: untrusted filter + client.Authenticate(untrusted, "123456") // $ Alert // BAD: untrusted filter + client.GetGroupsOfUser(untrusted) // $ Alert // BAD: untrusted filter // ... } diff --git a/go/ql/test/experimental/CWE-090/LDAPInjection.qlref b/go/ql/test/experimental/CWE-090/LDAPInjection.qlref index 7049e09a726..45935a174c4 100644 --- a/go/ql/test/experimental/CWE-090/LDAPInjection.qlref +++ b/go/ql/test/experimental/CWE-090/LDAPInjection.qlref @@ -1,2 +1,4 @@ query: experimental/CWE-090/LDAPInjection.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-203/Timing.qlref b/go/ql/test/experimental/CWE-203/Timing.qlref index 7306096e724..e14641beccf 100644 --- a/go/ql/test/experimental/CWE-203/Timing.qlref +++ b/go/ql/test/experimental/CWE-203/Timing.qlref @@ -1,2 +1,4 @@ query: experimental/CWE-203/Timing.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-203/timing.go b/go/ql/test/experimental/CWE-203/timing.go index 43401bd4111..32543e367b6 100644 --- a/go/ql/test/experimental/CWE-203/timing.go +++ b/go/ql/test/experimental/CWE-203/timing.go @@ -12,9 +12,9 @@ func bad(w http.ResponseWriter, req *http.Request) (interface{}, error) { secret := "MySuperSecretPasscode" secretHeader := "X-Secret" - headerSecret := req.Header.Get(secretHeader) + headerSecret := req.Header.Get(secretHeader) // $ Source secretStr := string(secret) - if len(headerSecret) != 0 && headerSecret != secretStr { + if len(headerSecret) != 0 && headerSecret != secretStr { // $ Alert return nil, fmt.Errorf("header %s=%s did not match expected secret", secretHeader, headerSecret) } return nil, nil @@ -25,9 +25,9 @@ func bad2(w http.ResponseWriter, req *http.Request) (interface{}, error) { secret := "MySuperSecretPasscode" secretHeader := "X-Secret" - headerSecret := req.Header.Get(secretHeader) + headerSecret := req.Header.Get(secretHeader) // $ Source secretStr := string(secret) - if len(headerSecret) != 0 && strings.Compare(headerSecret, secretStr) != 0 { + if len(headerSecret) != 0 && strings.Compare(headerSecret, secretStr) != 0 { // $ Alert return nil, fmt.Errorf("header %s=%s did not match expected secret", secretHeader, headerSecret) } return nil, nil @@ -38,8 +38,8 @@ func bad4(w http.ResponseWriter, req *http.Request) (interface{}, error) { secret := "MySuperSecretPasscode" secretHeader := "X-Secret" - headerSecret := req.Header.Get(secretHeader) - if len(secret) != 0 && headerSecret != "SecretStringLiteral" { + headerSecret := req.Header.Get(secretHeader) // $ Source + if len(secret) != 0 && headerSecret != "SecretStringLiteral" { // $ Alert return nil, fmt.Errorf("header %s=%s did not match expected secret", secretHeader, headerSecret) } return nil, nil diff --git a/go/ql/test/experimental/CWE-285/PamAuthBypass.qlref b/go/ql/test/experimental/CWE-285/PamAuthBypass.qlref index 8a1d5b259e0..85ba5b1005d 100644 --- a/go/ql/test/experimental/CWE-285/PamAuthBypass.qlref +++ b/go/ql/test/experimental/CWE-285/PamAuthBypass.qlref @@ -1 +1,2 @@ -experimental/CWE-285/PamAuthBypass.ql \ No newline at end of file +query: experimental/CWE-285/PamAuthBypass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-285/main.go b/go/ql/test/experimental/CWE-285/main.go index b0607a74a41..352a57bb699 100644 --- a/go/ql/test/experimental/CWE-285/main.go +++ b/go/ql/test/experimental/CWE-285/main.go @@ -9,7 +9,7 @@ import ( func bad() error { t, _ := pam.StartFunc("", "", func(s pam.Style, msg string) (string, error) { return "", nil - }) + }) // $ Alert return t.Authenticate(0) } diff --git a/go/ql/test/experimental/CWE-287/ImproperLdapAuth.go b/go/ql/test/experimental/CWE-287/ImproperLdapAuth.go index b4e7b796b90..6e2f7d44033 100644 --- a/go/ql/test/experimental/CWE-287/ImproperLdapAuth.go +++ b/go/ql/test/experimental/CWE-287/ImproperLdapAuth.go @@ -15,7 +15,7 @@ func bad(w http.ResponseWriter, req *http.Request) (interface{}, error) { ldapServer := "ldap.example.com" ldapPort := 389 bindDN := "cn=admin,dc=example,dc=com" - bindPassword := req.URL.Query()["password"][0] + bindPassword := req.URL.Query()["password"][0] // $ Source // Connect to the LDAP server l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) @@ -25,7 +25,7 @@ func bad(w http.ResponseWriter, req *http.Request) (interface{}, error) { defer l.Close() // BAD: user input is not sanetized - err = l.Bind(bindDN, bindPassword) + err = l.Bind(bindDN, bindPassword) // $ Alert if err != nil { return fmt.Errorf("LDAP bind failed: %v", err), err } @@ -84,7 +84,7 @@ func bad2(req *http.Request) { ldapPort := 389 bindDN := "cn=admin,dc=example,dc=com" // BAD : empty password - bindPassword := "" + bindPassword := "" // $ Source // Connect to the LDAP server l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) @@ -94,7 +94,7 @@ func bad2(req *http.Request) { defer l.Close() // BAD : bindPassword is empty - err = l.Bind(bindDN, bindPassword) + err = l.Bind(bindDN, bindPassword) // $ Alert if err != nil { log.Fatalf("LDAP bind failed: %v", err) } diff --git a/go/ql/test/experimental/CWE-287/ImproperLdapAuth.qlref b/go/ql/test/experimental/CWE-287/ImproperLdapAuth.qlref index 35ca7800cc8..409b5b3347d 100644 --- a/go/ql/test/experimental/CWE-287/ImproperLdapAuth.qlref +++ b/go/ql/test/experimental/CWE-287/ImproperLdapAuth.qlref @@ -1,2 +1,4 @@ query: experimental/CWE-287/ImproperLdapAuth.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.expected b/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.expected index 5b26a2a9b36..0cad327e641 100644 --- a/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.expected +++ b/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.expected @@ -1,3 +1,6 @@ +#select +| go-jose.v3.go:24:32:24:37 | JwtKey | go-jose.v3.go:13:21:13:33 | "AllYourBase" | go-jose.v3.go:24:32:24:37 | JwtKey | This $@. | go-jose.v3.go:13:21:13:33 | "AllYourBase" | Constant Key is used as JWT Secret key | +| golang-jwt-v5.go:27:9:27:15 | JwtKey1 | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | golang-jwt-v5.go:27:9:27:15 | JwtKey1 | This $@. | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | Constant Key is used as JWT Secret key | edges | go-jose.v3.go:13:14:13:34 | type conversion | go-jose.v3.go:24:32:24:37 | JwtKey | provenance | | | go-jose.v3.go:13:21:13:33 | "AllYourBase" | go-jose.v3.go:13:14:13:34 | type conversion | provenance | | @@ -11,6 +14,3 @@ nodes | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | semmle.label | "AllYourBase" | | golang-jwt-v5.go:27:9:27:15 | JwtKey1 | semmle.label | JwtKey1 | subpaths -#select -| go-jose.v3.go:24:32:24:37 | JwtKey | go-jose.v3.go:13:21:13:33 | "AllYourBase" | go-jose.v3.go:24:32:24:37 | JwtKey | This $@. | go-jose.v3.go:13:21:13:33 | "AllYourBase" | Constant Key is used as JWT Secret key | -| golang-jwt-v5.go:27:9:27:15 | JwtKey1 | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | golang-jwt-v5.go:27:9:27:15 | JwtKey1 | This $@. | golang-jwt-v5.go:19:22:19:34 | "AllYourBase" | Constant Key is used as JWT Secret key | diff --git a/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.qlref b/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.qlref index e6cee546420..63827b14d7a 100644 --- a/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.qlref +++ b/go/ql/test/experimental/CWE-321-V2/HardCodedKeys.qlref @@ -1 +1,2 @@ -experimental/CWE-321-V2/HardCodedKeys.ql \ No newline at end of file +query: experimental/CWE-321-V2/HardCodedKeys.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-321-V2/go-jose.v3.go b/go/ql/test/experimental/CWE-321-V2/go-jose.v3.go index e25624bb680..c9d103710ba 100644 --- a/go/ql/test/experimental/CWE-321-V2/go-jose.v3.go +++ b/go/ql/test/experimental/CWE-321-V2/go-jose.v3.go @@ -10,7 +10,7 @@ import ( ) // NOT OK -var JwtKey = []byte("AllYourBase") +var JwtKey = []byte("AllYourBase") // $ Source func main2(r *http.Request) { signedToken := r.URL.Query().Get("signedToken") @@ -21,7 +21,7 @@ func verifyJWT(signedToken string) { fmt.Println("verifying JWT") DecodedToken, _ := jwt.ParseSigned(signedToken) out := CustomerInfo{} - if err := DecodedToken.Claims(JwtKey, &out); err != nil { + if err := DecodedToken.Claims(JwtKey, &out); err != nil { // $ Alert panic(err) } fmt.Printf("%v\n", out) diff --git a/go/ql/test/experimental/CWE-321-V2/golang-jwt-v5.go b/go/ql/test/experimental/CWE-321-V2/golang-jwt-v5.go index 71917160bda..166c8e6454e 100644 --- a/go/ql/test/experimental/CWE-321-V2/golang-jwt-v5.go +++ b/go/ql/test/experimental/CWE-321-V2/golang-jwt-v5.go @@ -16,7 +16,7 @@ type CustomerInfo struct { } // BAD constant key -var JwtKey1 = []byte("AllYourBase") +var JwtKey1 = []byte("AllYourBase") // $ Source func main1(r *http.Request) { signedToken := r.URL.Query().Get("signedToken") @@ -24,7 +24,7 @@ func main1(r *http.Request) { } func LoadJwtKey(token *jwt.Token) (interface{}, error) { - return JwtKey1, nil + return JwtKey1, nil // $ Alert } func verifyJWT_golangjwt(signedToken string) { diff --git a/go/ql/test/experimental/CWE-369/DivideByZero.go b/go/ql/test/experimental/CWE-369/DivideByZero.go index 613479981b1..75588a18b45 100644 --- a/go/ql/test/experimental/CWE-369/DivideByZero.go +++ b/go/ql/test/experimental/CWE-369/DivideByZero.go @@ -7,37 +7,37 @@ import ( ) func myHandler1(w http.ResponseWriter, r *http.Request) { - param1 := r.URL.Query()["param1"][0] + param1 := r.URL.Query()["param1"][0] // $ Source value, _ := strconv.Atoi(param1) - out := 1337 / value + out := 1337 / value // $ Alert fmt.Println(out) } func myHandler2(w http.ResponseWriter, r *http.Request) { - param1 := r.URL.Query()["param1"][0] + param1 := r.URL.Query()["param1"][0] // $ Source value := int(param1[0]) - out := 1337 / value + out := 1337 / value // $ Alert fmt.Println(out) } func myHandler3(w http.ResponseWriter, r *http.Request) { - param1 := r.URL.Query()["param1"][0] + param1 := r.URL.Query()["param1"][0] // $ Source value, _ := strconv.ParseInt(param1, 10, 64) - out := 1337 / value + out := 1337 / value // $ Alert fmt.Println(out) } func myHandler4(w http.ResponseWriter, r *http.Request) { - param1 := r.URL.Query()["param1"][0] + param1 := r.URL.Query()["param1"][0] // $ Source value, _ := strconv.ParseFloat(param1, 32) - out := 1337 / value + out := 1337 / value // $ Alert fmt.Println(out) } func myHandler5(w http.ResponseWriter, r *http.Request) { - param1 := r.URL.Query()["param1"][0] + param1 := r.URL.Query()["param1"][0] // $ Source value, _ := strconv.ParseUint(param1, 10, 64) - out := 1337 / value + out := 1337 / value // $ Alert fmt.Println(out) } @@ -51,10 +51,10 @@ func myHandler6(w http.ResponseWriter, r *http.Request) { } func myHandler7(w http.ResponseWriter, r *http.Request) { - param1 := r.URL.Query()["param1"][0] + param1 := r.URL.Query()["param1"][0] // $ Source value := int(param1[0]) if value >= 0 { - out := 1337 / value + out := 1337 / value // $ Alert fmt.Println(out) } } diff --git a/go/ql/test/experimental/CWE-369/DivideByZero.qlref b/go/ql/test/experimental/CWE-369/DivideByZero.qlref index 80eca2d3219..0713092d4b8 100644 --- a/go/ql/test/experimental/CWE-369/DivideByZero.qlref +++ b/go/ql/test/experimental/CWE-369/DivideByZero.qlref @@ -1,2 +1,4 @@ query: experimental/CWE-369/DivideByZero.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected index 074dfaa134f..e95505223cd 100644 --- a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected +++ b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected @@ -1,3 +1,7 @@ +#select +| DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | This calls call to First in a $@. | DatabaseCallInLoop.go:7:2:11:2 | range statement | loop | +| test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:20:2:22:2 | for statement | loop | +| test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:24:2:26:2 | for statement | loop | edges | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | | test.go:10:1:12:1 | function declaration | test.go:11:2:11:13 | call to Take | @@ -7,7 +11,3 @@ edges | test.go:21:3:21:14 | call to runQuery | test.go:10:1:12:1 | function declaration | | test.go:24:2:26:2 | for statement | test.go:25:3:25:17 | call to runRunQuery | | test.go:25:3:25:17 | call to runRunQuery | test.go:14:1:16:1 | function declaration | -#select -| DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | This calls call to First in a $@. | DatabaseCallInLoop.go:7:2:11:2 | range statement | loop | -| test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:20:2:22:2 | for statement | loop | -| test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:24:2:26:2 | for statement | loop | diff --git a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.go b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.go index 138bbbcd9d4..eff08179ee5 100644 --- a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.go +++ b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.go @@ -6,8 +6,8 @@ func getUsers(db *gorm.DB, names []string) []User { res := make([]User, 0, len(names)) for _, name := range names { var user User - db.Where("name = ?", name).First(&user) + db.Where("name = ?", name).First(&user) // $ Alert res = append(res, user) - } + } // $ Source return res } diff --git a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.qlref b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.qlref index 63f27c9b41f..945fbc88364 100644 --- a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.qlref +++ b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.qlref @@ -1 +1,2 @@ -experimental/CWE-400/DatabaseCallInLoop.ql +query: experimental/CWE-400/DatabaseCallInLoop.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-400/test.go b/go/ql/test/experimental/CWE-400/test.go index 725fb541b38..4c0a7f01d2e 100644 --- a/go/ql/test/experimental/CWE-400/test.go +++ b/go/ql/test/experimental/CWE-400/test.go @@ -8,7 +8,7 @@ type User struct { } func runQuery(db *gorm.DB) { - db.Take(nil) + db.Take(nil) // $ Alert } func runRunQuery(db *gorm.DB) { @@ -19,9 +19,9 @@ func main() { var db *gorm.DB for i := 0; i < 10; i++ { runQuery(db) - } + } // $ Source for i := 10; i > 0; i-- { runRunQuery(db) - } + } // $ Source } diff --git a/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombs.qlref b/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombs.qlref index 93d41075d5f..367d7bfe2fd 100644 --- a/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombs.qlref +++ b/go/ql/test/experimental/CWE-522-DecompressionBombs/DecompressionBombs.qlref @@ -1,2 +1,4 @@ query: experimental/CWE-522-DecompressionBombs/DecompressionBombs.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-522-DecompressionBombs/test.go b/go/ql/test/experimental/CWE-522-DecompressionBombs/test.go index dc359c387ac..370b24d4d3e 100644 --- a/go/ql/test/experimental/CWE-522-DecompressionBombs/test.go +++ b/go/ql/test/experimental/CWE-522-DecompressionBombs/test.go @@ -56,41 +56,41 @@ func main() { func DecompressHandler(w http.ResponseWriter, request *http.Request) { GZipOpenReaderSafe(request.PostFormValue("test")) ZipOpenReaderSafe(request.PostFormValue("test")) - ZipOpenReader(request.FormValue("filepath")) - ZipNewReader(request.Body) - ZipNewReaderKlauspost(request.Body) - Bzip2Dsnet(request.Body) + ZipOpenReader(request.FormValue("filepath")) // $ Source + ZipNewReader(request.Body) // $ Source + ZipNewReaderKlauspost(request.Body) // $ Source + Bzip2Dsnet(request.Body) // $ Source Bzip2DsnetSafe(request.Body) - Bzip2(request.Body) + Bzip2(request.Body) // $ Source Bzip2Safe(request.Body) - Flate(request.Body) + Flate(request.Body) // $ Source FlateSafe(request.Body) - FlateKlauspost(request.Body) + FlateKlauspost(request.Body) // $ Source FlateKlauspostSafe(request.Body) - FlateDsnet(request.Body) + FlateDsnet(request.Body) // $ Source FlateDsnetSafe(request.Body) - ZlibKlauspost(request.Body) + ZlibKlauspost(request.Body) // $ Source ZlibKlauspostSafe(request.Body) - Zlib(request.Body) + Zlib(request.Body) // $ Source ZlibSafe(request.Body) - Snappy(request.Body) + Snappy(request.Body) // $ Source SnappySafe(request.Body) - SnappyKlauspost(request.Body) + SnappyKlauspost(request.Body) // $ Source SnappyKlauspostSafe(request.Body) - S2(request.Body) + S2(request.Body) // $ Source S2Safe(request.Body) - Gzip(request.Body) + Gzip(request.Body) // $ Source GzipSafe(request.Body) - GZipIoReader(request.Body, "dest") - GzipKlauspost(request.Body) + GZipIoReader(request.Body, "dest") // $ Source + GzipKlauspost(request.Body) // $ Source GzipKlauspostSafe(request.Body) - PzipKlauspost(request.Body) + PzipKlauspost(request.Body) // $ Source PzipKlauspostSafe(request.Body) - Zstd_Klauspost(request.Body) + Zstd_Klauspost(request.Body) // $ Source Zstd_KlauspostSafe(request.Body) - Zstd_DataDog(request.Body) + Zstd_DataDog(request.Body) // $ Source Zstd_DataDogSafe(request.Body) - Xz(request.Body) + Xz(request.Body) // $ Source XzSafe(request.Body) } @@ -131,7 +131,7 @@ func ZipOpenReader(filename string) { for _, f := range zipReader.File { rc, _ := f.Open() for { - result, _ := io.CopyN(os.Stdout, rc, 68) // $ hasValueFlow="rc" + result, _ := io.CopyN(os.Stdout, rc, 68) // $ hasValueFlow="rc" Alert if result == 0 { _ = rc.Close() break @@ -144,7 +144,7 @@ func ZipOpenReader(filename string) { for _, f := range zipKlauspostReader.File { rc, _ := f.Open() for { - result, _ := io.CopyN(os.Stdout, rc, 68) // $ hasValueFlow="rc" + result, _ := io.CopyN(os.Stdout, rc, 68) // $ hasValueFlow="rc" Alert if result == 0 { _ = rc.Close() break @@ -161,7 +161,7 @@ func ZipNewReader(file io.Reader) { for _, file := range zipReader.File { fileWriter := bytes.NewBuffer([]byte{}) fileReaderCloser, _ := file.Open() - result, _ := io.Copy(fileWriter, fileReaderCloser) // $ hasValueFlow="fileReaderCloser" + result, _ := io.Copy(fileWriter, fileReaderCloser) // $ hasValueFlow="fileReaderCloser" Alert fmt.Print(result) } } @@ -173,7 +173,7 @@ func ZipNewReaderKlauspost(file io.Reader) { fileWriter := bytes.NewBuffer([]byte{}) // file.OpenRaw() fileReaderCloser, _ := file.Open() - result, _ := io.Copy(fileWriter, fileReaderCloser) // $ hasValueFlow="fileReaderCloser" + result, _ := io.Copy(fileWriter, fileReaderCloser) // $ hasValueFlow="fileReaderCloser" Alert fmt.Print(result) } } @@ -183,7 +183,7 @@ func Bzip2Dsnet(file io.Reader) { bzip2Reader, _ := bzip2Dsnet.NewReader(file, &bzip2Dsnet.ReaderConfig{}) var out []byte = make([]byte, 70) - bzip2Reader.Read(out) // $ hasValueFlow="bzip2Reader" + bzip2Reader.Read(out) // $ hasValueFlow="bzip2Reader" Alert tarRead = tar.NewReader(bzip2Reader) TarDecompressor(tarRead) @@ -210,7 +210,7 @@ func Bzip2(file io.Reader) { bzip2Reader := bzip2.NewReader(file) var out []byte = make([]byte, 70) - bzip2Reader.Read(out) // $ hasValueFlow="bzip2Reader" + bzip2Reader.Read(out) // $ hasValueFlow="bzip2Reader" Alert tarRead = tar.NewReader(bzip2Reader) TarDecompressor(tarRead) @@ -235,7 +235,7 @@ func Flate(file io.Reader) { flateReader := flate.NewReader(file) var out []byte = make([]byte, 70) - flateReader.Read(out) // $ hasValueFlow="flateReader" + flateReader.Read(out) // $ hasValueFlow="flateReader" Alert tarRead = tar.NewReader(flateReader) TarDecompressor(tarRead) @@ -260,7 +260,7 @@ func FlateKlauspost(file io.Reader) { flateReader := flateKlauspost.NewReader(file) var out []byte = make([]byte, 70) - flateReader.Read(out) // $ hasValueFlow="flateReader" + flateReader.Read(out) // $ hasValueFlow="flateReader" Alert tarRead = tar.NewReader(flateReader) TarDecompressor(tarRead) @@ -285,7 +285,7 @@ func FlateDsnet(file io.Reader) { flateReader, _ := flateDsnet.NewReader(file, &flateDsnet.ReaderConfig{}) var out []byte = make([]byte, 70) - flateReader.Read(out) // $ hasValueFlow="flateReader" + flateReader.Read(out) // $ hasValueFlow="flateReader" Alert tarRead = tar.NewReader(flateReader) TarDecompressor(tarRead) @@ -310,7 +310,7 @@ func ZlibKlauspost(file io.Reader) { zlibReader, _ := zlibKlauspost.NewReader(file) var out []byte = make([]byte, 70) - zlibReader.Read(out) // $ hasValueFlow="zlibReader" + zlibReader.Read(out) // $ hasValueFlow="zlibReader" Alert tarRead = tar.NewReader(zlibReader) TarDecompressor(tarRead) @@ -335,7 +335,7 @@ func Zlib(file io.Reader) { zlibReader, _ := zlib.NewReader(file) var out []byte = make([]byte, 70) - zlibReader.Read(out) // $ hasValueFlow="zlibReader" + zlibReader.Read(out) // $ hasValueFlow="zlibReader" Alert tarRead = tar.NewReader(zlibReader) TarDecompressor(tarRead) @@ -360,8 +360,8 @@ func Snappy(file io.Reader) { snappyReader := snappy.NewReader(file) var out []byte = make([]byte, 70) - snappyReader.Read(out) // $ hasValueFlow="snappyReader" - snappyReader.ReadByte() // $ hasValueFlow="snappyReader" + snappyReader.Read(out) // $ hasValueFlow="snappyReader" Alert + snappyReader.ReadByte() // $ hasValueFlow="snappyReader" Alert tarRead = tar.NewReader(snappyReader) TarDecompressor(tarRead) @@ -386,10 +386,10 @@ func SnappyKlauspost(file io.Reader) { snappyReader := snappyKlauspost.NewReader(file) var out []byte = make([]byte, 70) - snappyReader.Read(out) // $ hasValueFlow="snappyReader" + snappyReader.Read(out) // $ hasValueFlow="snappyReader" Alert var buf bytes.Buffer - snappyReader.DecodeConcurrent(&buf, 2) // $ hasValueFlow="snappyReader" - snappyReader.ReadByte() // $ hasValueFlow="snappyReader" + snappyReader.DecodeConcurrent(&buf, 2) // $ hasValueFlow="snappyReader" Alert + snappyReader.ReadByte() // $ hasValueFlow="snappyReader" Alert tarRead = tar.NewReader(snappyReader) TarDecompressor(tarRead) @@ -414,10 +414,10 @@ func S2(file io.Reader) { s2Reader := s2.NewReader(file) var out []byte = make([]byte, 70) - s2Reader.Read(out) // $ hasValueFlow="s2Reader" - s2Reader.ReadByte() // $ hasValueFlow="s2Reader" + s2Reader.Read(out) // $ hasValueFlow="s2Reader" Alert + s2Reader.ReadByte() // $ hasValueFlow="s2Reader" Alert var buf bytes.Buffer - s2Reader.DecodeConcurrent(&buf, 2) // $ hasValueFlow="s2Reader" + s2Reader.DecodeConcurrent(&buf, 2) // $ hasValueFlow="s2Reader" Alert tarRead = tar.NewReader(s2Reader) TarDecompressor(tarRead) @@ -442,14 +442,14 @@ func GZipIoReader(src io.Reader, dst string) { dstF, _ := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) defer dstF.Close() newSrc := io.Reader(gzipReader) - _, _ = io.Copy(dstF, newSrc) // $ hasValueFlow="newSrc" + _, _ = io.Copy(dstF, newSrc) // $ hasValueFlow="newSrc" Alert } func Gzip(file io.Reader) { var tarRead *tar.Reader gzipReader, _ := gzip.NewReader(file) var out []byte = make([]byte, 70) - gzipReader.Read(out) // $ hasValueFlow="gzipReader" + gzipReader.Read(out) // $ hasValueFlow="gzipReader" Alert tarRead = tar.NewReader(gzipReader) TarDecompressor(tarRead) @@ -474,9 +474,9 @@ func GzipKlauspost(file io.Reader) { gzipReader, _ := gzipKlauspost.NewReader(file) var out []byte = make([]byte, 70) - gzipReader.Read(out) // $ hasValueFlow="gzipReader" + gzipReader.Read(out) // $ hasValueFlow="gzipReader" Alert var buf bytes.Buffer - gzipReader.WriteTo(&buf) // $ hasValueFlow="gzipReader" + gzipReader.WriteTo(&buf) // $ hasValueFlow="gzipReader" Alert tarRead = tar.NewReader(gzipReader) TarDecompressor(tarRead) @@ -501,9 +501,9 @@ func PzipKlauspost(file io.Reader) { pgzipReader, _ := pgzipKlauspost.NewReader(file) var out []byte = make([]byte, 70) - pgzipReader.Read(out) // $ hasValueFlow="pgzipReader" + pgzipReader.Read(out) // $ hasValueFlow="pgzipReader" Alert var buf bytes.Buffer - pgzipReader.WriteTo(&buf) // $ hasValueFlow="pgzipReader" + pgzipReader.WriteTo(&buf) // $ hasValueFlow="pgzipReader" Alert tarRead = tar.NewReader(pgzipReader) TarDecompressor(tarRead) @@ -528,11 +528,11 @@ func Zstd_Klauspost(file io.Reader) { zstdReader, _ := zstdKlauspost.NewReader(file) var out []byte = make([]byte, 70) - zstdReader.Read(out) // $ hasValueFlow="zstdReader" + zstdReader.Read(out) // $ hasValueFlow="zstdReader" Alert var buf bytes.Buffer - zstdReader.WriteTo(&buf) // $ hasValueFlow="zstdReader" + zstdReader.WriteTo(&buf) // $ hasValueFlow="zstdReader" Alert var src []byte - zstdReader.DecodeAll(src, nil) // $ hasValueFlow="zstdReader" + zstdReader.DecodeAll(src, nil) // $ hasValueFlow="zstdReader" Alert tarRead = tar.NewReader(zstdReader) TarDecompressor(tarRead) @@ -557,7 +557,7 @@ func Zstd_DataDog(file io.Reader) { zstdReader := zstdDataDog.NewReader(file) var out []byte = make([]byte, 70) - zstdReader.Read(out) // $ hasValueFlow="zstdReader" + zstdReader.Read(out) // $ hasValueFlow="zstdReader" Alert tarRead = tar.NewReader(zstdReader) TarDecompressor(tarRead) @@ -582,7 +582,7 @@ func Xz(file io.Reader) { xzReader, _ := xz.NewReader(file) var out []byte = make([]byte, 70) - xzReader.Read(out) // $ hasValueFlow="xzReader" + xzReader.Read(out) // $ hasValueFlow="xzReader" Alert tarRead = tar.NewReader(xzReader) fmt.Println(io.SeekStart) @@ -618,7 +618,7 @@ func TarDecompressor(tarRead *tar.Reader) { if cur.Typeflag != tar.TypeReg { continue } - data, _ := io.ReadAll(tarRead) // $ hasValueFlow="tarRead" + data, _ := io.ReadAll(tarRead) // $ hasValueFlow="tarRead" Alert files[cur.Name] = &fstest.MapFile{Data: data} } fmt.Print(files) @@ -626,7 +626,7 @@ func TarDecompressor(tarRead *tar.Reader) { func TarDecompressor2(tarRead *tar.Reader) { var tarOut []byte = make([]byte, 70) - tarRead.Read(tarOut) // $ hasValueFlow="tarRead" + tarRead.Read(tarOut) // $ hasValueFlow="tarRead" Alert fmt.Println("do sth with output:", tarOut) } diff --git a/go/ql/test/experimental/CWE-525/WebCacheDeception.qlref b/go/ql/test/experimental/CWE-525/WebCacheDeception.qlref index 8b0788ef904..9e5d5cc3033 100644 --- a/go/ql/test/experimental/CWE-525/WebCacheDeception.qlref +++ b/go/ql/test/experimental/CWE-525/WebCacheDeception.qlref @@ -1 +1,2 @@ -experimental/CWE-525/WebCacheDeception.ql \ No newline at end of file +query: experimental/CWE-525/WebCacheDeception.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-525/WebCacheDeceptionBad.go b/go/ql/test/experimental/CWE-525/WebCacheDeceptionBad.go index 577fbd78c06..978d05588bb 100644 --- a/go/ql/test/experimental/CWE-525/WebCacheDeceptionBad.go +++ b/go/ql/test/experimental/CWE-525/WebCacheDeceptionBad.go @@ -79,7 +79,7 @@ func badRoutingNet() { http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/")))) - http.HandleFunc("/adminusers/", ShowAdminPageCache) + http.HandleFunc("/adminusers/", ShowAdminPageCache) // $ Alert err := http.ListenAndServe(":1337", nil) if err != nil { log.Fatal("ListenAndServe: ", err) diff --git a/go/ql/test/experimental/CWE-525/WebCacheDeceptionFiber.go b/go/ql/test/experimental/CWE-525/WebCacheDeceptionFiber.go index 80f396c26df..1126659d76e 100644 --- a/go/ql/test/experimental/CWE-525/WebCacheDeceptionFiber.go +++ b/go/ql/test/experimental/CWE-525/WebCacheDeceptionFiber.go @@ -12,12 +12,12 @@ func badRouting() { log.Println("We are logging in Golang!") // GET /api/register - app.Get("/api/*", func(c *fiber.Ctx) error { + app.Get("/api/*", func(c *fiber.Ctx) error { // $ Alert msg := fmt.Sprintf("✋") return c.SendString(msg) // => ✋ register }) - app.Post("/api/*", func(c *fiber.Ctx) error { + app.Post("/api/*", func(c *fiber.Ctx) error { // $ Alert msg := fmt.Sprintf("✋") return c.SendString(msg) // => ✋ register }) diff --git a/go/ql/test/experimental/CWE-525/WebCacheDeceptionGoChi.go b/go/ql/test/experimental/CWE-525/WebCacheDeceptionGoChi.go index 539dae1dee9..3de5e659138 100644 --- a/go/ql/test/experimental/CWE-525/WebCacheDeceptionGoChi.go +++ b/go/ql/test/experimental/CWE-525/WebCacheDeceptionGoChi.go @@ -10,7 +10,7 @@ import ( func badRoutingChi() { r := chi.NewRouter() r.Use(middleware.Logger) - r.Get("/*", func(w http.ResponseWriter, r *http.Request) { + r.Get("/*", func(w http.ResponseWriter, r *http.Request) { // $ Alert w.Write([]byte("welcome")) }) http.ListenAndServe(":3000", r) diff --git a/go/ql/test/experimental/CWE-525/WebCacheDeceptionHTTPRouter.go b/go/ql/test/experimental/CWE-525/WebCacheDeceptionHTTPRouter.go index 864c6c5e31c..7d1cd0b3d16 100644 --- a/go/ql/test/experimental/CWE-525/WebCacheDeceptionHTTPRouter.go +++ b/go/ql/test/experimental/CWE-525/WebCacheDeceptionHTTPRouter.go @@ -18,7 +18,7 @@ func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { func badHTTPRouter() { router := httprouter.New() - router.GET("/test/*test", Index) + router.GET("/test/*test", Index) // $ Alert router.GET("/hello/:name", Hello) log.Fatal(http.ListenAndServe(":8082", router)) diff --git a/go/ql/test/experimental/CWE-74/Dsn.go b/go/ql/test/experimental/CWE-74/Dsn.go index 3cdabc7cb3f..56eee4a48ee 100644 --- a/go/ql/test/experimental/CWE-74/Dsn.go +++ b/go/ql/test/experimental/CWE-74/Dsn.go @@ -23,10 +23,10 @@ func good() (interface{}, error) { } func bad() interface{} { - name2 := os.Args[1:] + name2 := os.Args[1:] // $ Source[go/dsn-injection-local] // This is bad. `name` can be something like `test?allowAllFiles=true&` which will allow an attacker to access local files. dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", "username", "password", "127.0.0.1", 3306, name2[0]) - db, _ := sql.Open("mysql", dbDSN) + db, _ := sql.Open("mysql", dbDSN) // $ Alert[go/dsn-injection-local] return db } @@ -44,10 +44,10 @@ func good2(w http.ResponseWriter, req *http.Request) (interface{}, error) { } func bad2(w http.ResponseWriter, req *http.Request) interface{} { - name := req.FormValue("name") + name := req.FormValue("name") // $ Source[go/dsn-injection] // This is bad. `name` can be something like `test?allowAllFiles=true&` which will allow an attacker to access local files. dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", "username", "password", "127.0.0.1", 3306, name) - db, _ := sql.Open("mysql", dbDSN) + db, _ := sql.Open("mysql", dbDSN) // $ Alert[go/dsn-injection] return db } @@ -60,12 +60,12 @@ func (Config) Parse([]string) error { return nil } func RegexFuncModelTest(w http.ResponseWriter, req *http.Request) (interface{}, error) { cfg := NewConfig() - err := cfg.Parse(os.Args[1:]) // This is bad. `name` can be something like `test?allowAllFiles=true&` which will allow an attacker to access local files. + err := cfg.Parse(os.Args[1:]) // $ Source[go/dsn-injection-local] // This is bad. `name` can be something like `test?allowAllFiles=true&` which will allow an attacker to access local files. if err != nil { return nil, err } dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", "username", "password", "127.0.0.1", 3306, cfg.dsn) - db, _ := sql.Open("mysql", dbDSN) + db, _ := sql.Open("mysql", dbDSN) // $ Alert[go/dsn-injection-local] return db, nil } diff --git a/go/ql/test/experimental/CWE-74/DsnInjection.qlref b/go/ql/test/experimental/CWE-74/DsnInjection.qlref index f8e0117d735..1b468898078 100644 --- a/go/ql/test/experimental/CWE-74/DsnInjection.qlref +++ b/go/ql/test/experimental/CWE-74/DsnInjection.qlref @@ -1,2 +1,4 @@ query: experimental/CWE-74/DsnInjection.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.qlref b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.qlref index f2d6116c7f1..f0907dee939 100644 --- a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.qlref +++ b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.qlref @@ -1,2 +1,4 @@ query: experimental/CWE-74/DsnInjectionLocal.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-807/SensitiveConditionBypass.qlref b/go/ql/test/experimental/CWE-807/SensitiveConditionBypass.qlref index da2ab35074a..b31f535387e 100644 --- a/go/ql/test/experimental/CWE-807/SensitiveConditionBypass.qlref +++ b/go/ql/test/experimental/CWE-807/SensitiveConditionBypass.qlref @@ -1 +1,2 @@ -experimental/CWE-807/SensitiveConditionBypass.ql +query: experimental/CWE-807/SensitiveConditionBypass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-807/SensitiveConditionBypassBad.go b/go/ql/test/experimental/CWE-807/SensitiveConditionBypassBad.go index bf8e70f88b7..04161f28fa8 100644 --- a/go/ql/test/experimental/CWE-807/SensitiveConditionBypassBad.go +++ b/go/ql/test/experimental/CWE-807/SensitiveConditionBypassBad.go @@ -4,7 +4,7 @@ import "net/http" func example(w http.ResponseWriter, r *http.Request) { test2 := "test" - if r.Header.Get("X-Password") != test2 { + if r.Header.Get("X-Password") != test2 { // $ Alert login() } } diff --git a/go/ql/test/experimental/CWE-807/condition.go b/go/ql/test/experimental/CWE-807/condition.go index ecd6b0a9f2a..d2bef8b335b 100644 --- a/go/ql/test/experimental/CWE-807/condition.go +++ b/go/ql/test/experimental/CWE-807/condition.go @@ -13,7 +13,7 @@ const test = "localhost" // Should alert as authkey is sensitive func ex1(w http.ResponseWriter, r *http.Request) { - if r.Header.Get("Origin") != test { + if r.Header.Get("Origin") != test { // $ Alert authkey := "randomDatta" io.WriteString(w, authkey) } @@ -22,7 +22,7 @@ func ex1(w http.ResponseWriter, r *http.Request) { // Should alert as authkey is sensitive func ex2(w http.ResponseWriter, r *http.Request) { test2 := "test" - if r.Header.Get("Origin") != test2 { + if r.Header.Get("Origin") != test2 { // $ Alert authkey := "randomDatta2" io.WriteString(w, authkey) } @@ -31,7 +31,7 @@ func ex2(w http.ResponseWriter, r *http.Request) { // Should alert as login() is sensitive func ex3(w http.ResponseWriter, r *http.Request) { test2 := "test" - if r.Header.Get("Origin") != test2 { + if r.Header.Get("Origin") != test2 { // $ Alert login() } } diff --git a/go/ql/test/experimental/CWE-840/ConditionalBypass.qlref b/go/ql/test/experimental/CWE-840/ConditionalBypass.qlref index 6d167616055..8c99cf7c285 100644 --- a/go/ql/test/experimental/CWE-840/ConditionalBypass.qlref +++ b/go/ql/test/experimental/CWE-840/ConditionalBypass.qlref @@ -1 +1,2 @@ -experimental/CWE-840/ConditionalBypass.ql +query: experimental/CWE-840/ConditionalBypass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/CWE-840/ConditionalBypassBad.go b/go/ql/test/experimental/CWE-840/ConditionalBypassBad.go index b788dee2009..a90b723e8be 100644 --- a/go/ql/test/experimental/CWE-840/ConditionalBypassBad.go +++ b/go/ql/test/experimental/CWE-840/ConditionalBypassBad.go @@ -6,7 +6,7 @@ import ( func exampleHandlerBad(w http.ResponseWriter, r *http.Request) { // BAD: the Origin and Host headers are user controlled - if r.Header.Get("Origin") != "http://"+r.Host { + if r.Header.Get("Origin") != "http://"+r.Host { // $ Alert //do something } } diff --git a/go/ql/test/experimental/CWE-840/condition.go b/go/ql/test/experimental/CWE-840/condition.go index 7b7b7480c10..fa413f32576 100644 --- a/go/ql/test/experimental/CWE-840/condition.go +++ b/go/ql/test/experimental/CWE-840/condition.go @@ -6,14 +6,14 @@ import ( // BAD: taken from https://www.gorillatoolkit.org/pkg/websocket func ex1(w http.ResponseWriter, r *http.Request) { - if r.Header.Get("Origin") != "http://"+r.Host { + if r.Header.Get("Origin") != "http://"+r.Host { // $ Alert //do something } } // BAD: both operands are from remote sources func ex2(w http.ResponseWriter, r *http.Request) { - if r.Header.Get("Origin") != "http://"+r.Header.Get("Header") { + if r.Header.Get("Origin") != "http://"+r.Header.Get("Header") { // $ Alert //do something } } diff --git a/go/ql/test/experimental/InconsistentCode/DeferInLoop.go b/go/ql/test/experimental/InconsistentCode/DeferInLoop.go index 1b57d1855b4..476a72a68f9 100644 --- a/go/ql/test/experimental/InconsistentCode/DeferInLoop.go +++ b/go/ql/test/experimental/InconsistentCode/DeferInLoop.go @@ -5,7 +5,7 @@ import "os" func openFiles(filenames []string) { for _, filename := range filenames { file, err := os.Open(filename) - defer file.Close() + defer file.Close() // $ Alert[go/examples/deferinloop] if err != nil { // handle error } diff --git a/go/ql/test/experimental/InconsistentCode/DeferInLoop.qlref b/go/ql/test/experimental/InconsistentCode/DeferInLoop.qlref index e50bcf4fdf6..f291f77e09e 100644 --- a/go/ql/test/experimental/InconsistentCode/DeferInLoop.qlref +++ b/go/ql/test/experimental/InconsistentCode/DeferInLoop.qlref @@ -1 +1,2 @@ -experimental/InconsistentCode/DeferInLoop.ql +query: experimental/InconsistentCode/DeferInLoop.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/InconsistentCode/GORMErrorNotChecked.go b/go/ql/test/experimental/InconsistentCode/GORMErrorNotChecked.go index 422e49b5f10..c24f9bad5a7 100644 --- a/go/ql/test/experimental/InconsistentCode/GORMErrorNotChecked.go +++ b/go/ql/test/experimental/InconsistentCode/GORMErrorNotChecked.go @@ -4,6 +4,6 @@ import "gorm.io/gorm" func getUserId(db *gorm.DB, name string) int64 { var user User - db.Where("name = ?", name).First(&user) + db.Where("name = ?", name).First(&user) // $ Alert[go/examples/gorm-error-not-checked] return user.Id } diff --git a/go/ql/test/experimental/InconsistentCode/GORMErrorNotChecked.qlref b/go/ql/test/experimental/InconsistentCode/GORMErrorNotChecked.qlref index b52256ad539..20b8106442b 100644 --- a/go/ql/test/experimental/InconsistentCode/GORMErrorNotChecked.qlref +++ b/go/ql/test/experimental/InconsistentCode/GORMErrorNotChecked.qlref @@ -1 +1,2 @@ -experimental/InconsistentCode/GORMErrorNotChecked.ql +query: experimental/InconsistentCode/GORMErrorNotChecked.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/experimental/InconsistentCode/test.go b/go/ql/test/experimental/InconsistentCode/test.go index 1dc64350bd4..ec893a14e74 100644 --- a/go/ql/test/experimental/InconsistentCode/test.go +++ b/go/ql/test/experimental/InconsistentCode/test.go @@ -3,24 +3,24 @@ package main func test() { var xs []int for _ = range xs { - defer test() // not ok + defer test() // $ Alert[go/examples/deferinloop] // not ok } for _ = range xs { if true { - defer test() // not ok + defer test() // $ Alert[go/examples/deferinloop] // not ok } } for i := 0; i < 10; i++ { - defer test() + defer test() // $ Alert[go/examples/deferinloop] } for true { - defer test() // not ok + defer test() // $ Alert[go/examples/deferinloop] // not ok } for false { - defer test() // fine but caught + defer test() // $ Alert[go/examples/deferinloop] // fine but caught } } diff --git a/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.expected b/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.expected index 3c7e02eea26..0dfdf1d7c15 100644 --- a/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.expected +++ b/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.expected @@ -1,3 +1,15 @@ +#select +| WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | $@. | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | Dangerous array type casting to [8]uint8 from an index expression ([8]uint8)[2] (the destination type is 2 elements longer) | +| WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | $@. | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | Dangerous array type casting to [17]uint8 from an index expression ([8]uint8)[0] (the destination type is 9 elements longer) | +| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | $@. | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | +| WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | $@. | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | +| WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | $@. | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | Dangerous array type casting to [17]string from [8]string | +| WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | $@. | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | Dangerous type up-casting to [17]uint8 from struct type | +| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | $@. | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | +| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | $@. | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | +| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | $@. | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | Dangerous array type casting to [4]int64 from [1]int64 | +| WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | $@. | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | Dangerous numeric type casting to int64 from int8 | +| WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | $@. | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | Dangerous numeric type casting to int from int8 | edges | WrongUsageOfUnsafe.go:17:24:17:48 | type conversion | WrongUsageOfUnsafe.go:17:13:17:49 | type conversion | provenance | | | WrongUsageOfUnsafe.go:34:24:34:51 | type conversion | WrongUsageOfUnsafe.go:34:13:34:52 | type conversion | provenance | | @@ -48,15 +60,3 @@ nodes | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | semmle.label | type conversion | | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | semmle.label | type conversion | subpaths -#select -| WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | WrongUsageOfUnsafe.go:77:16:77:55 | type conversion | $@. | WrongUsageOfUnsafe.go:77:27:77:54 | type conversion | Dangerous array type casting to [8]uint8 from an index expression ([8]uint8)[2] (the destination type is 2 elements longer) | -| WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | WrongUsageOfUnsafe.go:111:16:111:59 | type conversion | $@. | WrongUsageOfUnsafe.go:111:31:111:58 | type conversion | Dangerous array type casting to [17]uint8 from an index expression ([8]uint8)[0] (the destination type is 9 elements longer) | -| WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | WrongUsageOfUnsafe.go:129:16:129:56 | type conversion | $@. | WrongUsageOfUnsafe.go:129:31:129:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | -| WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | WrongUsageOfUnsafe.go:149:16:149:56 | type conversion | $@. | WrongUsageOfUnsafe.go:149:31:149:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | -| WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | $@. | WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | Dangerous array type casting to [17]string from [8]string | -| WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | $@. | WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | Dangerous type up-casting to [17]uint8 from struct type | -| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | $@. | WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | -| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | $@. | WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | Dangerous array type casting to [17]uint8 from [8]uint8 | -| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | $@. | WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | Dangerous array type casting to [4]int64 from [1]int64 | -| WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | $@. | WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | Dangerous numeric type casting to int64 from int8 | -| WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | $@. | WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | Dangerous numeric type casting to int from int8 | diff --git a/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.go b/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.go index 8599550039a..f20b7289589 100644 --- a/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.go +++ b/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.go @@ -74,7 +74,7 @@ func badIndexExpr() { // the address of the 3rd element of the `harmless` array, // and continue for 8 bytes, going out of the boundaries of // `harmless` and crossing into the memory occupied by `secret`. - var leaking = (*[8]byte)(unsafe.Pointer(&harmless[2])) // BAD + var leaking = (*[8]byte)(unsafe.Pointer(&harmless[2])) // $ Alert // BAD fmt.Println(string((*leaking)[:])) @@ -108,7 +108,7 @@ func bad0() { // Read before secret, overflowing into secret // (notice we get the pointer to the first byte of harmless) - var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless[0])) // BAD + var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless[0])) // $ Alert // BAD fmt.Println(string((*leaking)[:])) @@ -126,7 +126,7 @@ func bad1() { // Read before secret, overflowing into secret // (notice we read more than the length of harmless) - var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // BAD + var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // $ Alert // BAD fmt.Println(string((*leaking)[:])) @@ -146,7 +146,7 @@ func bad2() { // Read before secret, overflowing into secret // (notice we read more than the length of harmless) - var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // BAD + var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // $ Alert // BAD fmt.Println(string((*leaking)[:])) @@ -163,7 +163,7 @@ func bad3() { // Read before secret, overflowing into secret // (notice we read more than the length of harmless) - var leaking = (*[8 + 9]string)(unsafe.Pointer(&harmless)) // BAD + var leaking = (*[8 + 9]string)(unsafe.Pointer(&harmless)) // $ Alert // BAD fmt.Println(*leaking) fmt.Println([17]string((*leaking))) @@ -186,7 +186,7 @@ func bad4() { // Read before secret, overflowing into secret // (notice we read more than the length of harmless) - var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // BAD + var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless)) // $ Alert // BAD fmt.Println(string((*leaking)[:])) @@ -208,7 +208,7 @@ func bad5() { // Read before secret, overflowing into secret // (notice we read more than the length of harmless) - var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless.Data)) // BAD + var leaking = (*[8 + 9]byte)(unsafe.Pointer(&harmless.Data)) // $ Alert // BAD fmt.Println(string(leaking[:])) @@ -224,7 +224,7 @@ func bad6() { secret := [9]byte{'s', 'e', 'n', 's', 'i', 't', 'i', 'v', 'e'} // Read before secret: - var leaking = buffer_request(unsafe.Pointer(&harmless)) // BAD (see inside buffer_request func) + var leaking = buffer_request(unsafe.Pointer(&harmless)) // $ Source // BAD (see inside buffer_request func) fmt.Println((string)(leaking[:])) @@ -240,7 +240,7 @@ func buffer_request(req unsafe.Pointer) [8 + 9]byte { // will be read, the read will also contain pieces of // data from `secret`. var buf [8 + 9]byte - buf = *(*[8 + 9]byte)(req) // BAD (from above func) + buf = *(*[8 + 9]byte)(req) // $ Alert // BAD (from above func) return buf } func bad7() { @@ -253,7 +253,7 @@ func bad7() { // (notice we read more than the length of harmless); // the leaking array will not contain letters, // but integers representing bytes from `secret`. - var leaking = (*[4]int64)(unsafe.Pointer(&harmless)) // BAD + var leaking = (*[4]int64)(unsafe.Pointer(&harmless)) // $ Alert // BAD fmt.Println(*leaking) @@ -271,7 +271,7 @@ func bad8() { // Read before secret, overflowing into secret // (notice we read more than the length of harmless); // the leaking data will contain some bits from `secret`. - var leaking = (*int64)(unsafe.Pointer(&harmless)) // BAD + var leaking = (*int64)(unsafe.Pointer(&harmless)) // $ Alert // BAD fmt.Println(*leaking) @@ -289,7 +289,7 @@ func bad9() { // Read before secret, overflowing into secret // (notice we read more than the length of harmless); // the leaking data will contain some bits from `secret`. - var leaking = (*int)(unsafe.Pointer(&harmless)) // BAD + var leaking = (*int)(unsafe.Pointer(&harmless)) // $ Alert // BAD fmt.Println(*leaking) diff --git a/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.qlref b/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.qlref index 2f5c54707c7..5496859ca2e 100644 --- a/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.qlref +++ b/go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.qlref @@ -1 +1,2 @@ -experimental/Unsafe/WrongUsageOfUnsafe.ql +query: experimental/Unsafe/WrongUsageOfUnsafe.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.qlref b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.qlref index b6916bd2cd4..e1918157744 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/SqlInjection.qlref @@ -1,2 +1,4 @@ query: Security/CWE-089/SqlInjection.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.qlref b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.qlref index 66b7d67dd8f..f47ad25ca9c 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/StoredXss.qlref @@ -1,2 +1,4 @@ query: Security/CWE-079/StoredXss.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/test.go b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/test.go index cce152e57ef..5dacd494c05 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/test.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/BeegoOrm/test.go @@ -8,61 +8,61 @@ import ( // BAD: using untrusted data in SQL queries func testDbMethods(bdb *orm.DB, untrustedSource *http.Request) { - untrusted := untrustedSource.UserAgent() + untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection] - bdb.Exec(untrusted) // $ querystring=untrusted - bdb.ExecContext(nil, untrusted) // $ querystring=untrusted - bdb.Prepare(untrusted) // $ querystring=untrusted - bdb.PrepareContext(nil, untrusted) // $ querystring=untrusted - bdb.Query(untrusted) // $ querystring=untrusted - bdb.QueryContext(nil, untrusted) // $ querystring=untrusted - bdb.QueryRow(untrusted) // $ querystring=untrusted - bdb.QueryRowContext(nil, untrusted) // $ querystring=untrusted + bdb.Exec(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + bdb.ExecContext(nil, untrusted) // $ querystring=untrusted Alert[go/sql-injection] + bdb.Prepare(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + bdb.PrepareContext(nil, untrusted) // $ querystring=untrusted Alert[go/sql-injection] + bdb.Query(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + bdb.QueryContext(nil, untrusted) // $ querystring=untrusted Alert[go/sql-injection] + bdb.QueryRow(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + bdb.QueryRowContext(nil, untrusted) // $ querystring=untrusted Alert[go/sql-injection] } // BAD: using untrusted data to build SQL queries (QueryBuilder does not sanitize its arguments) func testQueryBuilderMethods(qb orm.QueryBuilder, untrustedSource *http.Request) { - untrusted := untrustedSource.UserAgent() - untrusted2 := untrustedSource.UserAgent() + untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection] + untrusted2 := untrustedSource.UserAgent() // $ Source[go/sql-injection] - qb.Select(untrusted) // $ querystring=untrusted - qb.From(untrusted) // $ querystring=untrusted - qb.InnerJoin(untrusted) // $ querystring=untrusted - qb.LeftJoin(untrusted) // $ querystring=untrusted - qb.RightJoin(untrusted) // $ querystring=untrusted - qb.On(untrusted) // $ querystring=untrusted - qb.Where(untrusted) // $ querystring=untrusted - qb.And(untrusted) // $ querystring=untrusted - qb.Or(untrusted) // $ querystring=untrusted - qb.In(untrusted) // $ querystring=untrusted - qb.OrderBy(untrusted) // $ querystring=untrusted - qb.GroupBy(untrusted) // $ querystring=untrusted - qb.Having(untrusted) // $ querystring=untrusted - qb.Update(untrusted) // $ querystring=untrusted - qb.Set(untrusted) // $ querystring=untrusted - qb.Delete(untrusted) // $ querystring=untrusted - qb.InsertInto(untrusted, untrusted2) // $ querystring=untrusted querystring=untrusted2 - qb.Values(untrusted) // $ querystring=untrusted - qb.Subquery(untrusted, untrusted2) // $ querystring=untrusted querystring=untrusted2 + qb.Select(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.From(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.InnerJoin(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.LeftJoin(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.RightJoin(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.On(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.Where(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.And(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.Or(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.In(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.OrderBy(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.GroupBy(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.Having(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.Update(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.Set(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.Delete(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.InsertInto(untrusted, untrusted2) // $ querystring=untrusted querystring=untrusted2 Alert[go/sql-injection] + qb.Values(untrusted) // $ querystring=untrusted Alert[go/sql-injection] + qb.Subquery(untrusted, untrusted2) // $ querystring=untrusted querystring=untrusted2 Alert[go/sql-injection] } func testOrmerRaw(ormer orm.Ormer, untrustedSource *http.Request) { - untrusted := untrustedSource.UserAgent() + untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection] untrusted2 := untrustedSource.UserAgent() - ormer.Raw(untrusted, untrusted2) // $ querystring=untrusted // BAD: using an untrusted string as a query + ormer.Raw(untrusted, untrusted2) // $ querystring=untrusted Alert[go/sql-injection] // BAD: using an untrusted string as a query ormer.Raw("FROM ? SELECT ?", untrusted, untrusted2) // $ querystring="FROM ? SELECT ?" // GOOD: untrusted string used in argument context } func testFilterRaw(querySeter orm.QuerySeter, untrustedSource *http.Request) { - untrusted := untrustedSource.UserAgent() - querySeter.FilterRaw(untrusted, "safe") // $ querystring="safe" // GOOD: untrusted used as a column name - querySeter.FilterRaw("safe", untrusted) // $ querystring=untrusted // BAD: untrusted used as a SQL fragment + untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection] + querySeter.FilterRaw(untrusted, "safe") // $ querystring="safe" // GOOD: untrusted used as a column name + querySeter.FilterRaw("safe", untrusted) // $ querystring=untrusted Alert[go/sql-injection] // BAD: untrusted used as a SQL fragment } func testConditionRaw(cond orm.Condition, untrustedSource *http.Request) { - untrusted := untrustedSource.UserAgent() - cond.Raw(untrusted, "safe") // $ querystring="safe" // GOOD: untrusted used as a column name - cond.Raw("safe", untrusted) // $ querystring=untrusted // BAD: untrusted used as a SQL fragment + untrusted := untrustedSource.UserAgent() // $ Source[go/sql-injection] + cond.Raw(untrusted, "safe") // $ querystring="safe" // GOOD: untrusted used as a column name + cond.Raw("safe", untrusted) // $ querystring=untrusted Alert[go/sql-injection] // BAD: untrusted used as a SQL fragment } type SubStruct struct { @@ -77,90 +77,90 @@ type MyStruct struct { // BAD: (possible stored XSS) retrieving data from a database then writing to an HTTP response func testOrmerReads(ormer orm.Ormer, sink http.ResponseWriter) { obj := MyStruct{} - ormer.Read(&obj) - sink.Write([]byte(obj.field)) - sink.Write([]byte(obj.substructs[0].field)) + ormer.Read(&obj) // $ Source[go/stored-xss] + sink.Write([]byte(obj.field)) // $ Alert[go/stored-xss] + sink.Write([]byte(obj.substructs[0].field)) // $ Alert[go/stored-xss] obj2 := MyStruct{} - ormer.ReadForUpdate(&obj2) - sink.Write([]byte(obj2.field)) + ormer.ReadForUpdate(&obj2) // $ Source[go/stored-xss] + sink.Write([]byte(obj2.field)) // $ Alert[go/stored-xss] obj3 := MyStruct{} - ormer.ReadOrCreate(&obj3, "arg") - sink.Write([]byte(obj3.field)) + ormer.ReadOrCreate(&obj3, "arg") // $ Source[go/stored-xss] + sink.Write([]byte(obj3.field)) // $ Alert[go/stored-xss] } // BAD: (possible stored XSS) retrieving data from a database then writing to an HTTP response func testFieldReads(textField *orm.TextField, jsonField *orm.JSONField, jsonbField *orm.JsonbField, sink http.ResponseWriter) { - sink.Write([]byte(textField.Value())) - sink.Write([]byte(textField.RawValue().(string))) - sink.Write([]byte(textField.String())) - sink.Write([]byte(jsonField.Value())) - sink.Write([]byte(jsonField.RawValue().(string))) - sink.Write([]byte(jsonField.String())) - sink.Write([]byte(jsonbField.Value())) - sink.Write([]byte(jsonbField.RawValue().(string))) - sink.Write([]byte(jsonbField.String())) + sink.Write([]byte(textField.Value())) // $ Alert[go/stored-xss] + sink.Write([]byte(textField.RawValue().(string))) // $ Alert[go/stored-xss] + sink.Write([]byte(textField.String())) // $ Alert[go/stored-xss] + sink.Write([]byte(jsonField.Value())) // $ Alert[go/stored-xss] + sink.Write([]byte(jsonField.RawValue().(string))) // $ Alert[go/stored-xss] + sink.Write([]byte(jsonField.String())) // $ Alert[go/stored-xss] + sink.Write([]byte(jsonbField.Value())) // $ Alert[go/stored-xss] + sink.Write([]byte(jsonbField.RawValue().(string))) // $ Alert[go/stored-xss] + sink.Write([]byte(jsonbField.String())) // $ Alert[go/stored-xss] } // BAD: (possible stored XSS) retrieving data from a database then writing to an HTTP response func testQuerySeterReads(qs orm.QuerySeter, sink http.ResponseWriter) { var objs []*MyStruct - qs.All(&objs) - sink.Write([]byte(objs[0].field)) + qs.All(&objs) // $ Source[go/stored-xss] + sink.Write([]byte(objs[0].field)) // $ Alert[go/stored-xss] var obj MyStruct - qs.One(&obj) - sink.Write([]byte(obj.field)) + qs.One(&obj) // $ Source[go/stored-xss] + sink.Write([]byte(obj.field)) // $ Alert[go/stored-xss] var allMaps []orm.Params - qs.Values(&allMaps) - sink.Write([]byte(allMaps[0]["field"].(string))) + qs.Values(&allMaps) // $ Source[go/stored-xss] + sink.Write([]byte(allMaps[0]["field"].(string))) // $ Alert[go/stored-xss] var allLists []orm.ParamsList - qs.ValuesList(&allLists) - sink.Write([]byte(allLists[0][0].(string))) + qs.ValuesList(&allLists) // $ Source[go/stored-xss] + sink.Write([]byte(allLists[0][0].(string))) // $ Alert[go/stored-xss] var oneList orm.ParamsList - qs.ValuesFlat(&oneList, "colname") - sink.Write([]byte(oneList[0].(string))) + qs.ValuesFlat(&oneList, "colname") // $ Source[go/stored-xss] + sink.Write([]byte(oneList[0].(string))) // $ Alert[go/stored-xss] var oneRowMap orm.Params - qs.RowsToMap(&oneRowMap, "key", "value") - sink.Write([]byte(oneRowMap["field"].(string))) + qs.RowsToMap(&oneRowMap, "key", "value") // $ Source[go/stored-xss] + sink.Write([]byte(oneRowMap["field"].(string))) // $ Alert[go/stored-xss] var oneRowStruct MyStruct - qs.RowsToStruct(&oneRowStruct, "key", "value") - sink.Write([]byte(oneRowStruct.field)) + qs.RowsToStruct(&oneRowStruct, "key", "value") // $ Source[go/stored-xss] + sink.Write([]byte(oneRowStruct.field)) // $ Alert[go/stored-xss] } // BAD: (possible stored XSS) retrieving data from a database then writing to an HTTP response func testRawSeterReads(rs orm.RawSeter, sink http.ResponseWriter) { var allMaps []orm.Params - rs.Values(&allMaps) - sink.Write([]byte(allMaps[0]["field"].(string))) + rs.Values(&allMaps) // $ Source[go/stored-xss] + sink.Write([]byte(allMaps[0]["field"].(string))) // $ Alert[go/stored-xss] var allLists []orm.ParamsList - rs.ValuesList(&allLists) - sink.Write([]byte(allLists[0][0].(string))) + rs.ValuesList(&allLists) // $ Source[go/stored-xss] + sink.Write([]byte(allLists[0][0].(string))) // $ Alert[go/stored-xss] var oneList orm.ParamsList - rs.ValuesFlat(&oneList, "colname") - sink.Write([]byte(oneList[0].(string))) + rs.ValuesFlat(&oneList, "colname") // $ Source[go/stored-xss] + sink.Write([]byte(oneList[0].(string))) // $ Alert[go/stored-xss] var oneRowMap orm.Params - rs.RowsToMap(&oneRowMap, "key", "value") - sink.Write([]byte(oneRowMap["field"].(string))) + rs.RowsToMap(&oneRowMap, "key", "value") // $ Source[go/stored-xss] + sink.Write([]byte(oneRowMap["field"].(string))) // $ Alert[go/stored-xss] var oneRowStruct MyStruct - rs.RowsToStruct(&oneRowStruct, "key", "value") - sink.Write([]byte(oneRowStruct.field)) + rs.RowsToStruct(&oneRowStruct, "key", "value") // $ Source[go/stored-xss] + sink.Write([]byte(oneRowStruct.field)) // $ Alert[go/stored-xss] var strField string - rs.QueryRow(&strField) - sink.Write([]byte(strField)) + rs.QueryRow(&strField) // $ Source[go/stored-xss] + sink.Write([]byte(strField)) // $ Alert[go/stored-xss] var strFields []string - rs.QueryRows(&strFields) - sink.Write([]byte(strFields[0])) + rs.QueryRows(&strFields) // $ Source[go/stored-xss] + sink.Write([]byte(strFields[0])) // $ Alert[go/stored-xss] } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.qlref index 754513d72bb..e6b791f39fc 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Chi/ReflectedXss.qlref @@ -1,2 +1,4 @@ query: Security/CWE-079/ReflectedXss.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Chi/test.go b/go/ql/test/library-tests/semmle/go/frameworks/Chi/test.go index f02e0cdfb15..aeb33fe8af0 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Chi/test.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Chi/test.go @@ -10,7 +10,7 @@ var hidden string func hideUserData(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - hidden = r.URL.Path + hidden = r.URL.Path // $ Source next.ServeHTTP(w, r) }) } @@ -18,10 +18,10 @@ func hideUserData(next http.Handler) http.Handler { func main() { r := chi.NewRouter() r.With(hideUserData).Get("/", func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(hidden)) - w.Write([]byte(chi.URLParam(r, "someParam"))) - w.Write([]byte(chi.URLParamFromCtx(r.Context(), "someKey"))) - w.Write([]byte(chi.RouteContext(r.Context()).URLParam("someOtherKey"))) + w.Write([]byte(hidden)) // $ Alert + w.Write([]byte(chi.URLParam(r, "someParam"))) // $ Alert + w.Write([]byte(chi.URLParamFromCtx(r.Context(), "someKey"))) // $ Alert + w.Write([]byte(chi.RouteContext(r.Context()).URLParam("someOtherKey"))) // $ Alert }) http.ListenAndServe(":3000", r) } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.qlref index 867dd766561..13add930f51 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.qlref @@ -1,2 +1,4 @@ query: Security/CWE-601/OpenUrlRedirect.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.qlref index 754513d72bb..e6b791f39fc 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/ReflectedXss.qlref @@ -1,2 +1,4 @@ query: Security/CWE-079/ReflectedXss.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/TaintedPath.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Echo/TaintedPath.qlref index 78ce25b1921..6eb2e94892f 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/TaintedPath.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/TaintedPath.qlref @@ -1,2 +1,4 @@ query: Security/CWE-022/TaintedPath.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go b/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go index 4a9f4e161f6..2435d91c6d7 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/test.go @@ -12,81 +12,81 @@ import ( // All are XSS vulnerabilities, except as specifically noted. func testParam(ctx echo.Context) error { - param := ctx.Param("someParam") - ctx.HTML(200, param) + param := ctx.Param("someParam") // $ Source[go/reflected-xss] + ctx.HTML(200, param) // $ Alert[go/reflected-xss] return nil } func testParamValues(ctx echo.Context) error { - param := ctx.ParamValues()[0] - ctx.HTML(200, param) + param := ctx.ParamValues()[0] // $ Source[go/reflected-xss] + ctx.HTML(200, param) // $ Alert[go/reflected-xss] return nil } func testQueryParam(ctx echo.Context) error { - param := ctx.QueryParam("someParam") - ctx.HTML(200, param) + param := ctx.QueryParam("someParam") // $ Source[go/reflected-xss] + ctx.HTML(200, param) // $ Alert[go/reflected-xss] return nil } func testQueryParams(ctx echo.Context) error { - param := ctx.QueryParams()["someParam"][0] - ctx.HTML(200, param) + param := ctx.QueryParams()["someParam"][0] // $ Source[go/reflected-xss] + ctx.HTML(200, param) // $ Alert[go/reflected-xss] return nil } func testQueryString(ctx echo.Context) error { - qstr := ctx.QueryString() - ctx.HTML(200, qstr) + qstr := ctx.QueryString() // $ Source[go/reflected-xss] + ctx.HTML(200, qstr) // $ Alert[go/reflected-xss] return nil } func testFormValue(ctx echo.Context) error { - val := ctx.FormValue("someField") - ctx.HTML(200, val) + val := ctx.FormValue("someField") // $ Source[go/reflected-xss] + ctx.HTML(200, val) // $ Alert[go/reflected-xss] return nil } func testFormParams(ctx echo.Context) error { - params, _ := ctx.FormParams() - ctx.HTML(200, params["someField"][0]) + params, _ := ctx.FormParams() // $ Source[go/reflected-xss] + ctx.HTML(200, params["someField"][0]) // $ Alert[go/reflected-xss] return nil } func testFormFile(ctx echo.Context) error { - fileHeader, _ := ctx.FormFile("someFilename") + fileHeader, _ := ctx.FormFile("someFilename") // $ Source[go/reflected-xss] file, _ := fileHeader.Open() buffer := make([]byte, 100) file.Read(buffer) - ctx.HTMLBlob(200, buffer) + ctx.HTMLBlob(200, buffer) // $ Alert[go/reflected-xss] return nil } func testMultipartFormValue(ctx echo.Context) error { - form, _ := ctx.MultipartForm() - ctx.HTML(200, form.Value["someField"][0]) + form, _ := ctx.MultipartForm() // $ Source[go/reflected-xss] + ctx.HTML(200, form.Value["someField"][0]) // $ Alert[go/reflected-xss] return nil } func testMultipartFormFile(ctx echo.Context) error { - form, _ := ctx.MultipartForm() + form, _ := ctx.MultipartForm() // $ Source[go/reflected-xss] fileHeader := form.File["someFilename"][0] file, _ := fileHeader.Open() buffer := make([]byte, 100) file.Read(buffer) - ctx.HTMLBlob(200, buffer) + ctx.HTMLBlob(200, buffer) // $ Alert[go/reflected-xss] return nil } func testCookie(ctx echo.Context) error { - val, _ := ctx.Cookie("someKey") - ctx.HTML(200, val.Value) + val, _ := ctx.Cookie("someKey") // $ Source[go/reflected-xss] + ctx.HTML(200, val.Value) // $ Alert[go/reflected-xss] return nil } func testCookies(ctx echo.Context) error { - cookies := ctx.Cookies() - ctx.HTML(200, cookies[0].Value) + cookies := ctx.Cookies() // $ Source[go/reflected-xss] + ctx.HTML(200, cookies[0].Value) // $ Alert[go/reflected-xss] return nil } @@ -96,8 +96,8 @@ type myStruct struct { func testBind(ctx echo.Context) error { data := myStruct{} - ctx.Bind(&data) - ctx.HTML(200, data.s) + ctx.Bind(&data) // $ Source[go/reflected-xss] + ctx.HTML(200, data.s) // $ Alert[go/reflected-xss] return nil } @@ -110,8 +110,8 @@ func testGetSetEmpty(ctx echo.Context) error { } func testGetSet(ctx echo.Context) error { - ctx.Set("someKey", ctx.Param("someParam")) - ctx.HTML(200, ctx.Get("someKey").(string)) // BAD, the context is tainted + ctx.Set("someKey", ctx.Param("someParam")) // $ Source[go/reflected-xss] + ctx.HTML(200, ctx.Get("someKey").(string)) // $ Alert[go/reflected-xss] // BAD, the context is tainted return nil } @@ -121,20 +121,20 @@ func testGetSet(ctx echo.Context) error { // All are XSS vulnerabilities, except as specifically noted. func testHTML(ctx echo.Context) error { - param := ctx.Param("someParam") - ctx.HTML(200, param) + param := ctx.Param("someParam") // $ Source[go/reflected-xss] + ctx.HTML(200, param) // $ Alert[go/reflected-xss] return nil } func testHTMLBlob(ctx echo.Context) error { - param := ctx.Param("someParam") - ctx.HTMLBlob(200, []byte(param)) + param := ctx.Param("someParam") // $ Source[go/reflected-xss] + ctx.HTMLBlob(200, []byte(param)) // $ Alert[go/reflected-xss] return nil } func testBlob(ctx echo.Context) error { - param := ctx.Param("someParam") - ctx.Blob(200, "text/html", []byte(param)) // BAD, the content-type is HTML + param := ctx.Param("someParam") // $ Source[go/reflected-xss] + ctx.Blob(200, "text/html", []byte(param)) // $ Alert[go/reflected-xss] // BAD, the content-type is HTML return nil } @@ -145,9 +145,9 @@ func testBlobSafe(ctx echo.Context) error { } func testStream(ctx echo.Context) error { - param := ctx.Param("someParam") + param := ctx.Param("someParam") // $ Source[go/reflected-xss] reader := strings.NewReader(param) - ctx.Stream(200, "text/html", reader) // BAD, the content-type is HTML + ctx.Stream(200, "text/html", reader) // $ Alert[go/reflected-xss] // BAD, the content-type is HTML return nil } @@ -161,28 +161,28 @@ func testStreamSafe(ctx echo.Context) error { // Section: testing output methods defined on Response (XSS vulnerability) func testResponseWrite(ctx echo.Context) error { - param := ctx.Param("someParam") - ctx.Response().Write([]byte(param)) + param := ctx.Param("someParam") // $ Source[go/reflected-xss] + ctx.Response().Write([]byte(param)) // $ Alert[go/reflected-xss] return nil } // Section: test detecting an open redirect using the Context.Redirect function: func testRedirect(ctx echo.Context) error { - param := ctx.Param("someParam") - ctx.Redirect(301, param) + param := ctx.Param("someParam") // $ Source[go/unvalidated-url-redirection] + ctx.Redirect(301, param) // $ Alert[go/unvalidated-url-redirection] return nil } func testLocalRedirects(ctx echo.Context) error { - param := ctx.Param("someParam") + param := ctx.Param("someParam") // $ Source[go/unvalidated-url-redirection] param2 := param param3 := param // Gratuitous copy because sanitization of uses propagates to subsequent uses // GOOD: local redirects are unproblematic ctx.Redirect(301, "/local"+param) // BAD: this could be a non-local redirect - ctx.Redirect(301, "/"+param2) + ctx.Redirect(301, "/"+param2) // $ Alert[go/unvalidated-url-redirection] // GOOD: localhost redirects are unproblematic ctx.Redirect(301, "//localhost/"+param3) return nil @@ -221,12 +221,12 @@ func testNonExploitableFields(ctx echo.Context) error { func fsOpsTest() { e := echo.New() e.GET("/", func(c echo.Context) error { - filepath := c.QueryParam("filePath") - return c.File(filepath) // $ FileSystemAccess=filepath + filepath := c.QueryParam("filePath") // $ Source[go/path-injection] + return c.File(filepath) // $ FileSystemAccess=filepath Alert[go/path-injection] }) e.GET("/attachment", func(c echo.Context) error { - filepath := c.QueryParam("filePath") - return c.Attachment(filepath, "file name in response") // $ FileSystemAccess=filepath + filepath := c.QueryParam("filePath") // $ Source[go/path-injection] + return c.Attachment(filepath, "file name in response") // $ FileSystemAccess=filepath Alert[go/path-injection] }) _ = e.Start(":1323") } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.expected b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.expected index 703066d6449..4ec65220a52 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.expected @@ -1,8 +1,8 @@ +#select +| main.go:21:28:21:31 | name | main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | This log entry depends on a $@. | main.go:18:46:18:48 | definition of req | user-provided value | edges | main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | provenance | | nodes | main.go:18:46:18:48 | definition of req | semmle.label | definition of req | | main.go:21:28:21:31 | name | semmle.label | name | subpaths -#select -| main.go:21:28:21:31 | name | main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | This log entry depends on a $@. | main.go:18:46:18:48 | definition of req | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.qlref b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.qlref index 1837c628c33..fc8a61c453d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.qlref @@ -1 +1,2 @@ -Security/CWE-117/LogInjection.ql +query: Security/CWE-117/LogInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/main.go b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/main.go index 3eaacef9822..5acaded1e7a 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/main.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/GoMicro/main.go @@ -15,10 +15,10 @@ import ( type Greeter struct{} -func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error { // $ serverRequest="definition of req" +func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error { // $ serverRequest="definition of req" Source // var access name := req.Name - fmt.Println("Name :: %s", name) + fmt.Println("Name :: %s", name) // $ Alert return nil } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/CONSISTENCY/DataFlowConsistency.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/CONSISTENCY/DataFlowConsistency.expected index 0fd726cd886..999379f9298 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/CONSISTENCY/DataFlowConsistency.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/CONSISTENCY/DataFlowConsistency.expected @@ -1,28 +1,28 @@ reverseRead -| EndToEnd.go:30:35:30:35 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:30:35:30:42 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:36:18:36:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:36:18:36:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:44:18:44:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:44:18:44:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:51:20:51:20 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:51:20:51:27 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:58:18:58:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:58:18:58:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:64:26:64:26 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:64:26:64:33 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:69:22:69:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:69:22:69:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:74:22:74:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:74:22:74:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:79:35:79:35 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:79:35:79:42 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:84:22:84:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:84:22:84:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:89:21:89:21 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:89:21:89:28 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:94:20:94:20 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | -| EndToEnd.go:94:20:94:27 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:31:35:31:35 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:31:35:31:42 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:37:18:37:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:37:18:37:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:45:18:45:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:45:18:45:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:52:20:52:20 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:52:20:52:27 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:59:18:59:18 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:59:18:59:25 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:65:26:65:26 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:65:26:65:33 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:70:22:70:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:70:22:70:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:75:22:75:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:75:22:75:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:80:35:80:35 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:80:35:80:42 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:85:22:85:22 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:85:22:85:29 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:90:21:90:21 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:90:21:90:28 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:95:20:95:20 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | +| EndToEnd.go:95:20:95:27 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | | Revel.go:26:7:26:7 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | | Revel.go:27:7:27:7 | implicit read of field Controller | Origin of readStep is missing a PostUpdateNode. | | Revel.go:27:7:27:14 | implicit dereference | Origin of readStep is missing a PostUpdateNode. | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/EndToEnd.go b/go/ql/test/library-tests/semmle/go/frameworks/Revel/EndToEnd.go index 69fc2c52c4a..0e60981e13d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/EndToEnd.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/EndToEnd.go @@ -3,10 +3,11 @@ package main import ( "bytes" "errors" - staticControllers "github.com/revel/modules/static/app/controllers" - "github.com/revel/revel" "os" "time" + + staticControllers "github.com/revel/modules/static/app/controllers" + "github.com/revel/revel" ) // Use typical inheritence pattern, per github.com/revel/examples/booking: @@ -33,8 +34,8 @@ func (c MyRoute) Handler1() revel.Result { func (c MyRoute) Handler2() revel.Result { // BAD: the RenderBinary function copies an `io.Reader` to the user's browser. buf := &bytes.Buffer{} - buf.WriteString(c.Params.Form.Get("someField")) - return c.RenderBinary(buf, "index.html", revel.Inline, time.Now()) // $ responsebody='buf' + buf.WriteString(c.Params.Form.Get("someField")) // $ Source[go/reflected-xss] + return c.RenderBinary(buf, "index.html", revel.Inline, time.Now()) // $ responsebody='buf' Alert[go/reflected-xss] } func (c MyRoute) Handler3() revel.Result { @@ -55,18 +56,18 @@ func (c MyRoute) Handler4() revel.Result { func (c MyRoute) Handler5() revel.Result { // BAD: returning an arbitrary file (but this is detected at the os.Open call, not // due to modelling Revel) - f, _ := os.Open(c.Params.Form.Get("someField")) + f, _ := os.Open(c.Params.Form.Get("someField")) // $ Alert[go/path-injection] return c.RenderFile(f, revel.Inline) } func (c MyRoute) Handler6() revel.Result { // BAD: returning an arbitrary file (detected as a user-controlled file-op, not XSS) - return c.RenderFileName(c.Params.Form.Get("someField"), revel.Inline) + return c.RenderFileName(c.Params.Form.Get("someField"), revel.Inline) // $ Alert[go/path-injection] } func (c MyRoute) Handler7() revel.Result { // BAD: straightforward XSS - return c.RenderHTML(c.Params.Form.Get("someField")) // $ responsebody='call to Get' + return c.RenderHTML(c.Params.Form.Get("someField")) // $ responsebody='call to Get' Alert[go/reflected-xss] } func (c MyRoute) Handler8() revel.Result { @@ -91,5 +92,5 @@ func (c MyRoute) Handler11() revel.Result { func (c MyRoute) Handler12() revel.Result { // BAD: open redirect - return c.Redirect(c.Params.Form.Get("someField")) + return c.Redirect(c.Params.Form.Get("someField")) // $ Alert[go/unvalidated-url-redirection] } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected index d3f52f4f9c6..3c889cd177c 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected @@ -1,19 +1,19 @@ #select -| EndToEnd.go:94:20:94:49 | call to Get | EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:49 | call to Get | This path to an untrusted URL redirection depends on a $@. | EndToEnd.go:94:20:94:27 | selection of Params | user-provided value | +| EndToEnd.go:95:20:95:49 | call to Get | EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:49 | call to Get | This path to an untrusted URL redirection depends on a $@. | EndToEnd.go:95:20:95:27 | selection of Params | user-provided value | edges -| EndToEnd.go:94:20:94:27 | implicit dereference | EndToEnd.go:94:20:94:27 | selection of Params [postupdate] | provenance | Config | -| EndToEnd.go:94:20:94:27 | implicit dereference | EndToEnd.go:94:20:94:32 | selection of Form | provenance | Config | -| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:27 | implicit dereference | provenance | Src:MaD:2 Config | -| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:32 | selection of Form | provenance | Src:MaD:2 Config | -| EndToEnd.go:94:20:94:27 | selection of Params [postupdate] | EndToEnd.go:94:20:94:27 | implicit dereference | provenance | Config | -| EndToEnd.go:94:20:94:32 | selection of Form | EndToEnd.go:94:20:94:49 | call to Get | provenance | Config Sink:MaD:1 | +| EndToEnd.go:95:20:95:27 | implicit dereference | EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | provenance | Config | +| EndToEnd.go:95:20:95:27 | implicit dereference | EndToEnd.go:95:20:95:32 | selection of Form | provenance | Config | +| EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:27 | implicit dereference | provenance | Src:MaD:2 Config | +| EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:32 | selection of Form | provenance | Src:MaD:2 Config | +| EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | EndToEnd.go:95:20:95:27 | implicit dereference | provenance | Config | +| EndToEnd.go:95:20:95:32 | selection of Form | EndToEnd.go:95:20:95:49 | call to Get | provenance | Config Sink:MaD:1 | models | 1 | Sink: group:revel; Controller; true; Redirect; ; ; Argument[0]; url-redirection; manual | | 2 | Source: group:revel; Controller; true; Params; ; ; ; remote; manual | nodes -| EndToEnd.go:94:20:94:27 | implicit dereference | semmle.label | implicit dereference | -| EndToEnd.go:94:20:94:27 | selection of Params | semmle.label | selection of Params | -| EndToEnd.go:94:20:94:27 | selection of Params [postupdate] | semmle.label | selection of Params [postupdate] | -| EndToEnd.go:94:20:94:32 | selection of Form | semmle.label | selection of Form | -| EndToEnd.go:94:20:94:49 | call to Get | semmle.label | call to Get | +| EndToEnd.go:95:20:95:27 | implicit dereference | semmle.label | implicit dereference | +| EndToEnd.go:95:20:95:27 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | semmle.label | selection of Params [postupdate] | +| EndToEnd.go:95:20:95:32 | selection of Form | semmle.label | selection of Form | +| EndToEnd.go:95:20:95:49 | call to Get | semmle.label | call to Get | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.qlref index 867dd766561..13add930f51 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.qlref @@ -1,2 +1,4 @@ query: Security/CWE-601/OpenUrlRedirect.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected index 9ea4016a7e4..0de532aa186 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.expected @@ -1,16 +1,16 @@ #select -| EndToEnd.go:37:24:37:26 | buf | EndToEnd.go:36:18:36:25 | selection of Params | EndToEnd.go:37:24:37:26 | buf | Cross-site scripting vulnerability due to $@. | EndToEnd.go:36:18:36:25 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | | -| EndToEnd.go:69:22:69:51 | call to Get | EndToEnd.go:69:22:69:29 | selection of Params | EndToEnd.go:69:22:69:51 | call to Get | Cross-site scripting vulnerability due to $@. | EndToEnd.go:69:22:69:29 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | | +| EndToEnd.go:38:24:38:26 | buf | EndToEnd.go:37:18:37:25 | selection of Params | EndToEnd.go:38:24:38:26 | buf | Cross-site scripting vulnerability due to $@. | EndToEnd.go:37:18:37:25 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | | +| EndToEnd.go:70:22:70:51 | call to Get | EndToEnd.go:70:22:70:29 | selection of Params | EndToEnd.go:70:22:70:51 | call to Get | Cross-site scripting vulnerability due to $@. | EndToEnd.go:70:22:70:29 | selection of Params | user-provided value | EndToEnd.go:0:0:0:0 | EndToEnd.go | | | Revel.go:70:22:70:35 | selection of Query | Revel.go:70:22:70:29 | selection of Params | Revel.go:70:22:70:35 | selection of Query | Cross-site scripting vulnerability due to $@. The value is $@. | Revel.go:70:22:70:29 | selection of Params | user-provided value | views/myAppController/rawRead.html:1:1:2:9 | {{raw .Foo}}\n{{.Bar}}\n | instantiated as a raw template | | examples/booking/app/init.go:36:44:36:53 | selection of Path | examples/booking/app/init.go:36:44:36:48 | selection of URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:36:44:36:48 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | | | examples/booking/app/init.go:40:49:40:58 | selection of Path | examples/booking/app/init.go:40:49:40:53 | selection of URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | Cross-site scripting vulnerability due to $@. | examples/booking/app/init.go:40:49:40:53 | selection of URL | user-provided value | examples/booking/app/init.go:0:0:0:0 | examples/booking/app/init.go | | edges -| EndToEnd.go:36:2:36:4 | buf [postupdate] | EndToEnd.go:37:24:37:26 | buf | provenance | | -| EndToEnd.go:36:18:36:25 | selection of Params | EndToEnd.go:36:18:36:30 | selection of Form | provenance | Src:MaD:1 | -| EndToEnd.go:36:18:36:30 | selection of Form | EndToEnd.go:36:18:36:47 | call to Get | provenance | MaD:4 | -| EndToEnd.go:36:18:36:47 | call to Get | EndToEnd.go:36:2:36:4 | buf [postupdate] | provenance | MaD:3 | -| EndToEnd.go:69:22:69:29 | selection of Params | EndToEnd.go:69:22:69:34 | selection of Form | provenance | Src:MaD:1 | -| EndToEnd.go:69:22:69:34 | selection of Form | EndToEnd.go:69:22:69:51 | call to Get | provenance | MaD:4 | +| EndToEnd.go:37:2:37:4 | buf [postupdate] | EndToEnd.go:38:24:38:26 | buf | provenance | | +| EndToEnd.go:37:18:37:25 | selection of Params | EndToEnd.go:37:18:37:30 | selection of Form | provenance | Src:MaD:1 | +| EndToEnd.go:37:18:37:30 | selection of Form | EndToEnd.go:37:18:37:47 | call to Get | provenance | MaD:4 | +| EndToEnd.go:37:18:37:47 | call to Get | EndToEnd.go:37:2:37:4 | buf [postupdate] | provenance | MaD:3 | +| EndToEnd.go:70:22:70:29 | selection of Params | EndToEnd.go:70:22:70:34 | selection of Form | provenance | Src:MaD:1 | +| EndToEnd.go:70:22:70:34 | selection of Form | EndToEnd.go:70:22:70:51 | call to Get | provenance | MaD:4 | | Revel.go:70:22:70:29 | selection of Params | Revel.go:70:22:70:35 | selection of Query | provenance | Src:MaD:1 | | examples/booking/app/init.go:36:44:36:48 | selection of URL | examples/booking/app/init.go:36:44:36:53 | selection of Path | provenance | Src:MaD:2 | | examples/booking/app/init.go:40:49:40:53 | selection of URL | examples/booking/app/init.go:40:49:40:58 | selection of Path | provenance | Src:MaD:2 | @@ -20,14 +20,14 @@ models | 3 | Summary: io; StringWriter; true; WriteString; ; ; Argument[0]; Argument[receiver]; taint; manual | | 4 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | nodes -| EndToEnd.go:36:2:36:4 | buf [postupdate] | semmle.label | buf [postupdate] | -| EndToEnd.go:36:18:36:25 | selection of Params | semmle.label | selection of Params | -| EndToEnd.go:36:18:36:30 | selection of Form | semmle.label | selection of Form | -| EndToEnd.go:36:18:36:47 | call to Get | semmle.label | call to Get | -| EndToEnd.go:37:24:37:26 | buf | semmle.label | buf | -| EndToEnd.go:69:22:69:29 | selection of Params | semmle.label | selection of Params | -| EndToEnd.go:69:22:69:34 | selection of Form | semmle.label | selection of Form | -| EndToEnd.go:69:22:69:51 | call to Get | semmle.label | call to Get | +| EndToEnd.go:37:2:37:4 | buf [postupdate] | semmle.label | buf [postupdate] | +| EndToEnd.go:37:18:37:25 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:37:18:37:30 | selection of Form | semmle.label | selection of Form | +| EndToEnd.go:37:18:37:47 | call to Get | semmle.label | call to Get | +| EndToEnd.go:38:24:38:26 | buf | semmle.label | buf | +| EndToEnd.go:70:22:70:29 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:70:22:70:34 | selection of Form | semmle.label | selection of Form | +| EndToEnd.go:70:22:70:51 | call to Get | semmle.label | call to Get | | Revel.go:70:22:70:29 | selection of Params | semmle.label | selection of Params | | Revel.go:70:22:70:35 | selection of Query | semmle.label | selection of Query | | examples/booking/app/init.go:36:44:36:48 | selection of URL | semmle.label | selection of URL | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.qlref index 754513d72bb..e6b791f39fc 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/ReflectedXss.qlref @@ -1,2 +1,4 @@ query: Security/CWE-079/ReflectedXss.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go b/go/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go index f09dcd6fa58..219e1dddb4c 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go @@ -67,7 +67,7 @@ func (c myAppController) accessingParamsJSONIsUnsafe() { func (c myAppController) rawRead() { // $ responsebody='argument corresponding to c' c.ViewArgs["Foo"] = "

    raw HTML

    " // $ responsebody='"

    raw HTML

    "' c.ViewArgs["Bar"] = "

    not raw HTML

    " - c.ViewArgs["Foo"] = c.Params.Query // $ responsebody='selection of Query' + c.ViewArgs["Foo"] = c.Params.Query // $ responsebody='selection of Query' Alert[go/reflected-xss] c.Render() } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected index 7337f636c47..e007da1c95d 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.expected @@ -1,21 +1,21 @@ #select -| EndToEnd.go:58:18:58:47 | call to Get | EndToEnd.go:58:18:58:25 | selection of Params | EndToEnd.go:58:18:58:47 | call to Get | This path depends on a $@. | EndToEnd.go:58:18:58:25 | selection of Params | user-provided value | -| EndToEnd.go:64:26:64:55 | call to Get | EndToEnd.go:64:26:64:33 | selection of Params | EndToEnd.go:64:26:64:55 | call to Get | This path depends on a $@. | EndToEnd.go:64:26:64:33 | selection of Params | user-provided value | +| EndToEnd.go:59:18:59:47 | call to Get | EndToEnd.go:59:18:59:25 | selection of Params | EndToEnd.go:59:18:59:47 | call to Get | This path depends on a $@. | EndToEnd.go:59:18:59:25 | selection of Params | user-provided value | +| EndToEnd.go:65:26:65:55 | call to Get | EndToEnd.go:65:26:65:33 | selection of Params | EndToEnd.go:65:26:65:55 | call to Get | This path depends on a $@. | EndToEnd.go:65:26:65:33 | selection of Params | user-provided value | edges -| EndToEnd.go:58:18:58:25 | selection of Params | EndToEnd.go:58:18:58:30 | selection of Form | provenance | Src:MaD:3 | -| EndToEnd.go:58:18:58:30 | selection of Form | EndToEnd.go:58:18:58:47 | call to Get | provenance | MaD:4 Sink:MaD:2 | -| EndToEnd.go:64:26:64:33 | selection of Params | EndToEnd.go:64:26:64:38 | selection of Form | provenance | Src:MaD:3 | -| EndToEnd.go:64:26:64:38 | selection of Form | EndToEnd.go:64:26:64:55 | call to Get | provenance | MaD:4 Sink:MaD:1 | +| EndToEnd.go:59:18:59:25 | selection of Params | EndToEnd.go:59:18:59:30 | selection of Form | provenance | Src:MaD:3 | +| EndToEnd.go:59:18:59:30 | selection of Form | EndToEnd.go:59:18:59:47 | call to Get | provenance | MaD:4 Sink:MaD:2 | +| EndToEnd.go:65:26:65:33 | selection of Params | EndToEnd.go:65:26:65:38 | selection of Form | provenance | Src:MaD:3 | +| EndToEnd.go:65:26:65:38 | selection of Form | EndToEnd.go:65:26:65:55 | call to Get | provenance | MaD:4 Sink:MaD:1 | models | 1 | Sink: group:revel; Controller; true; RenderFileName; ; ; Argument[0]; path-injection; manual | | 2 | Sink: os; ; false; Open; ; ; Argument[0]; path-injection; manual | | 3 | Source: group:revel; Controller; true; Params; ; ; ; remote; manual | | 4 | Summary: net/url; Values; true; Get; ; ; Argument[receiver]; ReturnValue; taint; manual | nodes -| EndToEnd.go:58:18:58:25 | selection of Params | semmle.label | selection of Params | -| EndToEnd.go:58:18:58:30 | selection of Form | semmle.label | selection of Form | -| EndToEnd.go:58:18:58:47 | call to Get | semmle.label | call to Get | -| EndToEnd.go:64:26:64:33 | selection of Params | semmle.label | selection of Params | -| EndToEnd.go:64:26:64:38 | selection of Form | semmle.label | selection of Form | -| EndToEnd.go:64:26:64:55 | call to Get | semmle.label | call to Get | +| EndToEnd.go:59:18:59:25 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:59:18:59:30 | selection of Form | semmle.label | selection of Form | +| EndToEnd.go:59:18:59:47 | call to Get | semmle.label | call to Get | +| EndToEnd.go:65:26:65:33 | selection of Params | semmle.label | selection of Params | +| EndToEnd.go:65:26:65:38 | selection of Form | semmle.label | selection of Form | +| EndToEnd.go:65:26:65:55 | call to Get | semmle.label | call to Get | subpaths diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.qlref b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.qlref index 78ce25b1921..6eb2e94892f 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/TaintedPath.qlref @@ -1,2 +1,4 @@ query: Security/CWE-022/TaintedPath.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/examples/booking/app/init.go b/go/ql/test/library-tests/semmle/go/frameworks/Revel/examples/booking/app/init.go index 2f7fef73fc2..ca9232ec7c7 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/examples/booking/app/init.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/examples/booking/app/init.go @@ -33,11 +33,11 @@ func init() { switch event { case revel.ENGINE_BEFORE_INITIALIZED: revel.AddHTTPMux("/this/is/a/test", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "Hi there, it worked", r.URL.Path) // $ responsebody='selection of Path' responsebody='"Hi there, it worked"' + fmt.Fprintln(w, "Hi there, it worked", r.URL.Path) // $ responsebody='selection of Path' responsebody='"Hi there, it worked"' Alert[go/reflected-xss] w.WriteHeader(200) })) revel.AddHTTPMux("/this/is/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "Hi there, shorter prefix", r.URL.Path) // $ responsebody='selection of Path' responsebody='"Hi there, shorter prefix"' + fmt.Fprintln(w, "Hi there, shorter prefix", r.URL.Path) // $ responsebody='selection of Path' responsebody='"Hi there, shorter prefix"' Alert[go/reflected-xss] w.WriteHeader(200) })) } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.qlref b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.qlref index 754513d72bb..e6b791f39fc 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.qlref @@ -1,2 +1,4 @@ query: Security/CWE-079/ReflectedXss.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.qlref b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.qlref index b6916bd2cd4..e1918157744 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.qlref +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.qlref @@ -1,2 +1,4 @@ query: Security/CWE-089/SqlInjection.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go index a89167e126c..6b8a02a1fb3 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go @@ -9,50 +9,50 @@ import ( func test(request *http.Request, writer http.ResponseWriter) { - param1 := request.URL.Query().Get("param1") + param1 := request.URL.Query().Get("param1") // $ Source[go/reflected-xss] writer.Write([]byte(html.EscapeString(param1))) // GOOD: escaped. - writer.Write([]byte(html.UnescapeString(param1))) // BAD: unescaped. + writer.Write([]byte(html.UnescapeString(param1))) // $ Alert[go/reflected-xss] // BAD: unescaped. - node, _ := html.Parse(request.Body) - writer.Write([]byte(node.Data)) // BAD: writing unescaped HTML data + node, _ := html.Parse(request.Body) // $ Source[go/reflected-xss] + writer.Write([]byte(node.Data)) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data - node2, _ := html.ParseWithOptions(request.Body) - writer.Write([]byte(node2.Data)) // BAD: writing unescaped HTML data + node2, _ := html.ParseWithOptions(request.Body) // $ Source[go/reflected-xss] + writer.Write([]byte(node2.Data)) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data - nodes, _ := html.ParseFragment(request.Body, nil) - writer.Write([]byte(nodes[0].Data)) // BAD: writing unescaped HTML data + nodes, _ := html.ParseFragment(request.Body, nil) // $ Source[go/reflected-xss] + writer.Write([]byte(nodes[0].Data)) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data - nodes2, _ := html.ParseFragmentWithOptions(request.Body, nil) - writer.Write([]byte(nodes2[0].Data)) // BAD: writing unescaped HTML data + nodes2, _ := html.ParseFragmentWithOptions(request.Body, nil) // $ Source[go/reflected-xss] + writer.Write([]byte(nodes2[0].Data)) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data - html.Render(writer, node) // BAD: rendering untrusted HTML to `writer` + html.Render(writer, node) // $ Alert[go/reflected-xss] // BAD: rendering untrusted HTML to `writer` - tokenizer := html.NewTokenizer(request.Body) - writer.Write(tokenizer.Buffered()) // BAD: writing unescaped HTML data - writer.Write(tokenizer.Raw()) // BAD: writing unescaped HTML data + tokenizer := html.NewTokenizer(request.Body) // $ Source[go/reflected-xss] + writer.Write(tokenizer.Buffered()) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data + writer.Write(tokenizer.Raw()) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data _, value, _ := tokenizer.TagAttr() - writer.Write(value) // BAD: writing unescaped HTML data - writer.Write(tokenizer.Text()) // BAD: writing unescaped HTML data - writer.Write([]byte(tokenizer.Token().Data)) // BAD: writing unescaped HTML data + writer.Write(value) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data + writer.Write(tokenizer.Text()) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data + writer.Write([]byte(tokenizer.Token().Data)) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data - tokenizerFragment := html.NewTokenizerFragment(request.Body, "some context") - writer.Write(tokenizerFragment.Buffered()) // BAD: writing unescaped HTML data + tokenizerFragment := html.NewTokenizerFragment(request.Body, "some context") // $ Source[go/reflected-xss] + writer.Write(tokenizerFragment.Buffered()) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data var cleanNode html.Node - taintedNode, _ := html.Parse(request.Body) + taintedNode, _ := html.Parse(request.Body) // $ Source[go/reflected-xss] cleanNode.AppendChild(taintedNode) - html.Render(writer, &cleanNode) // BAD: writing unescaped HTML data + html.Render(writer, &cleanNode) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data var cleanNode2 html.Node - taintedNode2, _ := html.Parse(request.Body) + taintedNode2, _ := html.Parse(request.Body) // $ Source[go/reflected-xss] cleanNode2.InsertBefore(taintedNode2, &cleanNode2) - html.Render(writer, &cleanNode2) // BAD: writing unescaped HTML data + html.Render(writer, &cleanNode2) // $ Alert[go/reflected-xss] // BAD: writing unescaped HTML data } func sqlTest(request *http.Request, db *sql.DB) { // Ensure EscapeString is a taint propagator for non-XSS queries, e.g. SQL injection: - cookie, _ := request.Cookie("SomeCookie") - db.Query(html.EscapeString(cookie.Value)) + cookie, _ := request.Cookie("SomeCookie") // $ Source[go/sql-injection] + db.Query(html.EscapeString(cookie.Value)) // $ Alert[go/sql-injection] } diff --git a/go/ql/test/query-tests/InconsistentCode/ConstantLengthComparison/ConstantLengthComparison.go b/go/ql/test/query-tests/InconsistentCode/ConstantLengthComparison/ConstantLengthComparison.go index cec41e2dab2..a1a6b1f309e 100644 --- a/go/ql/test/query-tests/InconsistentCode/ConstantLengthComparison/ConstantLengthComparison.go +++ b/go/ql/test/query-tests/InconsistentCode/ConstantLengthComparison/ConstantLengthComparison.go @@ -2,7 +2,7 @@ package main func isPrefixOf(xs, ys []int) bool { for i := 0; i < len(xs); i++ { - if len(ys) == 0 || xs[i] != ys[i] { // NOT OK + if len(ys) == 0 || xs[i] != ys[i] { // $ Alert // NOT OK return false } } diff --git a/go/ql/test/query-tests/InconsistentCode/ConstantLengthComparison/ConstantLengthComparison.qlref b/go/ql/test/query-tests/InconsistentCode/ConstantLengthComparison/ConstantLengthComparison.qlref index 315838df15f..edd5d2d1d43 100644 --- a/go/ql/test/query-tests/InconsistentCode/ConstantLengthComparison/ConstantLengthComparison.qlref +++ b/go/ql/test/query-tests/InconsistentCode/ConstantLengthComparison/ConstantLengthComparison.qlref @@ -1 +1,2 @@ -InconsistentCode/ConstantLengthComparison.ql +query: InconsistentCode/ConstantLengthComparison.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/InconsistentLoopOrientation.go b/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/InconsistentLoopOrientation.go index 077015ced99..cda530aec6a 100644 --- a/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/InconsistentLoopOrientation.go +++ b/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/InconsistentLoopOrientation.go @@ -7,7 +7,7 @@ func zeroOutExceptBad(a []int, lower int, upper int) { } // zero out everything above index `upper` - for i := upper + 1; i < len(a); i-- { // NOT OK + for i := upper + 1; i < len(a); i-- { // $ Alert // NOT OK a[i] = 0 } } diff --git a/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/InconsistentLoopOrientation.qlref b/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/InconsistentLoopOrientation.qlref index 62ab35e2257..336261fde23 100644 --- a/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/InconsistentLoopOrientation.qlref +++ b/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/InconsistentLoopOrientation.qlref @@ -1 +1,2 @@ -InconsistentCode/InconsistentLoopOrientation.ql +query: InconsistentCode/InconsistentLoopOrientation.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/main.go b/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/main.go index ede1c5878fb..4cb6e1feac7 100644 --- a/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/main.go +++ b/go/ql/test/query-tests/InconsistentCode/InconsistentLoopOrientation/main.go @@ -6,12 +6,12 @@ func f1(i int) { } func f2(i int, s string) { - for j := i + 1; j < len(s); j-- { // NOT OK + for j := i + 1; j < len(s); j-- { // $ Alert // NOT OK } } func f3(s string) { - for i, l := 0, len(s); i > l; i++ { // NOT OK + for i, l := 0, len(s); i > l; i++ { // $ Alert // NOT OK } } @@ -22,7 +22,7 @@ func f4(lower int, a []int) { } func f5(upper int, a []int) { - for i := upper + 1; i < len(a); i-- { // NOT OK + for i := upper + 1; i < len(a); i-- { // $ Alert // NOT OK a[i] = 0 } } diff --git a/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/LengthComparisonOffByOne.go b/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/LengthComparisonOffByOne.go index 7db63c62bfe..965178e2cdc 100644 --- a/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/LengthComparisonOffByOne.go +++ b/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/LengthComparisonOffByOne.go @@ -5,9 +5,9 @@ import "strings" func containsBad(searchName string, names string) bool { values := strings.Split(names, ",") // BAD: index could be equal to length - for i := 0; i <= len(values); i++ { + for i := 0; i <= len(values); i++ { // $ Alert // When i = length, this access will be out of bounds - if values[i] == searchName { + if values[i] == searchName { // $ Source return true } } diff --git a/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/LengthComparisonOffByOne.qlref b/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/LengthComparisonOffByOne.qlref index 8692ba8a17d..ddd036de50a 100644 --- a/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/LengthComparisonOffByOne.qlref +++ b/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/LengthComparisonOffByOne.qlref @@ -1 +1,2 @@ -InconsistentCode/LengthComparisonOffByOne.ql +query: InconsistentCode/LengthComparisonOffByOne.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/main.go b/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/main.go index 3a426dc554d..01e849c0f2f 100644 --- a/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/main.go +++ b/go/ql/test/query-tests/InconsistentCode/LengthComparisonOffByOne/main.go @@ -3,8 +3,8 @@ package main import "regexp" func f1(i int, a []int) int { - if i <= len(a) { // NOT OK - return a[i] + if i <= len(a) { // $ Alert // NOT OK + return a[i] // $ Source } return -1 } @@ -26,8 +26,8 @@ func f3(i int, a []int) int { } func f4(i int, a []int) int { - if len(a) > 0 { // NOT OK - return a[1] + if len(a) > 0 { // $ Alert // NOT OK + return a[1] // $ Source } return -1 } diff --git a/go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/MissingErrorCheck.qlref b/go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/MissingErrorCheck.qlref index 519bdd54e68..c70c6a57526 100644 --- a/go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/MissingErrorCheck.qlref +++ b/go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/MissingErrorCheck.qlref @@ -1 +1,2 @@ -InconsistentCode/MissingErrorCheck.ql +query: InconsistentCode/MissingErrorCheck.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/tests.go b/go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/tests.go index da60b272bbe..1f45bbbf4e2 100644 --- a/go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/tests.go +++ b/go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/tests.go @@ -58,7 +58,7 @@ func missingCheckMayFail(fname string) { result, err := os.Open(fname) - fmt.Printf("Opened: %v\n", *result) // NOT OK + fmt.Printf("Opened: %v\n", *result) // $ Alert // NOT OK fmt.Printf("%v\n", err) // use err } @@ -240,7 +240,7 @@ func mishandlesMyError(input int) { result, err := returnsMyError(input) - fmt.Printf("Got: %d\n", *result) // NOT OK + fmt.Printf("Got: %d\n", *result) // $ Alert // NOT OK fmt.Printf("%v\n", err) // use err } diff --git a/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/MistypedExponentiation.go b/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/MistypedExponentiation.go index f6e3108f581..0ae2c8a0afb 100644 --- a/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/MistypedExponentiation.go +++ b/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/MistypedExponentiation.go @@ -3,5 +3,5 @@ package main import "fmt" func test() { - fmt.Println(2 ^ 32) // should be 1 << 32 + fmt.Println(2 ^ 32) // $ Alert // should be 1 << 32 } diff --git a/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/MistypedExponentiation.qlref b/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/MistypedExponentiation.qlref index bd96eb93eb4..40b505ceca2 100644 --- a/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/MistypedExponentiation.qlref +++ b/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/MistypedExponentiation.qlref @@ -1 +1,2 @@ -InconsistentCode/MistypedExponentiation.ql +query: InconsistentCode/MistypedExponentiation.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/main.go b/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/main.go index b8b4be44847..5aa436eb08f 100644 --- a/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/main.go +++ b/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/main.go @@ -12,13 +12,13 @@ func main() { expectingResponse := 1 << 5 power := 10 - fmt.Println(3 ^ 5) // Not OK + fmt.Println(3 ^ 5) // $ Alert // Not OK fmt.Println(0755 ^ 2423) // OK - fmt.Println(2 ^ 32) // Not OK - fmt.Println(10 ^ 5) // Not OK - fmt.Println(10 ^ exp) // Not OK + fmt.Println(2 ^ 32) // $ Alert // Not OK + fmt.Println(10 ^ 5) // $ Alert // Not OK + fmt.Println(10 ^ exp) // $ Alert // Not OK fmt.Println(253 ^ expectingResponse) // OK - fmt.Println(2 ^ power) // Not OK + fmt.Println(2 ^ power) // $ Alert // Not OK mask := (((1 << 10) - 1) ^ 7) // OK diff --git a/go/ql/test/query-tests/InconsistentCode/WhitespaceContradictsPrecedence/WhitespaceContradictsPrecedence.go b/go/ql/test/query-tests/InconsistentCode/WhitespaceContradictsPrecedence/WhitespaceContradictsPrecedence.go index ee6987ec931..bee4b5921b0 100644 --- a/go/ql/test/query-tests/InconsistentCode/WhitespaceContradictsPrecedence/WhitespaceContradictsPrecedence.go +++ b/go/ql/test/query-tests/InconsistentCode/WhitespaceContradictsPrecedence/WhitespaceContradictsPrecedence.go @@ -3,5 +3,5 @@ package main // autoformat-ignore (otherwise gofmt will fix the spacing to reflect precedence) func isBitSetBad(x int, pos uint) bool { - return x & 1<> 1; + return x+x >> 1; // $ Alert } func ok3(x int) int { diff --git a/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.go b/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.go index 70ccce77ba7..d5901800cbb 100644 --- a/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.go +++ b/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.go @@ -28,7 +28,7 @@ func test1(input string) error { } if ok2, _ := f2(input); !ok2 { // BAD: Wrapped error is always nil - return errors.Wrap(err, "") + return errors.Wrap(err, "") // $ Alert } return nil } @@ -38,13 +38,13 @@ func test2(err error) { errors.Wrap(err, "") // BAD: Wrapped error is always nil - errors.Wrap(nil, "") + errors.Wrap(nil, "") // $ Alert err = nil // BAD: Wrapped error is always nil - errors.Wrap(err, "") + errors.Wrap(err, "") // $ Alert var localErr error = nil // BAD: Wrapped error is always nil - errors.Wrap(localErr, "") + errors.Wrap(localErr, "") // $ Alert } diff --git a/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.qlref b/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.qlref index bad618814a1..03f9d3ebda1 100644 --- a/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.qlref +++ b/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.qlref @@ -1 +1,2 @@ -InconsistentCode/WrappedErrorAlwaysNil.ql +query: InconsistentCode/WrappedErrorAlwaysNil.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/CompareIdenticalValues.go b/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/CompareIdenticalValues.go index b096cdf5cec..594d8cfcca1 100644 --- a/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/CompareIdenticalValues.go +++ b/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/CompareIdenticalValues.go @@ -6,7 +6,7 @@ type Rectangle struct { func (r *Rectangle) containsBad(x, y int) bool { return r.x <= x && - y <= y && // NOT OK + y <= y && // $ Alert // NOT OK x <= r.x+r.width && y <= r.y+r.height } diff --git a/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/CompareIdenticalValues.qlref b/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/CompareIdenticalValues.qlref index 7c3ac7ace2b..e9d5bb357fd 100644 --- a/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/CompareIdenticalValues.qlref +++ b/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/CompareIdenticalValues.qlref @@ -1 +1,2 @@ -RedundantCode/CompareIdenticalValues.ql +query: RedundantCode/CompareIdenticalValues.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/tst.go b/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/tst.go index 935e71bab99..fbe842b669c 100644 --- a/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/tst.go +++ b/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/tst.go @@ -3,7 +3,7 @@ package main import "fmt" func foo(x int) bool { - return x == x // NOT OK + return x == x // $ Alert // NOT OK } func isNaN(x float32) bool { @@ -57,5 +57,5 @@ func baz2() bool { func baz3() bool { var y counter y.bimp() - return y == 0 // NOT OK + return y == 0 // $ Alert // NOT OK } diff --git a/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/vp.go b/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/vp.go index 64e070e660e..9087a589500 100644 --- a/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/vp.go +++ b/go/ql/test/query-tests/RedundantCode/CompareIdenticalValues/vp.go @@ -13,5 +13,5 @@ type t struct { } func (x *t) foo(other t) bool { - return x.GetLength() != x.GetLength() + return x.GetLength() != x.GetLength() // $ Alert } diff --git a/go/ql/test/query-tests/RedundantCode/DeadStoreOfField/DeadStoreOfField.go b/go/ql/test/query-tests/RedundantCode/DeadStoreOfField/DeadStoreOfField.go index b74b7312a7f..7e1328e5a33 100644 --- a/go/ql/test/query-tests/RedundantCode/DeadStoreOfField/DeadStoreOfField.go +++ b/go/ql/test/query-tests/RedundantCode/DeadStoreOfField/DeadStoreOfField.go @@ -5,5 +5,5 @@ type counter struct { } func (w counter) reset() { - w.val = 0 // NOT OK + w.val = 0 // $ Alert // NOT OK } diff --git a/go/ql/test/query-tests/RedundantCode/DeadStoreOfField/DeadStoreOfField.qlref b/go/ql/test/query-tests/RedundantCode/DeadStoreOfField/DeadStoreOfField.qlref index 90aa8beb7ad..1fa9500a954 100644 --- a/go/ql/test/query-tests/RedundantCode/DeadStoreOfField/DeadStoreOfField.qlref +++ b/go/ql/test/query-tests/RedundantCode/DeadStoreOfField/DeadStoreOfField.qlref @@ -1 +1,2 @@ -RedundantCode/DeadStoreOfField.ql +query: RedundantCode/DeadStoreOfField.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/DeadStoreOfLocal.qlref b/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/DeadStoreOfLocal.qlref index 9acb5d81615..5e4405270c0 100644 --- a/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/DeadStoreOfLocal.qlref +++ b/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/DeadStoreOfLocal.qlref @@ -1 +1,2 @@ -RedundantCode/DeadStoreOfLocal.ql +query: RedundantCode/DeadStoreOfLocal.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/main.go b/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/main.go index 31062a18f98..ee7b9214a66 100644 --- a/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/main.go +++ b/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/main.go @@ -22,7 +22,7 @@ func main() { } func deadParameter(x int) bool { // we don't want to flag x here - x = deadStore() // but we do want to flag this + x = deadStore() // $ Alert // but we do want to flag this return true } diff --git a/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/testdata.go b/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/testdata.go index dad31ebd1ae..da7d6db82c3 100644 --- a/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/testdata.go +++ b/go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/testdata.go @@ -29,12 +29,12 @@ func _() { func _() { var x int _ = x - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD } func _() { var x int - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD x = 0 _ = x } @@ -58,13 +58,13 @@ func _() { } func _() { - x := deadStore2() // BAD + x := deadStore2() // $ Alert // BAD x = "def" _ = x } func _() { - x := deadStore() // BAD + x := deadStore() // $ Alert // BAD x = 0 _ = x } @@ -96,18 +96,18 @@ func _() { } func _() { - x := deadStore() // BAD + x := deadStore() // $ Alert // BAD if b { - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD } x = 0 _ = x } func _() { - x := deadStore() // BAD + x := deadStore() // $ Alert // BAD for b { - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD } x = 0 _ = x @@ -125,13 +125,13 @@ func _() { } func _() { - x := deadStore() // BAD + x := deadStore() // $ Alert // BAD if b { - x = deadStore() // BAD - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD + x = deadStore() // $ Alert // BAD } if b { - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD } x = 0 _ = x @@ -140,7 +140,7 @@ func _() { func _() { x := 0 if b { - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD x = 0 } if b { @@ -161,7 +161,7 @@ func _() { x := 0 for { _ = x - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD x = 0 } } @@ -169,7 +169,7 @@ func _() { func _() { x := 0 for { - x += deadStore() // BAD + x += deadStore() // $ Alert // BAD x = 0 } } @@ -177,7 +177,7 @@ func _() { func _() { x := 0 for { - x++ // BAD + x++ // $ Alert // BAD x = 0 } } @@ -198,7 +198,7 @@ func _() { func _() { x := struct{ f int }{42} _ = x.f - x = struct{ f int }{23} + x = struct{ f int }{23} // $ Alert } func _() { @@ -259,13 +259,13 @@ func _() (x int) { } func _() (x int) { - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD x = 0 return } func _() (x int) { - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD return 0 } @@ -306,7 +306,7 @@ func _(a float32, b float32) (x int) { func _(a float32, b float32) (x int) { x = 1 - a /= b + a /= b // $ Alert return 2 } @@ -318,7 +318,7 @@ func _(a int, b int) (x int) { func _(a int, b int) (x int) { x = 1 - a %= b + a %= b // $ Alert return 2 } @@ -384,7 +384,7 @@ func _() { case true: _ = x default: - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD fallthrough case b: } @@ -429,16 +429,16 @@ func _() { var ch chan int select { case ch <- 0: - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD case <-ch: - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD default: _ = x } } func _() { - x := deadStore() // BAD + x := deadStore() // $ Alert // BAD var ch chan int select { case ch <- 0: @@ -485,7 +485,7 @@ func _() { func _() { var x int if b { - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD } if x = 0; b { @@ -539,7 +539,7 @@ func _() { func _() { x := 0 for x < 0 { - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD if b { break } @@ -577,7 +577,7 @@ func _() { var x int for { if b { - x = deadStore() // BAD + x = deadStore() // $ Alert // BAD break } _ = x @@ -626,7 +626,7 @@ func _(v1, v2 int32) (int32, int32) { func _(v1, v2 int32) (int32, int32) { if v1 > v2 { - v1, _ = v2, v1 + v1, _ = v2, v1 // $ Alert } v1, v2 = 0, 0 return v1, v2 diff --git a/go/ql/test/query-tests/RedundantCode/DuplicateBranches/DuplicateBranches.go b/go/ql/test/query-tests/RedundantCode/DuplicateBranches/DuplicateBranches.go index f4bc36b63fe..1f163c2867f 100644 --- a/go/ql/test/query-tests/RedundantCode/DuplicateBranches/DuplicateBranches.go +++ b/go/ql/test/query-tests/RedundantCode/DuplicateBranches/DuplicateBranches.go @@ -1,7 +1,7 @@ package main func abs(x int) int { - if x >= 0 { + if x >= 0 { // $ Alert return x } else { return x diff --git a/go/ql/test/query-tests/RedundantCode/DuplicateBranches/DuplicateBranches.qlref b/go/ql/test/query-tests/RedundantCode/DuplicateBranches/DuplicateBranches.qlref index 3eb10d9d91f..a32bc6c31f1 100644 --- a/go/ql/test/query-tests/RedundantCode/DuplicateBranches/DuplicateBranches.qlref +++ b/go/ql/test/query-tests/RedundantCode/DuplicateBranches/DuplicateBranches.qlref @@ -1 +1,2 @@ -RedundantCode/DuplicateBranches.ql +query: RedundantCode/DuplicateBranches.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/DuplicateBranches/main.go b/go/ql/test/query-tests/RedundantCode/DuplicateBranches/main.go index 0a524b094a7..9e367783550 100644 --- a/go/ql/test/query-tests/RedundantCode/DuplicateBranches/main.go +++ b/go/ql/test/query-tests/RedundantCode/DuplicateBranches/main.go @@ -3,7 +3,7 @@ package main import "fmt" func bad(x int) { - if x < 0 { // NOT OK + if x < 0 { // $ Alert // NOT OK fmt.Println("x is negative") } else { fmt.Println("x is negative") diff --git a/go/ql/test/query-tests/RedundantCode/DuplicateCondition/DuplicateCondition.go b/go/ql/test/query-tests/RedundantCode/DuplicateCondition/DuplicateCondition.go index a93bb546c42..2ad4ad8e0e4 100644 --- a/go/ql/test/query-tests/RedundantCode/DuplicateCondition/DuplicateCondition.go +++ b/go/ql/test/query-tests/RedundantCode/DuplicateCondition/DuplicateCondition.go @@ -1,9 +1,9 @@ package main func controller(msg string) { - if msg == "start" { + if msg == "start" { // $ Source start() - } else if msg == "start" { // NOT OK + } else if msg == "start" { // $ Alert // NOT OK stop() } else { panic("Message not understood.") diff --git a/go/ql/test/query-tests/RedundantCode/DuplicateCondition/DuplicateCondition.qlref b/go/ql/test/query-tests/RedundantCode/DuplicateCondition/DuplicateCondition.qlref index a6069ea94ad..36bb8140f1a 100644 --- a/go/ql/test/query-tests/RedundantCode/DuplicateCondition/DuplicateCondition.qlref +++ b/go/ql/test/query-tests/RedundantCode/DuplicateCondition/DuplicateCondition.qlref @@ -1 +1,2 @@ -RedundantCode/DuplicateCondition.ql +query: RedundantCode/DuplicateCondition.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/DuplicateCondition/tst.go b/go/ql/test/query-tests/RedundantCode/DuplicateCondition/tst.go index 912f13fef7e..60e88d978f6 100644 --- a/go/ql/test/query-tests/RedundantCode/DuplicateCondition/tst.go +++ b/go/ql/test/query-tests/RedundantCode/DuplicateCondition/tst.go @@ -5,8 +5,8 @@ func check(x int) bool { } func main() { - if ok := check(42); ok { - } else if ok { // NOT OK + if ok := check(42); ok { // $ Source + } else if ok { // $ Alert // NOT OK } else if ok := check(23); ok { // OK } } diff --git a/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/DuplicateSwitchCase.go b/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/DuplicateSwitchCase.go index 1c902c1328b..d2b1d320f33 100644 --- a/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/DuplicateSwitchCase.go +++ b/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/DuplicateSwitchCase.go @@ -4,7 +4,7 @@ func controller(msg string) { switch { case msg == "start": start() - case msg == "start": + case msg == "start": // $ Alert stop() default: panic("Message not understood.") diff --git a/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/DuplicateSwitchCase.qlref b/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/DuplicateSwitchCase.qlref index 570b78b5054..005bb508043 100644 --- a/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/DuplicateSwitchCase.qlref +++ b/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/DuplicateSwitchCase.qlref @@ -1 +1,2 @@ -RedundantCode/DuplicateSwitchCase.ql +query: RedundantCode/DuplicateSwitchCase.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/tst.go b/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/tst.go index c927cd3d686..235be408143 100644 --- a/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/tst.go +++ b/go/ql/test/query-tests/RedundantCode/DuplicateSwitchCase/tst.go @@ -6,7 +6,7 @@ func check(x int) { case x < 42: - case x < 23: // NOT OK + case x < 23: // $ Alert // NOT OK } } diff --git a/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/ExprHasNoEffect.go b/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/ExprHasNoEffect.go index 3c8b85f1e67..3b647bc2a8a 100644 --- a/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/ExprHasNoEffect.go +++ b/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/ExprHasNoEffect.go @@ -10,6 +10,6 @@ func (t Timestamp) addDays(d int) Timestamp { func test(t Timestamp) { fmt.Printf("Before: %s\n", t) - t.addDays(7) + t.addDays(7) // $ Alert fmt.Printf("After: %s\n", t) } diff --git a/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/ExprHasNoEffect.qlref b/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/ExprHasNoEffect.qlref index d13ada43194..bb442613246 100644 --- a/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/ExprHasNoEffect.qlref +++ b/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/ExprHasNoEffect.qlref @@ -1 +1,2 @@ -RedundantCode/ExprHasNoEffect.ql +query: RedundantCode/ExprHasNoEffect.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/main.go b/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/main.go index e9c18030df5..960260b1fce 100644 --- a/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/main.go +++ b/go/ql/test/query-tests/RedundantCode/ExprHasNoEffect/main.go @@ -23,10 +23,10 @@ func div(x int, y int) int { } func main() { - f1(42) // NOT OK + f1(42) // $ Alert // NOT OK f2(42) // OK - f1(f2(42)) // NOT OK - abs(-2) // NOT OK + f1(f2(42)) // $ Alert // NOT OK + abs(-2) // $ Alert // NOT OK div(1, 0) // OK dostuff() // OK cleanup() // OK diff --git a/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/ImpossibleInterfaceNilCheck.go b/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/ImpossibleInterfaceNilCheck.go index 00b015d3814..f0013365e1f 100644 --- a/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/ImpossibleInterfaceNilCheck.go +++ b/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/ImpossibleInterfaceNilCheck.go @@ -6,7 +6,7 @@ func niceFetch(url string) { var s string var e error s, e = fetch(url) - if e != nil { + if e != nil { // $ Alert fmt.Printf("Unable to fetch URL: %v\n", e) } else { fmt.Printf("URL contents: %s\n", s) diff --git a/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/ImpossibleInterfaceNilCheck.qlref b/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/ImpossibleInterfaceNilCheck.qlref index d858724be57..0049d67433a 100644 --- a/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/ImpossibleInterfaceNilCheck.qlref +++ b/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/ImpossibleInterfaceNilCheck.qlref @@ -1 +1,2 @@ -RedundantCode/ImpossibleInterfaceNilCheck.ql +query: RedundantCode/ImpossibleInterfaceNilCheck.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/tst.go b/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/tst.go index 81584045c13..e7716a7584a 100644 --- a/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/tst.go +++ b/go/ql/test/query-tests/RedundantCode/ImpossibleInterfaceNilCheck/tst.go @@ -7,7 +7,7 @@ func test1() { var y interface{} = x fmt.Println(x == nil) fmt.Println(x == y) - fmt.Println(y == nil) // NOT OK + fmt.Println(y == nil) // $ Alert // NOT OK } func test2() { diff --git a/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/NegativeLengthCheck.go b/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/NegativeLengthCheck.go index 6ebdb224ee1..9c7460b9432 100644 --- a/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/NegativeLengthCheck.go +++ b/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/NegativeLengthCheck.go @@ -1,7 +1,7 @@ package main func getFirst(xs []int) int { - if len(xs) < 0 { + if len(xs) < 0 { // $ Alert panic("No elements provided") } return xs[0] diff --git a/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/NegativeLengthCheck.qlref b/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/NegativeLengthCheck.qlref index d3e9be220bf..de3ae728414 100644 --- a/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/NegativeLengthCheck.qlref +++ b/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/NegativeLengthCheck.qlref @@ -1 +1,2 @@ -RedundantCode/NegativeLengthCheck.ql +query: RedundantCode/NegativeLengthCheck.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/main.go b/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/main.go index f43f4851c5f..9b145e293e2 100644 --- a/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/main.go +++ b/go/ql/test/query-tests/RedundantCode/NegativeLengthCheck/main.go @@ -3,7 +3,7 @@ package main import "os" func main() { - if len(os.Args) < 0 { // NOT OK + if len(os.Args) < 0 { // $ Alert // NOT OK println("No arguments provided.") } @@ -11,21 +11,21 @@ func main() { println("No arguments provided.") } - if cap(os.Args) < 0 { // NOT OK + if cap(os.Args) < 0 { // $ Alert // NOT OK println("Out of space!") } - if len(os.Args) <= -1 { // NOT OK + if len(os.Args) <= -1 { // $ Alert // NOT OK println("No arguments provided.") } - if len(os.Args) == -1 { // NOT OK + if len(os.Args) == -1 { // $ Alert // NOT OK println("No arguments provided.") } } func checkNegative(x uint) bool { - return x < 0 // NOT OK + return x < 0 // $ Alert // NOT OK } func checkNonPositive(x uint) bool { diff --git a/go/ql/test/query-tests/RedundantCode/RedundantExpr/RedundantExpr.go b/go/ql/test/query-tests/RedundantCode/RedundantExpr/RedundantExpr.go index 033f3883b0a..283d0552be8 100644 --- a/go/ql/test/query-tests/RedundantCode/RedundantExpr/RedundantExpr.go +++ b/go/ql/test/query-tests/RedundantCode/RedundantExpr/RedundantExpr.go @@ -1,5 +1,5 @@ package main func avg(x, y float64) float64 { - return (x + x) / 2 + return (x + x) / 2 // $ Alert } diff --git a/go/ql/test/query-tests/RedundantCode/RedundantExpr/RedundantExpr.qlref b/go/ql/test/query-tests/RedundantCode/RedundantExpr/RedundantExpr.qlref index 23a5db7b419..f9c95d27835 100644 --- a/go/ql/test/query-tests/RedundantCode/RedundantExpr/RedundantExpr.qlref +++ b/go/ql/test/query-tests/RedundantCode/RedundantExpr/RedundantExpr.qlref @@ -1 +1,2 @@ -RedundantCode/RedundantExpr.ql +query: RedundantCode/RedundantExpr.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/RedundantExpr/tst.go b/go/ql/test/query-tests/RedundantCode/RedundantExpr/tst.go index e4106fb7bfa..1a0d38eb2fe 100644 --- a/go/ql/test/query-tests/RedundantCode/RedundantExpr/tst.go +++ b/go/ql/test/query-tests/RedundantCode/RedundantExpr/tst.go @@ -1,12 +1,12 @@ package main func foo(x int) int { - return x - x /* NOT OK */ + (x & x) /* NOT OK */ + return x - x /* NOT OK */ + (x & x) /* NOT OK */ // $ Alert } func bar(b bool, x float32) float32 { if b { - return (x + x) / 2 // NOT OK + return (x + x) / 2 // $ Alert // NOT OK } else { return (x * x) / 2 // OK } diff --git a/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover.qlref b/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover.qlref index c8997068734..3f91b000a4c 100644 --- a/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover.qlref +++ b/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover.qlref @@ -1 +1,2 @@ -RedundantCode/RedundantRecover.ql +query: RedundantCode/RedundantRecover.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover1.go b/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover1.go index d058dd0dfde..3a9cc3f9cc2 100644 --- a/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover1.go +++ b/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover1.go @@ -3,7 +3,7 @@ package main import "fmt" func callRecover1() { - if recover() != nil { + if recover() != nil { // $ Alert fmt.Printf("recovered") } } diff --git a/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover2.go b/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover2.go index 4365cb7c9fe..2627373ad27 100644 --- a/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover2.go +++ b/go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover2.go @@ -1,6 +1,6 @@ package main func fun2() { - defer recover() + defer recover() // $ Alert panic("2") } diff --git a/go/ql/test/query-tests/RedundantCode/RedundantRecover/tst.go b/go/ql/test/query-tests/RedundantCode/RedundantRecover/tst.go index 0533a060931..c9bebbd4bfe 100644 --- a/go/ql/test/query-tests/RedundantCode/RedundantRecover/tst.go +++ b/go/ql/test/query-tests/RedundantCode/RedundantRecover/tst.go @@ -5,7 +5,7 @@ import "fmt" func callRecover3() { // This will have no effect because panics do not propagate down the stack, // only back up the stack - if recover() != nil { + if recover() != nil { // $ Alert fmt.Printf("recovered") } } diff --git a/go/ql/test/query-tests/RedundantCode/SelfAssignment/SelfAssignment.go b/go/ql/test/query-tests/RedundantCode/SelfAssignment/SelfAssignment.go index ab2e585e198..00b971db61a 100644 --- a/go/ql/test/query-tests/RedundantCode/SelfAssignment/SelfAssignment.go +++ b/go/ql/test/query-tests/RedundantCode/SelfAssignment/SelfAssignment.go @@ -9,5 +9,5 @@ func (r *Rect) setWidth(width int) { } func (r *Rect) setHeight(height int) { - height = height + height = height // $ Alert } diff --git a/go/ql/test/query-tests/RedundantCode/SelfAssignment/SelfAssignment.qlref b/go/ql/test/query-tests/RedundantCode/SelfAssignment/SelfAssignment.qlref index 3eebdc5dc73..fcdd1725603 100644 --- a/go/ql/test/query-tests/RedundantCode/SelfAssignment/SelfAssignment.qlref +++ b/go/ql/test/query-tests/RedundantCode/SelfAssignment/SelfAssignment.qlref @@ -1 +1,2 @@ -RedundantCode/SelfAssignment.ql +query: RedundantCode/SelfAssignment.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/SelfAssignment/tst.go b/go/ql/test/query-tests/RedundantCode/SelfAssignment/tst.go index 31a556ce551..fef980cdc15 100644 --- a/go/ql/test/query-tests/RedundantCode/SelfAssignment/tst.go +++ b/go/ql/test/query-tests/RedundantCode/SelfAssignment/tst.go @@ -2,5 +2,5 @@ package main func main() { x := 42 - x = x // NOT OK + x = x // $ Alert // NOT OK } diff --git a/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/ShiftOutOfRange.go b/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/ShiftOutOfRange.go index aaa05763ce2..64d1383393d 100644 --- a/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/ShiftOutOfRange.go +++ b/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/ShiftOutOfRange.go @@ -1,7 +1,7 @@ package main func shift(base int32) int32 { - return base << 40 + return base << 40 // $ Alert } var x1 = shift(1) diff --git a/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/ShiftOutOfRange.qlref b/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/ShiftOutOfRange.qlref index 223322f9776..2920410dfeb 100644 --- a/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/ShiftOutOfRange.qlref +++ b/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/ShiftOutOfRange.qlref @@ -1 +1,2 @@ -RedundantCode/ShiftOutOfRange.ql +query: RedundantCode/ShiftOutOfRange.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/main.go b/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/main.go index 4afb91d1750..22d68cc6bac 100644 --- a/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/main.go +++ b/go/ql/test/query-tests/RedundantCode/ShiftOutOfRange/main.go @@ -1,15 +1,15 @@ package main func bad1(x uint8) uint8 { - return x << 8 // NOT OK + return x << 8 // $ Alert // NOT OK } func bad2(y int32) int32 { - return y >> 33 // NOT OK + return y >> 33 // $ Alert // NOT OK } func bad3(z int) int { - return z << 64 // NOT OK + return z << 64 // $ Alert // NOT OK } func good1(x uint8) uint8 { diff --git a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.go b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.go index 10250238158..a11218b99e1 100644 --- a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.go +++ b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.go @@ -2,7 +2,7 @@ package main func mul(xs []int) int { res := 1 - for i := 0; i < len(xs); i++ { + for i := 0; i < len(xs); i++ { // $ Alert x := xs[i] res *= x if res == 0 { diff --git a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.qlref b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.qlref index 645ea622227..a705d9b8cff 100644 --- a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.qlref +++ b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.qlref @@ -1 +1,2 @@ -RedundantCode/UnreachableStatement.ql +query: RedundantCode/UnreachableStatement.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go index 7903ef1ef84..cc26b717f60 100644 --- a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go +++ b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go @@ -10,16 +10,16 @@ func reachable() {} func test1() { return - unreachable() // NOT OK + unreachable() // $ Alert // NOT OK } func test2() { select {} - unreachable() // NOT OK + unreachable() // $ Alert // NOT OK } func test3() { - for i := 0; i < 10; unreachable() { // NOT OK + for i := 0; i < 10; unreachable() { // $ Alert // NOT OK return } } @@ -27,7 +27,7 @@ func test3() { func test4() { for true { } - unreachable() // NOT OK + unreachable() // $ Alert // NOT OK } func test5(cond bool) { @@ -46,15 +46,15 @@ func test6(cond bool) { } reachable() } - unreachable() // NOT OK + unreachable() // $ Alert // NOT OK } func test7(cond bool) { for true { continue - unreachable() // NOT OK + unreachable() // $ Alert // NOT OK } - unreachable() // NOT OK + unreachable() // $ Alert // NOT OK } func test8() { @@ -138,25 +138,25 @@ func test16() *mystruct { select {} // Flagged, as `return nil` is possible and preferable when the // return site is unreachable. - return &mystruct{0, true} + return &mystruct{0, true} // $ Alert } func test17() int { select {} // Flagged, as a nontrivial unreachable return - return test10(1) + return test10(1) // $ Alert } func test18() bool { select {} // Flagged, as a nontrivial unreachable return - return test10(1) == 1 + return test10(1) == 1 // $ Alert } func test19() mystruct { select {} // Flagged, as a nontrivial unreachable return - return mystruct{test10(1), test10(2) == 2} + return mystruct{test10(1), test10(2) == 2} // $ Alert } func main() {} diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.go b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.go index 073c8555efc..3f290ccf983 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.go +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.go @@ -8,8 +8,8 @@ import ( func checkRedirect(req *http.Request, via []*http.Request) error { // BAD: the host of `req.URL` may be controlled by an attacker - re := "^((www|beta).)?example.com/" - if matched, _ := regexp.MatchString(re, req.URL.Host); matched { + re := "^((www|beta).)?example.com/" // $ Alert + if matched, _ := regexp.MatchString(re, req.URL.Host); matched { // $ Sink return nil } return errors.New("Invalid redirect") diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.qlref b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.qlref index 88d20f52eee..0a6dac4bded 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.qlref +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.qlref @@ -1,2 +1,4 @@ query: Security/CWE-020/IncompleteHostnameRegexp.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go index 7eda0d7255a..d677cab50d4 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/main.go @@ -37,30 +37,30 @@ func proxy() { HandleConnect(goproxy.AlwaysReject) // OK (rejecting all requests) proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^test1.github.com$"))). DoFunc(reject) // OK (rejecting all requests) - proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^test2.github.com$"))). - DoFunc(sometimesReject) // NOT OK (sometimes accepts requests) + proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^test2.github.com$"))). // $ Alert + DoFunc(sometimesReject) // NOT OK (sometimes accepts requests) } func main() { - regexp.Match(`https://www.example.com`, []byte("")) // NOT OK + regexp.Match(`https://www.example.com`, []byte("")) // $ Alert // NOT OK regexp.Match(`https://www\.example\.com`, []byte("")) // OK } -const sourceConst = `https://www.example.com` +const sourceConst = `https://www.example.com` // $ Alert const firstHalfConst = `https://www.example.` func concatenateStrings() { firstHalf := `https://www.example.` regexp.Match(firstHalf+`com`, []byte("")) // MISSING: NOT OK - regexp.Match(firstHalfConst+`com`, []byte("")) // NOT OK + regexp.Match(firstHalfConst+`com`, []byte("")) // $ Alert // NOT OK - regexp.Match(`https://www.example.`+`com`, []byte("")) // NOT OK + regexp.Match(`https://www.example.`+`com`, []byte("")) // $ Alert // NOT OK } func avoidDuplicateResults() { localVar1 := sourceConst localVar2 := localVar1 localVar3 := localVar2 - regexp.Match(localVar3, []byte("")) // NOT OK + regexp.Match(localVar3, []byte("")) // $ Sink // NOT OK } diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/IncompleteUrlSchemeCheck.go b/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/IncompleteUrlSchemeCheck.go index f38261a032d..69221d5c212 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/IncompleteUrlSchemeCheck.go +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/IncompleteUrlSchemeCheck.go @@ -4,7 +4,7 @@ import "net/url" func sanitizeUrl(urlstr string) string { u, err := url.Parse(urlstr) - if err != nil || u.Scheme == "javascript" { + if err != nil || u.Scheme == "javascript" { // $ Alert return "about:blank" } return urlstr diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/IncompleteUrlSchemeCheck.qlref b/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/IncompleteUrlSchemeCheck.qlref index b27571781b3..0c088087e99 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/IncompleteUrlSchemeCheck.qlref +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/IncompleteUrlSchemeCheck.qlref @@ -1 +1,2 @@ -Security/CWE-020/IncompleteUrlSchemeCheck.ql +query: Security/CWE-020/IncompleteUrlSchemeCheck.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/main.go b/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/main.go index ebe18f142f8..8b96f7c0af8 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/main.go +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteUrlSchemeCheck/main.go @@ -14,7 +14,7 @@ func test(urlstr string) { urlstr = strings.NewReplacer("\n", "", "\r", "", "\t", "", "\u0000", "").Replace(urlstr) urlstr = strings.ToLower(urlstr) - if strings.HasPrefix(urlstr, "javascript:") || strings.HasPrefix(urlstr, "data:") { // NOT OK + if strings.HasPrefix(urlstr, "javascript:") || strings.HasPrefix(urlstr, "data:") { // $ Alert // NOT OK return } } diff --git a/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/MissingRegexpAnchor.go b/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/MissingRegexpAnchor.go index 60cb9d5b6bb..6e7a567cb8c 100644 --- a/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/MissingRegexpAnchor.go +++ b/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/MissingRegexpAnchor.go @@ -8,7 +8,7 @@ import ( func checkRedirect2(req *http.Request, via []*http.Request) error { // BAD: the host of `req.URL` may be controlled by an attacker - re := "https?://www\\.example\\.com/" + re := "https?://www\\.example\\.com/" // $ Alert if matched, _ := regexp.MatchString(re, req.URL.String()); matched { return nil } diff --git a/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/MissingRegexpAnchor.qlref b/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/MissingRegexpAnchor.qlref index b03fcd14a59..ba73933077f 100644 --- a/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/MissingRegexpAnchor.qlref +++ b/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/MissingRegexpAnchor.qlref @@ -1 +1,2 @@ -Security/CWE-020/MissingRegexpAnchor.ql +query: Security/CWE-020/MissingRegexpAnchor.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/main.go b/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/main.go index efd10b7a6e2..8674e2f2f38 100644 --- a/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/main.go +++ b/go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/main.go @@ -6,36 +6,36 @@ import ( func main() { regexp.Match(`^a|`, []byte("")) // OK - regexp.Match(`^a|b`, []byte("")) // NOT OK + regexp.Match(`^a|b`, []byte("")) // $ Alert // NOT OK regexp.Match(`a|^b`, []byte("")) // OK regexp.Match(`^a|^b`, []byte("")) // OK - regexp.Match(`^a|b|c`, []byte("")) // NOT OK + regexp.Match(`^a|b|c`, []byte("")) // $ Alert // NOT OK regexp.Match(`a|^b|c`, []byte("")) // OK regexp.Match(`a|b|^c`, []byte("")) // OK regexp.Match(`^a|^b|c`, []byte("")) // OK regexp.Match(`(^a)|b`, []byte("")) // OK - regexp.Match(`^a|(b)`, []byte("")) // NOT OK + regexp.Match(`^a|(b)`, []byte("")) // $ Alert // NOT OK regexp.Match(`^a|(^b)`, []byte("")) // OK - regexp.Match(`^(a)|(b)`, []byte("")) // NOT OK + regexp.Match(`^(a)|(b)`, []byte("")) // $ Alert // NOT OK - regexp.Match(`a|b$`, []byte("")) // NOT OK + regexp.Match(`a|b$`, []byte("")) // $ Alert // NOT OK regexp.Match(`a$|b`, []byte("")) // OK regexp.Match(`a$|b$`, []byte("")) // OK - regexp.Match(`a|b|c$`, []byte("")) // NOT OK + regexp.Match(`a|b|c$`, []byte("")) // $ Alert // NOT OK regexp.Match(`a|b$|c`, []byte("")) // OK regexp.Match(`a$|b|c`, []byte("")) // OK regexp.Match(`a|b$|c$`, []byte("")) // OK regexp.Match(`a|(b$)`, []byte("")) // OK - regexp.Match(`(a)|b$`, []byte("")) // NOT OK + regexp.Match(`(a)|b$`, []byte("")) // $ Alert // NOT OK regexp.Match(`(a$)|b$`, []byte("")) // OK - regexp.Match(`(a)|(b)$`, []byte("")) // NOT OK + regexp.Match(`(a)|(b)$`, []byte("")) // $ Alert // NOT OK - regexp.Match(`https?://good.com`, []byte("http://evil.com/?http://good.com")) // NOT OK + regexp.Match(`https?://good.com`, []byte("http://evil.com/?http://good.com")) // $ Alert // NOT OK regexp.Match(`^https?://good.com`, []byte("http://evil.com/?http://good.com")) // OK - regexp.Match(`www\.example\.com`, []byte("")) // NOT OK + regexp.Match(`www\.example\.com`, []byte("")) // $ Alert // NOT OK regexp.Match(`^www\.example\.com`, []byte("")) // OK regexp.Match(`\Awww\.example\.com`, []byte("")) // OK regexp.Match(`www\.example\.com$`, []byte("")) // OK diff --git a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.go b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.go index d9f2199fd52..4194d79c262 100644 --- a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.go +++ b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.go @@ -3,7 +3,7 @@ package main import "regexp" func broken(hostNames []byte) string { - var hostRe = regexp.MustCompile("\bforbidden.host.org") + var hostRe = regexp.MustCompile("\bforbidden.host.org") // $ Alert if hostRe.Match(hostNames) { return "Must not target forbidden.host.org" } else { diff --git a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.qlref b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.qlref index 727f3528b23..17c2ba019cb 100644 --- a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.qlref +++ b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.qlref @@ -1 +1,2 @@ -Security/CWE-020/SuspiciousCharacterInRegexp.ql +query: Security/CWE-020/SuspiciousCharacterInRegexp.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/test.go b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/test.go index ff3da9b8496..a872de93073 100644 --- a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/test.go +++ b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/test.go @@ -4,23 +4,23 @@ import "regexp" func main() { // many backslashes - regexp.MustCompile("\a") // BAD + regexp.MustCompile("\a") // $ Alert // BAD regexp.MustCompile("\\a") - regexp.MustCompile("\\\a") // BAD - regexp.MustCompile("x\\\a") // BAD + regexp.MustCompile("\\\a") // $ Alert // BAD + regexp.MustCompile("x\\\a") // $ Alert // BAD regexp.MustCompile("\\\\a") - regexp.MustCompile("\\\\\a") // BAD + regexp.MustCompile("\\\\\a") // $ Alert // BAD regexp.MustCompile("\\\\\\a") - regexp.MustCompile("\\\\\\\a") // BAD + regexp.MustCompile("\\\\\\\a") // $ Alert // BAD regexp.MustCompile("\\\\\\\\a") - regexp.MustCompile("\\\\\\\\\a") // BAD + regexp.MustCompile("\\\\\\\\\a") // $ Alert // BAD regexp.MustCompile("\\\\\\\\\\a") // BAD: probably a mistake: - regexp.MustCompile("hello\aworld") - regexp.MustCompile("hello\\\aworld") - regexp.MustCompile("hello\bworld") - regexp.MustCompile("hello\\\bworld") + regexp.MustCompile("hello\aworld") // $ Alert + regexp.MustCompile("hello\\\aworld") // $ Alert + regexp.MustCompile("hello\bworld") // $ Alert + regexp.MustCompile("hello\\\bworld") // $ Alert // GOOD: more likely deliberate: regexp.MustCompile("hello\\aworld") regexp.MustCompile("hello\x07world") diff --git a/go/ql/test/query-tests/Security/CWE-022/GorillaMuxDefault/TaintedPath.qlref b/go/ql/test/query-tests/Security/CWE-022/GorillaMuxDefault/TaintedPath.qlref index 1e9166dd1ca..688f7b5136f 100644 --- a/go/ql/test/query-tests/Security/CWE-022/GorillaMuxDefault/TaintedPath.qlref +++ b/go/ql/test/query-tests/Security/CWE-022/GorillaMuxDefault/TaintedPath.qlref @@ -1,2 +1,4 @@ query: Security/CWE-022/TaintedPath.ql -postprocess: utils/test//PrettyPrintModels.ql \ No newline at end of file +postprocess: + - utils/test//PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-022/GorillaMuxSkipClean/MuxClean.go b/go/ql/test/query-tests/Security/CWE-022/GorillaMuxSkipClean/MuxClean.go index cb3b5d2a7b8..2767b5e6b5a 100644 --- a/go/ql/test/query-tests/Security/CWE-022/GorillaMuxSkipClean/MuxClean.go +++ b/go/ql/test/query-tests/Security/CWE-022/GorillaMuxSkipClean/MuxClean.go @@ -10,8 +10,8 @@ import ( // BAD: Gorilla's `Vars` is not a sanitizer as `Router.SkipClean` has been called func GorillaHandler(w http.ResponseWriter, r *http.Request) { - not_tainted_path := mux.Vars(r)["id"] - data, _ := ioutil.ReadFile(filepath.Join("/home/user/", not_tainted_path)) + not_tainted_path := mux.Vars(r)["id"] // $ Source + data, _ := ioutil.ReadFile(filepath.Join("/home/user/", not_tainted_path)) // $ Alert w.Write(data) } diff --git a/go/ql/test/query-tests/Security/CWE-022/GorillaMuxSkipClean/TaintedPath.qlref b/go/ql/test/query-tests/Security/CWE-022/GorillaMuxSkipClean/TaintedPath.qlref index 1e9166dd1ca..688f7b5136f 100644 --- a/go/ql/test/query-tests/Security/CWE-022/GorillaMuxSkipClean/TaintedPath.qlref +++ b/go/ql/test/query-tests/Security/CWE-022/GorillaMuxSkipClean/TaintedPath.qlref @@ -1,2 +1,4 @@ query: Security/CWE-022/TaintedPath.ql -postprocess: utils/test//PrettyPrintModels.ql \ No newline at end of file +postprocess: + - utils/test//PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.go b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.go index 65da5caecd2..812b56f7c94 100644 --- a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.go +++ b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.go @@ -12,14 +12,14 @@ import ( ) func handler(w http.ResponseWriter, r *http.Request) { - tainted_path := r.URL.Query()["path"][0] + tainted_path := r.URL.Query()["path"][0] // $ Source[go/path-injection] // BAD: This could read any file on the file system - data, _ := ioutil.ReadFile(tainted_path) + data, _ := ioutil.ReadFile(tainted_path) // $ Alert[go/path-injection] w.Write(data) // BAD: This could still read any file on the file system - data, _ = ioutil.ReadFile(filepath.Join("/home/user/", tainted_path)) + data, _ = ioutil.ReadFile(filepath.Join("/home/user/", tainted_path)) // $ Alert[go/path-injection] w.Write(data) // GOOD: This can only read inside the provided safe path @@ -71,7 +71,7 @@ func handler(w http.ResponseWriter, r *http.Request) { // BAD: Sanitized by path.Clean with a prepended '/' forcing interpretation // as an absolute path, however is not sufficient for Windows paths. - data, _ = ioutil.ReadFile(path.Clean("/" + tainted_path)) + data, _ = ioutil.ReadFile(path.Clean("/" + tainted_path)) // $ Alert[go/path-injection] w.Write(data) // GOOD: Multipart.Form.FileHeader.Filename sanitized by filepath.Base when calling ParseMultipartForm diff --git a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.qlref b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.qlref index 78ce25b1921..6eb2e94892f 100644 --- a/go/ql/test/query-tests/Security/CWE-022/TaintedPath.qlref +++ b/go/ql/test/query-tests/Security/CWE-022/TaintedPath.qlref @@ -1,2 +1,4 @@ query: Security/CWE-022/TaintedPath.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.go b/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.go index 8a3016f9c31..66a8763a2b0 100644 --- a/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.go +++ b/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.go @@ -28,7 +28,7 @@ func unzipSymlinkBad(f io.Reader, target string) { break } if isRel(header.Linkname, target) && isRel(header.Name, target) { - os.Symlink(header.Linkname, header.Name) + os.Symlink(header.Linkname, header.Name) // $ Alert[go/unsafe-unzip-symlink] } } } @@ -40,7 +40,7 @@ func unzipSymlinkBadZip(f io.ReaderAt, target string) { linkNameBytes, _ := ioutil.ReadAll(linkData) linkName := string(linkNameBytes) if isRel(linkName, target) && isRel(header.Name, target) { - os.Symlink(linkName, header.Name) + os.Symlink(linkName, header.Name) // $ Alert[go/unsafe-unzip-symlink] } } } @@ -109,7 +109,7 @@ func getNextHeader(f *tar.Reader) (*tar.Header, error) { } func writeSymlink(linkName, fileName string) { - os.Symlink(linkName, fileName) + os.Symlink(linkName, fileName) // $ Sink[go/unsafe-unzip-symlink] } // BAD: a variant of `unzipSymlinkBad` where the tar-read and symlink @@ -123,7 +123,7 @@ func unzipSymlinkBadFactored(f io.Reader, target string) { break } if isRel(header.Linkname, target) && isRel(header.Name, target) { - writeSymlink(header.Linkname, header.Name) + writeSymlink(header.Linkname, header.Name) // $ Alert[go/unsafe-unzip-symlink] } } } diff --git a/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.qlref b/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.qlref index a40aa6194e1..5971b073735 100644 --- a/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.qlref +++ b/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.qlref @@ -1,2 +1,4 @@ query: Security/CWE-022/UnsafeUnzipSymlink.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlinkGood.go b/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlinkGood.go index dde03db263d..d662246a9c2 100644 --- a/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlinkGood.go +++ b/go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlinkGood.go @@ -58,7 +58,7 @@ func isRelGoodReadlink(candidate, target string) bool { if filepath.IsAbs(candidate) { return false } - realpath, err := os.Readlink(filepath.Join(target, candidate)) + realpath, err := os.Readlink(filepath.Join(target, candidate)) // $ Sink[go/zipslip] if err != nil { return false } @@ -69,7 +69,7 @@ func isRelGoodReadlink(candidate, target string) bool { func unzipSymlinkGoodReadlink(f io.Reader, target string) { r := tar.NewReader(f) for { - header, err := r.Next() + header, err := r.Next() // $ Alert[go/zipslip] if err != nil { break } diff --git a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.go b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.go index 1628eabbef9..936c3c8e9a2 100644 --- a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.go +++ b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.go @@ -11,6 +11,6 @@ func unzip(f string) { for _, f := range r.File { p, _ := filepath.Abs(f.Name) // BAD: This could overwrite any file on the file system - ioutil.WriteFile(p, []byte("present"), 0666) - } + ioutil.WriteFile(p, []byte("present"), 0666) // $ Sink[go/zipslip] + } // $ Alert[go/zipslip] } diff --git a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.qlref b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.qlref index da30bbaf10d..39acfb7ca4a 100644 --- a/go/ql/test/query-tests/Security/CWE-022/ZipSlip.qlref +++ b/go/ql/test/query-tests/Security/CWE-022/ZipSlip.qlref @@ -1,2 +1,4 @@ query: Security/CWE-022/ZipSlip.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-022/tarslip.go b/go/ql/test/query-tests/Security/CWE-022/tarslip.go index 37b3a32715c..f7e01ff0565 100644 --- a/go/ql/test/query-tests/Security/CWE-022/tarslip.go +++ b/go/ql/test/query-tests/Security/CWE-022/tarslip.go @@ -12,8 +12,8 @@ import ( func untarBad(reader io.Reader, prefix string) { tarReader := tar.NewReader(reader) - header, _ := tarReader.Next() - os.MkdirAll(path.Dir(header.Name), 0755) // NOT OK + header, _ := tarReader.Next() // $ Alert[go/zipslip] + os.MkdirAll(path.Dir(header.Name), 0755) // $ Sink[go/zipslip] // NOT OK } func untarGood(reader io.Reader, prefix string) { diff --git a/go/ql/test/query-tests/Security/CWE-022/tst.go b/go/ql/test/query-tests/Security/CWE-022/tst.go index 599faccf0f1..4cf3a77c4c8 100644 --- a/go/ql/test/query-tests/Security/CWE-022/tst.go +++ b/go/ql/test/query-tests/Security/CWE-022/tst.go @@ -26,7 +26,7 @@ func unzip2(f string, root string) { if err == nil { ioutil.WriteFile(filepath.Join(root, relpath), []byte("present"), 0666) // OK } - ioutil.WriteFile(path, []byte("present"), 0666) // NOT OK + ioutil.WriteFile(path, []byte("present"), 0666) // $ Sink[go/zipslip] // NOT OK if containedIn(path, root) { ioutil.WriteFile(path, []byte("present"), 0666) // OK } @@ -40,7 +40,7 @@ func unzip2(f string, root string) { if containedIn(f.Name, root) { ioutil.WriteFile(f.Name, []byte("present"), 0666) // OK } - } + } // $ Alert[go/zipslip] } func containedIn(f string, root string) bool { diff --git a/go/ql/test/query-tests/Security/CWE-078/ArgumentInjection.go b/go/ql/test/query-tests/Security/CWE-078/ArgumentInjection.go index d38d4662542..7519916afe0 100644 --- a/go/ql/test/query-tests/Security/CWE-078/ArgumentInjection.go +++ b/go/ql/test/query-tests/Security/CWE-078/ArgumentInjection.go @@ -6,7 +6,7 @@ import ( ) func handler2(req *http.Request) { - path := req.URL.Query()["path"][0] - cmd := exec.Command("rsync", path, "/tmp") + path := req.URL.Query()["path"][0] // $ Source[go/command-injection] + cmd := exec.Command("rsync", path, "/tmp") // $ Alert[go/command-injection] cmd.Run() } diff --git a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.go b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.go index ff046f24084..a8af53b7fc5 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.go +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.go @@ -6,7 +6,7 @@ import ( ) func handler(req *http.Request) { - cmdName := req.URL.Query()["cmd"][0] - cmd := exec.Command(cmdName) + cmdName := req.URL.Query()["cmd"][0] // $ Source[go/command-injection] + cmd := exec.Command(cmdName) // $ Alert[go/command-injection] cmd.Run() } diff --git a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.qlref b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.qlref index 2b07372975f..b1836a682e3 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection.qlref +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection.qlref @@ -1,2 +1,4 @@ query: Security/CWE-078/CommandInjection.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-078/CommandInjection2.go b/go/ql/test/query-tests/Security/CWE-078/CommandInjection2.go index 943a3f72f05..975ff72d177 100644 --- a/go/ql/test/query-tests/Security/CWE-078/CommandInjection2.go +++ b/go/ql/test/query-tests/Security/CWE-078/CommandInjection2.go @@ -10,9 +10,9 @@ import ( ) func handlerExample(req *http.Request) { - imageName := req.URL.Query()["imageName"][0] + imageName := req.URL.Query()["imageName"][0] // $ Source[go/command-injection] outputPath := "/tmp/output.svg" - cmd := exec.Command("sh", "-c", fmt.Sprintf("imagetool %s > %s", imageName, outputPath)) // NOT OK - correctly flagged + cmd := exec.Command("sh", "-c", fmt.Sprintf("imagetool %s > %s", imageName, outputPath)) // $ Alert[go/command-injection] // NOT OK - correctly flagged cmd.Run() // ... } @@ -38,10 +38,10 @@ func handlerExample2(req *http.Request) { } func handlerExample3(req *http.Request) { - imageName := req.URL.Query()["imageName"][0] + imageName := req.URL.Query()["imageName"][0] // $ Source[go/command-injection] outputPath := "/tmp/output.svg" - cmd := exec.Command("sh", "-c", fmt.Sprintf("imagetool %s > %s", imageName, outputPath)) // NOT OK - correctly flagged + cmd := exec.Command("sh", "-c", fmt.Sprintf("imagetool %s > %s", imageName, outputPath)) // $ Alert[go/command-injection] // NOT OK - correctly flagged cmd.Run() // Validate the imageName with a regular expression diff --git a/go/ql/test/query-tests/Security/CWE-078/GitSubcommands.go b/go/ql/test/query-tests/Security/CWE-078/GitSubcommands.go index 5e72e5825af..80322dcd27b 100644 --- a/go/ql/test/query-tests/Security/CWE-078/GitSubcommands.go +++ b/go/ql/test/query-tests/Security/CWE-078/GitSubcommands.go @@ -8,13 +8,13 @@ import ( // BAD: using git subcommands that are vulnerable to arbitrary remote command execution func gitSubcommandsBad(req *http.Request) { - tainted := req.URL.Query()["cmd"][0] + tainted := req.URL.Query()["cmd"][0] // $ Source[go/command-injection] - exec.Command("git", "clone", tainted) - exec.Command("git", "fetch", tainted) - exec.Command("git", "pull", tainted) - exec.Command("git", "ls-remote", tainted) - exec.Command("git", "fetch-pack", tainted) + exec.Command("git", "clone", tainted) // $ Alert[go/command-injection] + exec.Command("git", "fetch", tainted) // $ Alert[go/command-injection] + exec.Command("git", "pull", tainted) // $ Alert[go/command-injection] + exec.Command("git", "ls-remote", tainted) // $ Alert[go/command-injection] + exec.Command("git", "fetch-pack", tainted) // $ Alert[go/command-injection] } // GOOD: using a sampling of git subcommands that are not vulnerable to arbitrary remote command execution @@ -30,11 +30,11 @@ func gitSubcommandsGood(req *http.Request) { // BAD: using git subcommands that are vulnerable to arbitrary remote command execution func gitSubcommandsGood2(req *http.Request) { - tainted := req.URL.Query()["cmd"][0] + tainted := req.URL.Query()["cmd"][0] // $ Source[go/command-injection] if !strings.HasPrefix(tainted, "--") { exec.Command("git", "clone", tainted) // GOOD, `tainted` cannot start with "--" } else { - exec.Command("git", "clone", tainted) // BAD, `tainted` can start with "--" + exec.Command("git", "clone", tainted) // $ Alert[go/command-injection] // BAD, `tainted` can start with "--" } } diff --git a/go/ql/test/query-tests/Security/CWE-078/SanitizingDoubleDash.go b/go/ql/test/query-tests/Security/CWE-078/SanitizingDoubleDash.go index 0428df55086..9a8692319bb 100644 --- a/go/ql/test/query-tests/Security/CWE-078/SanitizingDoubleDash.go +++ b/go/ql/test/query-tests/Security/CWE-078/SanitizingDoubleDash.go @@ -6,12 +6,12 @@ import ( ) func testDoubleDashSanitizes(req *http.Request) { - tainted := req.URL.Query()["cmd"][0] + tainted := req.URL.Query()["cmd"][0] // $ Source[go/command-injection] // BAD: no sanitizing "--" preceding tainted data { arrayLit := [1]string{tainted} - exec.Command("git", arrayLit[:]...) + exec.Command("git", arrayLit[:]...) // $ Alert[go/command-injection] } // GOOD: sanitizing "--" preceding tainted data @@ -37,7 +37,7 @@ func testDoubleDashSanitizes(req *http.Request) { { arrayLit := []string{} arrayLit = append(arrayLit, tainted, "--") - exec.Command("git", arrayLit...) + exec.Command("git", arrayLit...) // $ Alert[go/command-injection] } // GOOD: sanitizing "--" preceding tainted data, built in two steps @@ -51,7 +51,7 @@ func testDoubleDashSanitizes(req *http.Request) { { arrayLit := []string{tainted} arrayLit = append(arrayLit, "--") - exec.Command("git", arrayLit...) + exec.Command("git", arrayLit...) // $ Alert[go/command-injection] } // GOOD: sanitizing "--" preceding tainted data, built in three steps @@ -67,7 +67,7 @@ func testDoubleDashSanitizes(req *http.Request) { arrayLit := []string{"something else"} arrayLit = append(arrayLit, tainted) arrayLit = append(arrayLit, "--") - exec.Command("git", arrayLit...) + exec.Command("git", arrayLit...) // $ Alert[go/command-injection] } // GOOD: sanitizing "--" preceding tainted data, used directly in a Command @@ -77,7 +77,7 @@ func testDoubleDashSanitizes(req *http.Request) { // BAD: sanitizing "--" comes after tainted data, used directly in a Command { - exec.Command("git", tainted, "--") + exec.Command("git", tainted, "--") // $ Alert[go/command-injection] } // GOOD: sanitizing "--" preceding tainted data, used directly in a Command, after several other arguments @@ -89,66 +89,66 @@ func testDoubleDashSanitizes(req *http.Request) { // This test mirrors testDoubleDashSanitizes above, but uses sudo instead of git, where "--" is not sanitizing. // All cases are therefore BAD. func testDoubleDashIrrelevant(req *http.Request) { - tainted := req.URL.Query()["cmd"][0] + tainted := req.URL.Query()["cmd"][0] // $ Source[go/command-injection] { arrayLit := [1]string{tainted} - exec.Command("sudo", arrayLit[:]...) // BAD + exec.Command("sudo", arrayLit[:]...) // $ Alert[go/command-injection] // BAD } { arrayLit := [2]string{"--", tainted} - exec.Command("sudo", arrayLit[:]...) // BAD + exec.Command("sudo", arrayLit[:]...) // $ Alert[go/command-injection] // BAD } { arrayLit := []string{"--", tainted} - exec.Command("sudo", arrayLit...) // BAD + exec.Command("sudo", arrayLit...) // $ Alert[go/command-injection] // BAD } { arrayLit := []string{} arrayLit = append(arrayLit, "--", tainted) - exec.Command("sudo", arrayLit...) // BAD + exec.Command("sudo", arrayLit...) // $ Alert[go/command-injection] // BAD } { arrayLit := []string{} arrayLit = append(arrayLit, tainted, "--") - exec.Command("sudo", arrayLit...) // BAD + exec.Command("sudo", arrayLit...) // $ Alert[go/command-injection] // BAD } { arrayLit := []string{"--"} arrayLit = append(arrayLit, tainted) - exec.Command("sudo", arrayLit...) // BAD + exec.Command("sudo", arrayLit...) // $ Alert[go/command-injection] // BAD } { arrayLit := []string{tainted} arrayLit = append(arrayLit, "--") - exec.Command("sudo", arrayLit...) // BAD + exec.Command("sudo", arrayLit...) // $ Alert[go/command-injection] // BAD } { arrayLit := []string{"--"} arrayLit = append(arrayLit, "something else") arrayLit = append(arrayLit, tainted) - exec.Command("sudo", arrayLit...) // BAD + exec.Command("sudo", arrayLit...) // $ Alert[go/command-injection] // BAD } { arrayLit := []string{"something else"} arrayLit = append(arrayLit, tainted) arrayLit = append(arrayLit, "--") - exec.Command("sudo", arrayLit...) // BAD + exec.Command("sudo", arrayLit...) // $ Alert[go/command-injection] // BAD } { - exec.Command("sudo", "--", tainted) // BAD + exec.Command("sudo", "--", tainted) // $ Alert[go/command-injection] // BAD } { - exec.Command("sudo", tainted, "--") // BAD + exec.Command("sudo", tainted, "--") // $ Alert[go/command-injection] // BAD } } diff --git a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.go b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.go index 5b7c16d0c59..ee38e54f4da 100644 --- a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.go +++ b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.go @@ -8,9 +8,9 @@ import ( var db *sql.DB func run(query string) { - rows, _ := db.Query(query) + rows, _ := db.Query(query) // $ Source[go/stored-command] var cmdName string rows.Scan(&cmdName) - cmd := exec.Command(cmdName) + cmd := exec.Command(cmdName) // $ Alert[go/stored-command] cmd.Run() } diff --git a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.qlref b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.qlref index 92c41892880..d1bc2b0f697 100644 --- a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.qlref +++ b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.qlref @@ -1,2 +1,4 @@ query: Security/CWE-078/StoredCommand.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.go b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.go index 0df976d93c3..9e36ea24c99 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.go +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.go @@ -8,6 +8,6 @@ import ( func handler(db *sql.DB, req *http.Request) { q := fmt.Sprintf("SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='%s' ORDER BY PRICE", - req.URL.Query()["category"]) - db.Query(q) + req.URL.Query()["category"]) // $ Source[go/sql-injection] + db.Query(q) // $ Alert[go/sql-injection] } diff --git a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.qlref b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.qlref index b6916bd2cd4..e1918157744 100644 --- a/go/ql/test/query-tests/Security/CWE-089/SqlInjection.qlref +++ b/go/ql/test/query-tests/Security/CWE-089/SqlInjection.qlref @@ -1,2 +1,4 @@ query: Security/CWE-089/SqlInjection.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-089/StringBreak.go b/go/ql/test/query-tests/Security/CWE-089/StringBreak.go index 5667ca35035..26cb9986c91 100644 --- a/go/ql/test/query-tests/Security/CWE-089/StringBreak.go +++ b/go/ql/test/query-tests/Security/CWE-089/StringBreak.go @@ -8,10 +8,10 @@ import ( ) func save(id string, version interface{}) { - versionJSON, _ := json.Marshal(version) + versionJSON, _ := json.Marshal(version) // $ Source[go/unsafe-quoting] sq.StatementBuilder. Insert("resources"). Columns("resource_id", "version_md5"). - Values(id, sq.Expr(fmt.Sprintf("md5('%s')", versionJSON))). + Values(id, sq.Expr(fmt.Sprintf("md5('%s')", versionJSON))). // $ Alert[go/unsafe-quoting] Exec() } diff --git a/go/ql/test/query-tests/Security/CWE-089/StringBreak.qlref b/go/ql/test/query-tests/Security/CWE-089/StringBreak.qlref index 45a8c419134..096091bde4c 100644 --- a/go/ql/test/query-tests/Security/CWE-089/StringBreak.qlref +++ b/go/ql/test/query-tests/Security/CWE-089/StringBreak.qlref @@ -1,2 +1,4 @@ query: Security/CWE-089/StringBreak.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-089/StringBreakMismatched.go b/go/ql/test/query-tests/Security/CWE-089/StringBreakMismatched.go index c838d5f6b7d..70f3af40d6f 100644 --- a/go/ql/test/query-tests/Security/CWE-089/StringBreakMismatched.go +++ b/go/ql/test/query-tests/Security/CWE-089/StringBreakMismatched.go @@ -10,23 +10,23 @@ import ( // Bad because quote characters are removed before concatenation, // but then enclosed in a different enclosing quote: func mismatch1(id string, version interface{}) { - versionJSON, _ := json.Marshal(version) + versionJSON, _ := json.Marshal(version) // $ Source[go/unsafe-quoting] escaped := strings.Replace(string(versionJSON), "\"", "", -1) sq.StatementBuilder. Insert("resources"). Columns("resource_id", "version_md5"). - Values(id, sq.Expr("'"+escaped+"'")). + Values(id, sq.Expr("'"+escaped+"'")). // $ Alert[go/unsafe-quoting] Exec() } // Bad because quote characters are removed before concatenation, // but then enclosed in a different enclosing quote: func mismatch2(id string, version interface{}) { - versionJSON, _ := json.Marshal(version) + versionJSON, _ := json.Marshal(version) // $ Source[go/unsafe-quoting] escaped := strings.Replace(string(versionJSON), "'", "", -1) sq.StatementBuilder. Insert("resources"). Columns("resource_id", "version_md5"). - Values(id, sq.Expr("\""+escaped+"\"")). + Values(id, sq.Expr("\""+escaped+"\"")). // $ Alert[go/unsafe-quoting] Exec() } diff --git a/go/ql/test/query-tests/Security/CWE-089/issue48.go b/go/ql/test/query-tests/Security/CWE-089/issue48.go index 2c23b617190..9ef91eb1350 100644 --- a/go/ql/test/query-tests/Security/CWE-089/issue48.go +++ b/go/ql/test/query-tests/Security/CWE-089/issue48.go @@ -14,29 +14,29 @@ func handler1(db *sql.DB, req *http.Request) { // read data from request body and unmarshal to a indeterminacy struct // POST: {"a": "b", "category": "test"} var RequestDataFromJson map[string]interface{} - b, _ := ioutil.ReadAll(req.Body) + b, _ := ioutil.ReadAll(req.Body) // $ Source[go/sql-injection] json.Unmarshal(b, &RequestDataFromJson) q3 := fmt.Sprintf("SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='%s' ORDER BY PRICE", RequestDataFromJson["category"]) - db.Query(q3) // NOT OK + db.Query(q3) // $ Alert[go/sql-injection] // NOT OK // read data from request body and unmarshal to a determined struct // POST: {"id": "1", "category": "test"} var RequestDataFromJson2 RequestStruct - b2, _ := ioutil.ReadAll(req.Body) + b2, _ := ioutil.ReadAll(req.Body) // $ Source[go/sql-injection] json.Unmarshal(b2, &RequestDataFromJson2) q4 := fmt.Sprintf("SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='%s' ORDER BY PRICE", RequestDataFromJson2.Category) - db.Query(q4) // NOT OK + db.Query(q4) // $ Alert[go/sql-injection] // NOT OK // read json data from a url parameter // GET: ?json={"id": 1, "category": "test"} var RequestDataFromJson3 RequestStruct - json.Unmarshal([]byte(req.URL.Query()["json"][0]), &RequestDataFromJson3) + json.Unmarshal([]byte(req.URL.Query()["json"][0]), &RequestDataFromJson3) // $ Source[go/sql-injection] q5 := fmt.Sprintf("SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='%s' ORDER BY PRICE", RequestDataFromJson3.Category) - db.Query(q5) // NOT OK + db.Query(q5) // $ Alert[go/sql-injection] // NOT OK } diff --git a/go/ql/test/query-tests/Security/CWE-089/main.go b/go/ql/test/query-tests/Security/CWE-089/main.go index 7e5f5a35a9d..d0b17bf1145 100644 --- a/go/ql/test/query-tests/Security/CWE-089/main.go +++ b/go/ql/test/query-tests/Security/CWE-089/main.go @@ -8,12 +8,12 @@ import ( ) func test(db *sql.DB, r *http.Request) { - db.Query(r.Form["query"][0]) // NOT OK + db.Query(r.Form["query"][0]) // $ Alert[go/sql-injection] // NOT OK } func test2(tx *sql.Tx, r *http.Request) { - tx.Query(fmt.Sprintf("SELECT USER FROM USERS WHERE ID='%s'", r.URL.Query()["uuid"])) // NOT OK - tx.Query(fmt.Sprintf("SELECT USER FROM USERS WHERE ID='%s'", r.Header.Get("X-Uuid"))) // NOT OK + tx.Query(fmt.Sprintf("SELECT USER FROM USERS WHERE ID='%s'", r.URL.Query()["uuid"])) // $ Alert[go/sql-injection] // NOT OK + tx.Query(fmt.Sprintf("SELECT USER FROM USERS WHERE ID='%s'", r.Header.Get("X-Uuid"))) // $ Alert[go/sql-injection] // NOT OK } func main() {} @@ -27,39 +27,39 @@ type RequestStruct struct { func handler2(db *sql.DB, req *http.Request) { RequestData := &RequestStruct{ Id: 1, - Category: req.URL.Query()["category"], + Category: req.URL.Query()["category"], // $ Source[go/sql-injection] } q := fmt.Sprintf("SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='%s' ORDER BY PRICE", RequestData.Category) - db.Query(q) + db.Query(q) // $ Alert[go/sql-injection] } func handler3(db *sql.DB, req *http.Request) { RequestData := &RequestStruct{} - RequestData.Category = req.URL.Query()["category"] + RequestData.Category = req.URL.Query()["category"] // $ Source[go/sql-injection] q := fmt.Sprintf("SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='%s' ORDER BY PRICE", RequestData.Category) - db.Query(q) + db.Query(q) // $ Alert[go/sql-injection] } func handler4(db *sql.DB, req *http.Request) { RequestData := &RequestStruct{} - (*RequestData).Category = req.URL.Query()["category"] + (*RequestData).Category = req.URL.Query()["category"] // $ Source[go/sql-injection] q := fmt.Sprintf("SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='%s' ORDER BY PRICE", RequestData.Category) - db.Query(q) + db.Query(q) // $ Alert[go/sql-injection] } func handler5(db *sql.DB, req *http.Request) { RequestData := &RequestStruct{} - (*RequestData).Category = req.URL.Query()["category"] + (*RequestData).Category = req.URL.Query()["category"] // $ Source[go/sql-injection] q := fmt.Sprintf("SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='%s' ORDER BY PRICE", (*RequestData).Category) - db.Query(q) + db.Query(q) // $ Alert[go/sql-injection] } // This is an integer, so should not counted as injection diff --git a/go/ql/test/query-tests/Security/CWE-089/mongoDB.go b/go/ql/test/query-tests/Security/CWE-089/mongoDB.go index 818f8adb13c..34c89d297b9 100644 --- a/go/ql/test/query-tests/Security/CWE-089/mongoDB.go +++ b/go/ql/test/query-tests/Security/CWE-089/mongoDB.go @@ -37,7 +37,7 @@ func mongo2(w http.ResponseWriter, r *http.Request) { // Get a handle for your collection db := client.Database("test") coll := db.Collection("collection") - untrustedInput := r.Referer() + untrustedInput := r.Referer() // $ Source[go/sql-injection] filter := bson.D{{"name", untrustedInput}} @@ -54,30 +54,30 @@ func mongo2(w http.ResponseWriter, r *http.Request) { update := bson.D{{"$inc", bson.D{{"age", 1}}}} // models := nil - coll.Aggregate(ctx, pipeline, nil) + coll.Aggregate(ctx, pipeline, nil) // $ Alert[go/sql-injection] // coll.BulkWrite(ctx, models, nil) coll.BulkWrite(ctx, nil, nil) coll.Clone(nil) - coll.CountDocuments(ctx, filter, nil) + coll.CountDocuments(ctx, filter, nil) // $ Alert[go/sql-injection] coll.Database() - coll.DeleteMany(ctx, filter, nil) - coll.DeleteOne(ctx, filter, nil) + coll.DeleteMany(ctx, filter, nil) // $ Alert[go/sql-injection] + coll.DeleteOne(ctx, filter, nil) // $ Alert[go/sql-injection] - coll.Distinct(ctx, fieldName, filter) + coll.Distinct(ctx, fieldName, filter) // $ Alert[go/sql-injection] coll.Drop(ctx) coll.EstimatedDocumentCount(ctx, nil) - coll.Find(ctx, filter, nil) - coll.FindOne(ctx, filter, nil) - coll.FindOneAndDelete(ctx, filter, nil) - coll.FindOneAndReplace(ctx, filter, nil) - coll.FindOneAndUpdate(ctx, filter, nil) + coll.Find(ctx, filter, nil) // $ Alert[go/sql-injection] + coll.FindOne(ctx, filter, nil) // $ Alert[go/sql-injection] + coll.FindOneAndDelete(ctx, filter, nil) // $ Alert[go/sql-injection] + coll.FindOneAndReplace(ctx, filter, nil) // $ Alert[go/sql-injection] + coll.FindOneAndUpdate(ctx, filter, nil) // $ Alert[go/sql-injection] coll.Indexes() coll.InsertMany(ctx, documents) coll.InsertOne(ctx, document, nil) coll.Name() - coll.ReplaceOne(ctx, filter, replacement) - coll.UpdateMany(ctx, filter, update) - coll.UpdateOne(ctx, filter, update) - coll.Watch(ctx, pipeline) + coll.ReplaceOne(ctx, filter, replacement) // $ Alert[go/sql-injection] + coll.UpdateMany(ctx, filter, update) // $ Alert[go/sql-injection] + coll.UpdateOne(ctx, filter, update) // $ Alert[go/sql-injection] + coll.Watch(ctx, pipeline) // $ Alert[go/sql-injection] } diff --git a/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.go b/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.go index aa11afa816a..c717cf6fd71 100644 --- a/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.go +++ b/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.go @@ -3,11 +3,11 @@ package main import "encoding/json" func encryptValue(v interface{}) ([]byte, error) { - jsonData, err := json.Marshal(v) + jsonData, err := json.Marshal(v) // $ Source if err != nil { return nil, err } - size := len(jsonData) + (len(jsonData) % 16) + size := len(jsonData) + (len(jsonData) % 16) // $ Alert buffer := make([]byte, size) copy(buffer, jsonData) return encryptBuffer(buffer) diff --git a/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.qlref b/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.qlref index f6da9bc1c36..e06f99c7747 100644 --- a/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.qlref +++ b/go/ql/test/query-tests/Security/CWE-190/AllocationSizeOverflow.qlref @@ -1,2 +1,4 @@ query: Security/CWE-190/AllocationSizeOverflow.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-190/tst.go b/go/ql/test/query-tests/Security/CWE-190/tst.go index abe4452343e..6958fd9ad9a 100644 --- a/go/ql/test/query-tests/Security/CWE-190/tst.go +++ b/go/ql/test/query-tests/Security/CWE-190/tst.go @@ -11,28 +11,28 @@ func test(x int, s string, xs []int, ys [16]int, ss [16]string, h *header) { jsonData, _ := json.Marshal(x) ignore(make([]byte, len(jsonData)+1)) // OK: data is small - jsonData, _ = json.Marshal(s) - ignore(make([]byte, len(jsonData)+1)) // NOT OK: data might be big + jsonData, _ = json.Marshal(s) // $ Source + ignore(make([]byte, len(jsonData)+1)) // $ Alert // NOT OK: data might be big jsonData, _ = json.Marshal("hi there") ignore(make([]byte, len(jsonData)+1)) // OK: data is small - jsonData, _ = json.Marshal(xs) - ignore(make([]byte, len(jsonData)+1)) // NOT OK: data might be big + jsonData, _ = json.Marshal(xs) // $ Source + ignore(make([]byte, len(jsonData)+1)) // $ Alert // NOT OK: data might be big jsonData, _ = json.Marshal(ys) ignore(make([]byte, len(jsonData)+1)) // OK: data is small - jsonData, _ = json.Marshal(ss) - ignore(make([]byte, 10, len(jsonData)+1)) // NOT OK: data might be big + jsonData, _ = json.Marshal(ss) // $ Source + ignore(make([]byte, 10, len(jsonData)+1)) // $ Alert // NOT OK: data might be big jsonData, _ = json.Marshal(h) ignore(make([]byte, len(jsonData)+1)) // OK: data is small var i interface{} i = h - jsonData, _ = json.Marshal(i) - ignore(make([]byte, len(jsonData)+1)) // NOT OK: data might be big + jsonData, _ = json.Marshal(i) // $ Source + ignore(make([]byte, len(jsonData)+1)) // $ Alert // NOT OK: data might be big } func ignore(_ interface{}) {} diff --git a/go/ql/test/query-tests/Security/CWE-190/tst2.go b/go/ql/test/query-tests/Security/CWE-190/tst2.go index d9dfe6912e8..28725266d96 100644 --- a/go/ql/test/query-tests/Security/CWE-190/tst2.go +++ b/go/ql/test/query-tests/Security/CWE-190/tst2.go @@ -6,13 +6,13 @@ import ( ) func test2(filename string) { - data, _ := ioutil.ReadFile(filename) - ignore(make([]byte, len(data)+1)) // NOT OK + data, _ := ioutil.ReadFile(filename) // $ Source + ignore(make([]byte, len(data)+1)) // $ Alert // NOT OK } func test3(r io.Reader) { - data, _ := ioutil.ReadAll(r) - ignore(make([]byte, len(data)+1)) // NOT OK + data, _ := ioutil.ReadAll(r) // $ Source + ignore(make([]byte, len(data)+1)) // $ Alert // NOT OK } func test4(r io.Reader, ws []io.Writer) { diff --git a/go/ql/test/query-tests/Security/CWE-190/tst3.go b/go/ql/test/query-tests/Security/CWE-190/tst3.go index 660345b099d..9a905563953 100644 --- a/go/ql/test/query-tests/Security/CWE-190/tst3.go +++ b/go/ql/test/query-tests/Security/CWE-190/tst3.go @@ -3,8 +3,8 @@ package main import "encoding/json" func testSanitizers(s string) { - jsonData, _ := json.Marshal(s) - ignore(make([]byte, len(jsonData)+1)) // NOT OK: data might be big + jsonData, _ := json.Marshal(s) // $ Source + ignore(make([]byte, len(jsonData)+1)) // $ Alert // NOT OK: data might be big ignore(make([]byte, int64(len(jsonData))+1)) // OK: sanitized by widening to 64 bits @@ -21,7 +21,7 @@ func testSanitizers(s string) { } { - newlength := len(jsonData) + 3 // NOT OK: newlength is changed after the upper bound check (even though it's made smaller) + newlength := len(jsonData) + 3 // $ Alert // NOT OK: newlength is changed after the upper bound check (even though it's made smaller) if newlength < 1000 { newlength = newlength - 1 ignore(make([]byte, newlength)) @@ -29,7 +29,7 @@ func testSanitizers(s string) { } { - newlength := len(jsonData) + 4 // NOT OK: there is an upper bound check but it doesn't dominate `make` + newlength := len(jsonData) + 4 // $ Alert // NOT OK: there is an upper bound check but it doesn't dominate `make` if newlength < 1000 { ignore(newlength + 2) } diff --git a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.qlref b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.qlref index 18cf2d49a1a..420481918d1 100644 --- a/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.qlref +++ b/go/ql/test/query-tests/Security/CWE-209/StackTraceExposure.qlref @@ -1 +1,2 @@ -Security/CWE-209/StackTraceExposure.ql +query: Security/CWE-209/StackTraceExposure.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-209/test.go b/go/ql/test/query-tests/Security/CWE-209/test.go index 77df73b8046..6a1b6c298ba 100644 --- a/go/ql/test/query-tests/Security/CWE-209/test.go +++ b/go/ql/test/query-tests/Security/CWE-209/test.go @@ -12,10 +12,10 @@ var logger log.Logger func handlePanic(w http.ResponseWriter, r *http.Request) { buf := make([]byte, 2<<16) - stackLen := runtime.Stack(buf, true) + stackLen := runtime.Stack(buf, true) // $ Source buf = buf[:stackLen] // BAD: printing a stack trace back to the response - w.Write(buf) + w.Write(buf) // $ Alert // GOOD: logging the response to the server and sending // a more generic message. logger.Printf("Panic: %s", buf) diff --git a/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/DisabledCertificateCheck.go b/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/DisabledCertificateCheck.go index b0490ad6f4f..67f757544f2 100644 --- a/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/DisabledCertificateCheck.go +++ b/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/DisabledCertificateCheck.go @@ -7,7 +7,7 @@ import ( func doAuthReq(authReq *http.Request) *http.Response { tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // NOT OK + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // $ Alert // NOT OK } client := &http.Client{Transport: tr} res, _ := client.Do(authReq) diff --git a/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/DisabledCertificateCheck.qlref b/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/DisabledCertificateCheck.qlref index cca259717b5..8864221dea7 100644 --- a/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/DisabledCertificateCheck.qlref +++ b/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/DisabledCertificateCheck.qlref @@ -1 +1,2 @@ -Security/CWE-295/DisabledCertificateCheck.ql +query: Security/CWE-295/DisabledCertificateCheck.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/main.go b/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/main.go index 3cb5d107a70..152ece5ba46 100644 --- a/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/main.go +++ b/go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/main.go @@ -6,7 +6,7 @@ import ( ) func bad1(cfg *tls.Config) { - cfg.InsecureSkipVerify = true // NOT OK + cfg.InsecureSkipVerify = true // $ Alert // NOT OK } func good1(cfg *tls.Config) { @@ -54,12 +54,12 @@ func makeInsecureConfig() *tls.Config { } func makeConfig() *tls.Config { - return &tls.Config{InsecureSkipVerify: true} // NOT OK + return &tls.Config{InsecureSkipVerify: true} // $ Alert // NOT OK } func bad3() *http.Transport { transport := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // NOT OK + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // $ Alert // NOT OK } return transport } diff --git a/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.expected b/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.expected index b81d24f2665..b05736dc4c4 100644 --- a/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.expected +++ b/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.expected @@ -1,3 +1,8 @@ +#select +| InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | this source | +| InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | this source | +| InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | this source | +| InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | this source | edges | InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | provenance | | | InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | provenance | | @@ -41,8 +46,3 @@ nodes | InsecureHostKeyCallbackExample.go:118:35:118:61 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey | | InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | semmle.label | potentiallySecureCallback | subpaths -#select -| InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | this source | -| InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:26:20:26:46 | call to InsecureIgnoreHostKey | this source | -| InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | this source | -| InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | Configuring SSH ClientConfig with insecure HostKeyCallback implementation from $@. | InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | this source | diff --git a/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.qlref b/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.qlref index b5f8712594d..2c5cecd3a29 100644 --- a/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.qlref +++ b/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.qlref @@ -1 +1,2 @@ -Security/CWE-322/InsecureHostKeyCallback.ql +query: Security/CWE-322/InsecureHostKeyCallback.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallbackExample.go b/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallbackExample.go index d13bda30a5e..1d5b17ebd8d 100644 --- a/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallbackExample.go +++ b/go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallbackExample.go @@ -15,7 +15,7 @@ func insecureSSHClientConfig() { HostKeyCallback: ssh.HostKeyCallback( // BAD func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil - }), + }), // $ Source Alert } } @@ -23,7 +23,7 @@ func insecureSSHClientConfigAlt() { _ = &ssh.ClientConfig{ User: "user", Auth: []ssh.AuthMethod{nil}, - HostKeyCallback: ssh.InsecureIgnoreHostKey(), // BAD + HostKeyCallback: ssh.InsecureIgnoreHostKey(), // $ Alert // BAD } } @@ -31,12 +31,12 @@ func insecureSSHClientConfigLocalFlow() { callback := ssh.HostKeyCallback( func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil - }) + }) // $ Source _ = &ssh.ClientConfig{ User: "user", Auth: []ssh.AuthMethod{nil}, - HostKeyCallback: callback, // BAD + HostKeyCallback: callback, // $ Alert // BAD } } @@ -44,12 +44,12 @@ func insecureSSHClientConfigLocalFlowAlt() { callback := func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil - } + } // $ Source _ = &ssh.ClientConfig{ User: "user", Auth: []ssh.AuthMethod{nil}, - HostKeyCallback: ssh.HostKeyCallback(callback), // BAD + HostKeyCallback: ssh.HostKeyCallback(callback), // $ Alert // BAD } } diff --git a/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.go b/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.go index 9d5ce2ac424..6c28a054b65 100644 --- a/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.go +++ b/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.go @@ -6,16 +6,16 @@ import ( ) func foo1() { - rsa.GenerateKey(rand.Reader, 1024) // BAD + rsa.GenerateKey(rand.Reader, 1024) // $ Alert // BAD } func foo2() { - size := 1024 - rsa.GenerateKey(rand.Reader, size) // BAD + size := 1024 // $ Source + rsa.GenerateKey(rand.Reader, size) // $ Alert // BAD } func foo3() { - foo5(1024) // BAD + foo5(1024) // $ Source // BAD } func foo4() { @@ -23,13 +23,13 @@ func foo4() { } func foo5(size int) { - rsa.GenerateKey(rand.Reader, size) + rsa.GenerateKey(rand.Reader, size) // $ Alert } func foo6() { - keyBits := 1024 + keyBits := 1024 // $ Source if keyBits >= 2047 { - rsa.GenerateKey(rand.Reader, keyBits) // BAD + rsa.GenerateKey(rand.Reader, keyBits) // $ Alert // BAD } } @@ -41,10 +41,10 @@ func foo7() { } func foo8() { - keyBits := 1024 + keyBits := 1024 // $ Source switch { case keyBits >= 2047: - rsa.GenerateKey(rand.Reader, keyBits) // BAD + rsa.GenerateKey(rand.Reader, keyBits) // $ Alert // BAD } } @@ -58,13 +58,13 @@ func foo9() { func foo10(customOptionSupplied bool, nonConstantKeyBits int) { keyBits := 0 - constantKeyBits := 1024 + constantKeyBits := 1024 // $ Source if customOptionSupplied { keyBits = constantKeyBits } else { keyBits = nonConstantKeyBits } - rsa.GenerateKey(rand.Reader, keyBits) // BAD + rsa.GenerateKey(rand.Reader, keyBits) // $ Alert // BAD } func foo11(customOptionSupplied bool, nonConstantKeyBits int) { diff --git a/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.qlref b/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.qlref index fbb59dd4be6..ef999cf368a 100644 --- a/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.qlref +++ b/go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.qlref @@ -1 +1,2 @@ -Security/CWE-326/InsufficientKeySize.ql +query: Security/CWE-326/InsufficientKeySize.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.go b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.go index 24dfeb195a0..5a91077e555 100644 --- a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.go +++ b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.go @@ -18,7 +18,7 @@ func oldVersionFunc() bool { func minMaxTlsVersion() { { config := &tls.Config{} - config.MinVersion = 0 // BAD + config.MinVersion = 0 // $ Alert[go/insecure-tls] // BAD } { config := &tls.Config{} @@ -27,7 +27,7 @@ func minMaxTlsVersion() { /// { config := &tls.Config{ - MinVersion: 0, // BAD + MinVersion: 0, // $ Alert[go/insecure-tls] // BAD } _ = config } @@ -40,40 +40,40 @@ func minMaxTlsVersion() { /// { config := &tls.Config{} - config.MinVersion = tls.VersionSSL30 // BAD + config.MinVersion = tls.VersionSSL30 // $ Alert[go/insecure-tls] // BAD } { config := &tls.Config{} - config.MaxVersion = tls.VersionSSL30 // BAD + config.MaxVersion = tls.VersionSSL30 // $ Alert[go/insecure-tls] // BAD } /// { config := &tls.Config{} - config.MinVersion = tls.VersionTLS10 // BAD + config.MinVersion = tls.VersionTLS10 // $ Alert[go/insecure-tls] // BAD } { config := &tls.Config{} - config.MaxVersion = tls.VersionTLS10 // BAD + config.MaxVersion = tls.VersionTLS10 // $ Alert[go/insecure-tls] // BAD } /// { config := &tls.Config{} - config.MinVersion = tls.VersionTLS11 // BAD + config.MinVersion = tls.VersionTLS11 // $ Alert[go/insecure-tls] // BAD } { config := &tls.Config{} - config.MaxVersion = tls.VersionTLS11 // BAD + config.MaxVersion = tls.VersionTLS11 // $ Alert[go/insecure-tls] // BAD } /// { config := &tls.Config{ - MinVersion: tls.VersionTLS11, // BAD + MinVersion: tls.VersionTLS11, // $ Alert[go/insecure-tls] // BAD } _ = config } { config := &tls.Config{ - MaxVersion: tls.VersionTLS11, // BAD + MaxVersion: tls.VersionTLS11, // $ Alert[go/insecure-tls] // BAD } _ = config } @@ -92,13 +92,13 @@ func minMaxTlsVersion() { /// { config := &tls.Config{ - MinVersion: 0x0300, // BAD + MinVersion: 0x0300, // $ Alert[go/insecure-tls] // BAD } _ = config } { config := &tls.Config{ - MaxVersion: 0x0301, // BAD + MaxVersion: 0x0301, // $ Alert[go/insecure-tls] // BAD } _ = config } @@ -108,7 +108,7 @@ func minMaxTlsVersion() { oldVersionFlag := len(os.Args) > 3 if unknown { config := &tls.Config{ - MinVersion: 0, // BAD + MinVersion: 0, // $ Alert[go/insecure-tls] // BAD } _ = config } @@ -198,7 +198,7 @@ func minMaxTlsVersion() { _ = config default: config := &tls.Config{ - MinVersion: 0, // BAD + MinVersion: 0, // $ Alert[go/insecure-tls] // BAD } _ = config } @@ -216,7 +216,7 @@ func minMaxTlsVersion() { _ = config default: config := &tls.Config{ - MinVersion: 0, // BAD + MinVersion: 0, // $ Alert[go/insecure-tls] // BAD } _ = config } @@ -257,61 +257,61 @@ func cipherSuites() { { config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_RSA_WITH_RC4_128_SHA, // BAD - tls.TLS_RSA_WITH_AES_128_CBC_SHA256, // BAD - tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, // BAD - tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, // BAD - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // BAD - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // BAD - }, + tls.TLS_RSA_WITH_RC4_128_SHA, // $ Source[go/insecure-tls] // BAD + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, // $ Source[go/insecure-tls] // BAD + tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, // $ Source[go/insecure-tls] // BAD + tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, // $ Source[go/insecure-tls] // BAD + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // $ Source[go/insecure-tls] // BAD + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } { config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_RSA_WITH_RC4_128_SHA, // BAD - }, + tls.TLS_RSA_WITH_RC4_128_SHA, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } { config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_RSA_WITH_AES_128_CBC_SHA256, // BAD - }, + tls.TLS_RSA_WITH_AES_128_CBC_SHA256, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } { config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, // BAD - }, + tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } { config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, // BAD - }, + tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } { config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // BAD - }, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } { config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // BAD - }, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } @@ -326,33 +326,33 @@ func cipherSuites() { { config := &tls.Config{} config.CipherSuites = make([]uint16, 0) - config.CipherSuites = append(config.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) // BAD + config.CipherSuites = append(config.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) // $ Alert[go/insecure-tls] // BAD } { config := &tls.Config{} config.CipherSuites = make([]uint16, 0) - suites := tls.InsecureCipherSuites() + suites := tls.InsecureCipherSuites() // $ Source[go/insecure-tls] for _, v := range suites { - config.CipherSuites = append(config.CipherSuites, v.ID) // BAD + config.CipherSuites = append(config.CipherSuites, v.ID) // $ Alert[go/insecure-tls] // BAD } } { config := &tls.Config{} cipherSuites := make([]uint16, 0) - suites := tls.InsecureCipherSuites() + suites := tls.InsecureCipherSuites() // $ Source[go/insecure-tls] for _, v := range suites { cipherSuites = append(cipherSuites, v.ID) } - config.CipherSuites = cipherSuites // BAD + config.CipherSuites = cipherSuites // $ Alert[go/insecure-tls] // BAD } { config := &tls.Config{} cipherSuites := make([]uint16, 0) - suites := tls.InsecureCipherSuites() + suites := tls.InsecureCipherSuites() // $ Source[go/insecure-tls] for i := range suites { cipherSuites = append(cipherSuites, suites[i].ID) } - config.CipherSuites = cipherSuites // BAD + config.CipherSuites = cipherSuites // $ Alert[go/insecure-tls] // BAD } unknown := len(os.Args) > 1 insecureFlag := len(os.Args) > 2 @@ -360,8 +360,8 @@ func cipherSuites() { if unknown { config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // BAD - }, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } @@ -430,8 +430,8 @@ func cipherSuites() { default: config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // BAD - }, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } @@ -454,8 +454,8 @@ func cipherSuites() { default: config := &tls.Config{ CipherSuites: []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // BAD - }, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // $ Source[go/insecure-tls] // BAD + }, // $ Alert[go/insecure-tls] } _ = config } diff --git a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.qlref b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.qlref index 0349f62f26f..892cb53d05b 100644 --- a/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.qlref +++ b/go/ql/test/query-tests/Security/CWE-327/UnsafeTLS.qlref @@ -1,2 +1,4 @@ query: Security/CWE-327/InsecureTLS.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.go b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.go index 2e4d309f46c..0dbc48b19d1 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.go +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.go @@ -9,7 +9,7 @@ var charset = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345 func generatePassword() string { s := make([]rune, 20) for i := range s { - s[i] = charset[rand.Intn(len(charset))] // BAD: weak RNG used to generate password + s[i] = charset[rand.Intn(len(charset))] // $ Alert // BAD: weak RNG used to generate password } return string(s) } diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.qlref b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.qlref index b30e6ede8ce..f148404a1c5 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.qlref +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/InsecureRandomness.qlref @@ -1,2 +1,4 @@ query: Security/CWE-338/InsecureRandomness.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/sample.go b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/sample.go index 9eef81f63bb..3edbb67c42d 100644 --- a/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/sample.go +++ b/go/ql/test/query-tests/Security/CWE-338/InsecureRandomness/sample.go @@ -12,7 +12,7 @@ import ( ) func Guid() []byte { - hash := sha256.Sum256([]byte(fmt.Sprintf("%n", rand.Uint32()))) // OK: may not be used in a cryptographic setting + hash := sha256.Sum256([]byte(fmt.Sprintf("%n", rand.Uint32()))) // $ Source // OK: may not be used in a cryptographic setting return hash[:] } @@ -23,7 +23,7 @@ func createHash(key string) string { } func ed25519FromGuid() { - ed25519.NewKeyFromSeed(Guid()) // BAD: Guid internally uses rand + ed25519.NewKeyFromSeed(Guid()) // $ Alert // BAD: Guid internally uses rand } func encrypt(data []byte, password string) []byte { @@ -31,16 +31,16 @@ func encrypt(data []byte, password string) []byte { gcm, _ := cipher.NewGCM(block) nonce := make([]byte, gcm.NonceSize()) - random := rand.New(rand.NewSource(999)) + random := rand.New(rand.NewSource(999)) // $ Source io.ReadFull(random, nonce) - ciphertext := gcm.Seal(data[:0], nonce, data, nil) // BAD: use of an insecure rng to generate a nonce + ciphertext := gcm.Seal(data[:0], nonce, data, nil) // $ Alert // BAD: use of an insecure rng to generate a nonce return ciphertext } func makePasswordFiveChar() string { s := make([]rune, 5) - s[0] = charset[rand.Intn(len(charset))] // BAD: weak RNG used to generate salt + s[0] = charset[rand.Intn(len(charset))] // $ Alert // BAD: weak RNG used to generate salt s[1] = charset[rand.Intn(len(charset))] // Rest OK because only the first result is caught s[2] = charset[rand.Intn(len(charset))] s[3] = charset[rand.Intn(len(charset))] @@ -52,8 +52,8 @@ func generateRandomKey() ed25519.PrivateKey { candidates := "0123456789ABCDEF" seed := "" for i := 0; i < ed25519.SeedSize; i++ { - randNumber := rand.Intn(len(candidates)) + randNumber := rand.Intn(len(candidates)) // $ Source seed += string(candidates[randNumber]) } - return ed25519.NewKeyFromSeed([]byte(seed)) // BAD: seed candidates were selected with a weak RNG + return ed25519.NewKeyFromSeed([]byte(seed)) // $ Alert // BAD: seed candidates were selected with a weak RNG } diff --git a/go/ql/test/query-tests/Security/CWE-347/MissingJwtSignatureCheck.qlref b/go/ql/test/query-tests/Security/CWE-347/MissingJwtSignatureCheck.qlref index 404fe618edc..55524e6e0e6 100644 --- a/go/ql/test/query-tests/Security/CWE-347/MissingJwtSignatureCheck.qlref +++ b/go/ql/test/query-tests/Security/CWE-347/MissingJwtSignatureCheck.qlref @@ -1,2 +1,4 @@ query: Security/CWE-347/MissingJwtSignatureCheck.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-347/go-jose.v3.go b/go/ql/test/query-tests/Security/CWE-347/go-jose.v3.go index 3e55ced31f6..67ce9ed00ea 100644 --- a/go/ql/test/query-tests/Security/CWE-347/go-jose.v3.go +++ b/go/ql/test/query-tests/Security/CWE-347/go-jose.v3.go @@ -22,7 +22,7 @@ func jose(r *http.Request) { verifyJWT(signedToken) // NOT OK: no verification - signedToken = r.URL.Query().Get("signedToken") + signedToken = r.URL.Query().Get("signedToken") // $ Source notVerifyJWT(signedToken) } @@ -30,7 +30,7 @@ func notVerifyJWT(signedToken string) { fmt.Println("only decoding JWT") DecodedToken, _ := jwt.ParseSigned(signedToken) out := CustomerInfo{} - if err := DecodedToken.UnsafeClaimsWithoutVerification(&out); err != nil { + if err := DecodedToken.UnsafeClaimsWithoutVerification(&out); err != nil { // $ Alert panic(err) } fmt.Printf("%v\n", out) diff --git a/go/ql/test/query-tests/Security/CWE-347/golang-jwt-v5.go b/go/ql/test/query-tests/Security/CWE-347/golang-jwt-v5.go index e37265f03c0..82d6c764797 100644 --- a/go/ql/test/query-tests/Security/CWE-347/golang-jwt-v5.go +++ b/go/ql/test/query-tests/Security/CWE-347/golang-jwt-v5.go @@ -25,13 +25,13 @@ func golangjwt(r *http.Request) { verifyJWT_golangjwt(signedToken) // NOT OK: only unverified parse - signedToken = r.URL.Query().Get("signedToken") + signedToken = r.URL.Query().Get("signedToken") // $ Source notVerifyJWT_golangjwt(signedToken) } func notVerifyJWT_golangjwt(signedToken string) { fmt.Println("only decoding JWT") - DecodedToken, _, err := jwt.NewParser().ParseUnverified(signedToken, &CustomerInfo1{}) + DecodedToken, _, err := jwt.NewParser().ParseUnverified(signedToken, &CustomerInfo1{}) // $ Alert if claims, ok := DecodedToken.Claims.(*CustomerInfo1); ok { fmt.Printf("DecodedToken:%v\n", claims) } else { diff --git a/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.go b/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.go index 75f899aea51..817c76c8bfa 100644 --- a/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.go +++ b/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.go @@ -17,9 +17,9 @@ import ( func main() {} -const stateStringConst = "state" +const stateStringConst = "state" // $ Source -var stateStringVar = "state" +var stateStringVar = "state" // $ Source func badWithStringLiteralState(w http.ResponseWriter) { conf := &oauth2.Config{ @@ -32,7 +32,7 @@ func badWithStringLiteralState(w http.ResponseWriter) { }, } - url := conf.AuthCodeURL("state") // BAD + url := conf.AuthCodeURL("state") // $ Alert // BAD _ = url // ... } @@ -47,7 +47,7 @@ func badWithConstState(w http.ResponseWriter) { }, } - url := conf.AuthCodeURL(stateStringConst) // BAD + url := conf.AuthCodeURL(stateStringConst) // $ Alert // BAD _ = url // ... } @@ -62,7 +62,7 @@ func badWithFixedVarState(w http.ResponseWriter) { }, } - url := conf.AuthCodeURL(stateStringVar) // BAD + url := conf.AuthCodeURL(stateStringVar) // $ Alert // BAD _ = url // ... } @@ -78,12 +78,12 @@ func badWithFixedStateReturned(w http.ResponseWriter) { } state := newFixedState() - url := conf.AuthCodeURL(state) // BAD + url := conf.AuthCodeURL(state) // $ Alert // BAD _ = url // ... } func newFixedState() string { - return "state" + return "state" // $ Source } func betterWithVariableStateReturned(w http.ResponseWriter) { @@ -229,7 +229,7 @@ func badWithConstStatePrinter(w http.ResponseWriter) { }, } - url := conf.AuthCodeURL(stateStringConst) // BAD + url := conf.AuthCodeURL(stateStringConst) // $ Alert // BAD fmt.Printf("LOG: URL %v", url) // ... } diff --git a/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.qlref b/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.qlref index 7898f39d415..7d6cf646915 100644 --- a/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.qlref +++ b/go/ql/test/query-tests/Security/CWE-352/ConstantOauth2State.qlref @@ -1 +1,2 @@ -Security/CWE-352/ConstantOauth2State.ql +query: Security/CWE-352/ConstantOauth2State.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.go b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.go index 279e59c9cfb..74e7c7c1c33 100644 --- a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.go +++ b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.go @@ -1,7 +1,7 @@ package main -func sanitizeUrl(redir string) string { - if len(redir) > 0 && redir[0] == '/' { +func sanitizeUrl(redir string) string { // $ Source + if len(redir) > 0 && redir[0] == '/' { // $ Alert return redir } return "/" diff --git a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.qlref b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.qlref index fddee377510..59540d49a15 100644 --- a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.qlref +++ b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.qlref @@ -1,2 +1,4 @@ query: Security/CWE-601/BadRedirectCheck.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/cves.go b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/cves.go index 42e8bab3452..01fc6553977 100644 --- a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/cves.go +++ b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/cves.go @@ -8,12 +8,12 @@ import ( // CVE-2018-15178 // Code from github.com/gogs/gogs func isValidRedirect(url string) bool { - return len(url) >= 2 && url[0] == '/' && url[1] != '/' // NOT OK + return len(url) >= 2 && url[0] == '/' && url[1] != '/' // $ Alert // NOT OK } -func alsoABadRedirect(url string, rw http.ResponseWriter, req *http.Request) { +func alsoABadRedirect(url string, rw http.ResponseWriter, req *http.Request) { // $ Source if isValidRedirect(url) { - http.Redirect(rw, req, url, 302) + http.Redirect(rw, req, url, 302) // $ Sink } } @@ -30,17 +30,17 @@ func alsoAGoodRedirect(url string, rw http.ResponseWriter, req *http.Request) { // CVE-2017-1000070 (both vulnerable!) // Code from github.com/bitly/oauth2_proxy func OAuthCallback(rw http.ResponseWriter, req *http.Request) { - redirect := req.Form.Get("state") - if !strings.HasPrefix(redirect, "/") { // NOT OK + redirect := req.Form.Get("state") // $ Source + if !strings.HasPrefix(redirect, "/") { // $ Alert // NOT OK redirect = "/" } - http.Redirect(rw, req, redirect, 302) + http.Redirect(rw, req, redirect, 302) // $ Sink } func OAuthCallback1(rw http.ResponseWriter, req *http.Request) { - redirect := req.Form.Get("state") - if !strings.HasPrefix(redirect, "/") || strings.HasPrefix(redirect, "//") { // NOT OK + redirect := req.Form.Get("state") // $ Source + if !strings.HasPrefix(redirect, "/") || strings.HasPrefix(redirect, "//") { // $ Alert // NOT OK redirect = "/" } - http.Redirect(rw, req, redirect, 302) + http.Redirect(rw, req, redirect, 302) // $ Sink } diff --git a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/main.go b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/main.go index beccc9a135d..f45653e0945 100644 --- a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/main.go +++ b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/main.go @@ -7,8 +7,8 @@ import ( "strings" ) -func badRedirect(redirect string, rw http.ResponseWriter, req *http.Request) { - http.Redirect(rw, req, sanitizeUrl(redirect), 302) +func badRedirect(redirect string, rw http.ResponseWriter, req *http.Request) { // $ Source + http.Redirect(rw, req, sanitizeUrl(redirect), 302) // $ Sink } func goodRedirect(redirect string, rw http.ResponseWriter, req *http.Request) { @@ -22,16 +22,16 @@ func goodRedirect2(url string, rw http.ResponseWriter, req *http.Request) { func isValidRedir(redirect string) bool { switch { // Not OK: does not check for '/\' - case strings.HasPrefix(redirect, "/") && !strings.HasPrefix(redirect, "//"): + case strings.HasPrefix(redirect, "/") && !strings.HasPrefix(redirect, "//"): // $ Alert return true default: return false } } -func alsoABadRedirect1(url string, rw http.ResponseWriter, req *http.Request) { +func alsoABadRedirect1(url string, rw http.ResponseWriter, req *http.Request) { // $ Source if isValidRedir(url) { - http.Redirect(rw, req, url, 302) + http.Redirect(rw, req, url, 302) // $ Sink } } @@ -65,28 +65,28 @@ func goodRedirect4(url string, rw http.ResponseWriter, req *http.Request) { http.Redirect(rw, req, getTarget(url), 302) } -func getTarget1(redirect string) string { - if redirect[0] != '/' { +func getTarget1(redirect string) string { // $ Source + if redirect[0] != '/' { // $ Alert return "/" } return path.Clean(redirect) } -func badRedirect1(url string, rw http.ResponseWriter, req *http.Request) { - http.Redirect(rw, req, getTarget1(url), 302) +func badRedirect1(url string, rw http.ResponseWriter, req *http.Request) { // $ Source + http.Redirect(rw, req, getTarget1(url), 302) // $ Sink } func getTarget2(redirect string) string { u, _ := url.Parse(redirect) - if u.Path[0] != '/' { + if u.Path[0] != '/' { // $ Alert return "/" } - return u.Path + return u.Path // $ Source } func badRedirect2(url string, rw http.ResponseWriter, req *http.Request) { - http.Redirect(rw, req, getTarget2(url), 302) + http.Redirect(rw, req, getTarget2(url), 302) // $ Sink } diff --git a/go/ql/test/query-tests/Security/CWE-643/XPathInjection.go b/go/ql/test/query-tests/Security/CWE-643/XPathInjection.go index 50b130db91c..bb7a45ca99a 100644 --- a/go/ql/test/query-tests/Security/CWE-643/XPathInjection.go +++ b/go/ql/test/query-tests/Security/CWE-643/XPathInjection.go @@ -10,10 +10,10 @@ import ( func processRequest(r *http.Request, doc tree.Node) { r.ParseForm() - username := r.Form.Get("username") + username := r.Form.Get("username") // $ Source // BAD: User input used directly in an XPath expression - xPath := goxpath.MustParse("//users/user[login/text()='" + username + "']/home_dir/text()") + xPath := goxpath.MustParse("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert unsafeRes, _ := xPath.ExecBool(doc) fmt.Println(unsafeRes) diff --git a/go/ql/test/query-tests/Security/CWE-643/XPathInjection.qlref b/go/ql/test/query-tests/Security/CWE-643/XPathInjection.qlref index e6a07d4a688..f3d92cc4c01 100644 --- a/go/ql/test/query-tests/Security/CWE-643/XPathInjection.qlref +++ b/go/ql/test/query-tests/Security/CWE-643/XPathInjection.qlref @@ -1,2 +1,4 @@ query: Security/CWE-643/XPathInjection.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/go/ql/test/query-tests/Security/CWE-643/tst.go b/go/ql/test/query-tests/Security/CWE-643/tst.go index d3fc98b41a7..cf15ceeb033 100644 --- a/go/ql/test/query-tests/Security/CWE-643/tst.go +++ b/go/ql/test/query-tests/Security/CWE-643/tst.go @@ -32,70 +32,70 @@ func main() {} func testAntchfxXpath(r *http.Request) { r.ParseForm() - username := r.Form.Get("username") + username := r.Form.Get("username") // $ Source // BAD: User input used directly in an XPath expression - _, _ = xpath.Compile("//users/user[login/text()='" + username + "']/home_dir/text()") - _, _ = xpath.CompileWithNS("//users/user[login/text()='"+username+"']/home_dir/text()", make(map[string]string)) - _ = xpath.MustCompile("//users/user[login/text()='" + username + "']/home_dir/text()") - _ = xpath.Select(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") + _, _ = xpath.Compile("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert + _, _ = xpath.CompileWithNS("//users/user[login/text()='"+username+"']/home_dir/text()", make(map[string]string)) // $ Alert + _ = xpath.MustCompile("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert + _ = xpath.Select(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert } func testAntchfxHtmlquery(r *http.Request) { r.ParseForm() - username := r.Form.Get("username") + username := r.Form.Get("username") // $ Source // BAD: User input used directly in an XPath expression - _ = htmlquery.Find(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - _ = htmlquery.FindOne(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - _, _ = htmlquery.Query(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - _, _ = htmlquery.QueryAll(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") + _ = htmlquery.Find(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + _ = htmlquery.FindOne(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + _, _ = htmlquery.Query(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + _, _ = htmlquery.QueryAll(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert } func testAntchfxXmlquery(r *http.Request, n *xmlquery.Node) { r.ParseForm() - username := r.Form.Get("username") + username := r.Form.Get("username") // $ Source // BAD: User input used directly in an XPath expression - _ = xmlquery.Find(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - _ = xmlquery.FindOne(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - xmlquery.FindEach(nil, "//users/user[login/text()='"+username+"']/home_dir/text()", nil) - xmlquery.FindEachWithBreak(nil, "//users/user[login/text()='"+username+"']/home_dir/text()", nil) - _, _ = xmlquery.Query(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - _, _ = xmlquery.QueryAll(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - _ = n.SelectElements("//users/user[login/text()='" + username + "']/home_dir/text()") - _ = n.SelectElement("//users/user[login/text()='" + username + "']/home_dir/text()") + _ = xmlquery.Find(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + _ = xmlquery.FindOne(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + xmlquery.FindEach(nil, "//users/user[login/text()='"+username+"']/home_dir/text()", nil) // $ Alert + xmlquery.FindEachWithBreak(nil, "//users/user[login/text()='"+username+"']/home_dir/text()", nil) // $ Alert + _, _ = xmlquery.Query(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + _, _ = xmlquery.QueryAll(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + _ = n.SelectElements("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert + _ = n.SelectElement("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert } func testAntchfxJsonquery(r *http.Request) { r.ParseForm() - username := r.Form.Get("username") + username := r.Form.Get("username") // $ Source // BAD: User input used directly in an XPath expression - _ = jsonquery.Find(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - _ = jsonquery.FindOne(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - _, _ = jsonquery.Query(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") - _, _ = jsonquery.QueryAll(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") + _ = jsonquery.Find(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + _ = jsonquery.FindOne(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + _, _ = jsonquery.Query(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert + _, _ = jsonquery.QueryAll(nil, "//users/user[login/text()='"+username+"']/home_dir/text()") // $ Alert } func testGoXmlpathXmlpath(r *http.Request) { r.ParseForm() - username := r.Form.Get("username") + username := r.Form.Get("username") // $ Source // BAD: User input used directly in an XPath expression - _, _ = xmlpath.Compile("//users/user[login/text()='" + username + "']/home_dir/text()") - _ = xmlpath.MustCompile("//users/user[login/text()='" + username + "']/home_dir/text()") + _, _ = xmlpath.Compile("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert + _ = xmlpath.MustCompile("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert } func testChrisTrenkampGoxpath(r *http.Request) { r.ParseForm() - username := r.Form.Get("username") - password := r.Form.Get("password") + username := r.Form.Get("username") // $ Source + password := r.Form.Get("password") // $ Source // BAD: User input used directly in an XPath expression - _, _ = goxpath.Parse("//users/user[login/text()='" + username + "' and password/text() = '" + password + "']/home_dir/text()") - _ = goxpath.MustParse("//users/user[login/text()='" + username + "' and password/text() = '" + password + "']/home_dir/text()") - _, _ = goxpath.ParseExec("//users/user[login/text()='"+username+"' and password/text() = '"+password+"']/home_dir/text()", nil) + _, _ = goxpath.Parse("//users/user[login/text()='" + username + "' and password/text() = '" + password + "']/home_dir/text()") // $ Alert + _ = goxpath.MustParse("//users/user[login/text()='" + username + "' and password/text() = '" + password + "']/home_dir/text()") // $ Alert + _, _ = goxpath.ParseExec("//users/user[login/text()='"+username+"' and password/text() = '"+password+"']/home_dir/text()", nil) // $ Alert // GOOD: Uses parameters to avoid including user input directly in XPath expression _ = goxpath.MustParse("//users/user[login/text()=$username and password/text() = $password]/home_dir/text()") @@ -103,24 +103,24 @@ func testChrisTrenkampGoxpath(r *http.Request) { func testSanthoshTekuriXpathparser(r *http.Request) { r.ParseForm() - username := r.Form.Get("username") + username := r.Form.Get("username") // $ Source // BAD: User input used directly in an XPath expression - _, _ = xpathparser.Parse("//users/user[login/text()='" + username + "']/home_dir/text()") - _ = xpathparser.MustParse("//users/user[login/text()='" + username + "']/home_dir/text()") + _, _ = xpathparser.Parse("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert + _ = xpathparser.MustParse("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert } func testJbowtieGokogiri(r *http.Request, n gokogiriXml.Node) { r.ParseForm() - username := r.Form.Get("username") - password := r.Form.Get("password") + username := r.Form.Get("username") // $ Source + password := r.Form.Get("password") // $ Source // BAD: User input used directly in an XPath expression - xpath := gokogiriXpath.Compile("//users/user[login/text()='" + username + "' and password/text() = '" + password + "']/home_dir/text()") - _, _ = n.Search("//users/user[login/text()='" + username + "' and password/text() = '" + password + "']/home_dir/text()") - _, _ = n.SearchWithVariables("//users/user[login/text()='"+username+"' and password/text() = '"+password+"']/home_dir/text()", nil) - _, _ = n.EvalXPath("//users/user[login/text()='"+username+"' and password/text() = '"+password+"']/home_dir/text()", nil) - _ = n.EvalXPathAsBoolean("//users/user[login/text()='"+username+"' and password/text() = '"+password+"']/home_dir/text()", nil) + xpath := gokogiriXpath.Compile("//users/user[login/text()='" + username + "' and password/text() = '" + password + "']/home_dir/text()") // $ Alert + _, _ = n.Search("//users/user[login/text()='" + username + "' and password/text() = '" + password + "']/home_dir/text()") // $ Alert + _, _ = n.SearchWithVariables("//users/user[login/text()='"+username+"' and password/text() = '"+password+"']/home_dir/text()", nil) // $ Alert + _, _ = n.EvalXPath("//users/user[login/text()='"+username+"' and password/text() = '"+password+"']/home_dir/text()", nil) // $ Alert + _ = n.EvalXPathAsBoolean("//users/user[login/text()='"+username+"' and password/text() = '"+password+"']/home_dir/text()", nil) // $ Alert // OK: Not flagged, since the creation of `xpath` is already flagged. _, _ = n.Search(xpath) @@ -136,12 +136,12 @@ func testJbowtieGokogiri(r *http.Request, n gokogiriXml.Node) { func testLestratGoLibxml2(r *http.Request) { r.ParseForm() - username := r.Form.Get("username") + username := r.Form.Get("username") // $ Source p := parser.New(parser.XMLParseNoEnt) // BAD: User input used directly in an XPath expression - _, _ = p.Parse([]byte("//users/user[login/text()='" + username + "']/home_dir/text()")) + _, _ = p.Parse([]byte("//users/user[login/text()='" + username + "']/home_dir/text()")) // $ Alert _, _ = p.ParseReader(strings.NewReader("//users/user[login/text()='" + username + "']/home_dir/text()")) - _, _ = p.ParseString("//users/user[login/text()='" + username + "']/home_dir/text()") + _, _ = p.ParseString("//users/user[login/text()='" + username + "']/home_dir/text()") // $ Alert } diff --git a/go/ql/test/query-tests/Security/CWE-798/AlertSuppressionExample.go b/go/ql/test/query-tests/Security/CWE-798/AlertSuppressionExample.go index c6cd369394f..938884f98df 100644 --- a/go/ql/test/query-tests/Security/CWE-798/AlertSuppressionExample.go +++ b/go/ql/test/query-tests/Security/CWE-798/AlertSuppressionExample.go @@ -8,7 +8,7 @@ func login(user, password string) bool { func TestLogin(t *testing.T) { user := "testuser" - password := "horsebatterystaplecorrect" // lgtm[go/hardcoded-credentials] + password := "horsebatterystaplecorrect" // $ Alert // lgtm[go/hardcoded-credentials] if !login(user, password) { t.Errorf("Login test failed.") } diff --git a/go/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.go b/go/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.go index 78d0603c2c3..8c3a96c941b 100644 --- a/go/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.go +++ b/go/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.go @@ -7,7 +7,7 @@ import ( const ( user = "dbuser" - password = "s3cretp4ssword" + password = "s3cretp4ssword" // $ Alert ) func connect() *sql.DB { diff --git a/go/ql/test/query-tests/Security/CWE-798/HardcodedKeysBad.go b/go/ql/test/query-tests/Security/CWE-798/HardcodedKeysBad.go index 2ffc46147f6..1c91a2b97b5 100644 --- a/go/ql/test/query-tests/Security/CWE-798/HardcodedKeysBad.go +++ b/go/ql/test/query-tests/Security/CWE-798/HardcodedKeysBad.go @@ -16,5 +16,5 @@ func bad() (interface{}, error) { } token := jwt.NewWithClaims(nil, claims) - return token.SignedString(mySigningKey) + return token.SignedString(mySigningKey) // $ Alert } diff --git a/go/ql/test/query-tests/Security/CWE-798/jwt.go b/go/ql/test/query-tests/Security/CWE-798/jwt.go index 560f95800df..f43749e6b4a 100644 --- a/go/ql/test/query-tests/Security/CWE-798/jwt.go +++ b/go/ql/test/query-tests/Security/CWE-798/jwt.go @@ -39,14 +39,14 @@ func gjwtt() (interface{}, error) { } token := gjwt.NewWithClaims(nil, claims) - return token.SignedString(mySigningKey) // BAD + return token.SignedString(mySigningKey) // $ Alert // BAD } func gin_jwt() (interface{}, error) { var identityKey = "id" return jwt.New(&jwt.GinJWTMiddleware{ Realm: "test zone", - Key: []byte("key2"), // BAD + Key: []byte("key2"), // $ Alert // BAD Timeout: time.Hour, MaxRefresh: time.Hour, IdentityKey: identityKey, @@ -65,12 +65,12 @@ func gin_jwt() (interface{}, error) { func cristalhq() (interface{}, error) { key := []byte(`key3`) - return cristal.NewSignerHS(cristal.HS256, key) // BAD + return cristal.NewSignerHS(cristal.HS256, key) // $ Alert // BAD } func josev3() (interface{}, error) { key := []byte("key4") - return jose_v3.NewSigner(jose_v3.SigningKey{Algorithm: "", Key: key}, nil) // BAD + return jose_v3.NewSigner(jose_v3.SigningKey{Algorithm: "", Key: key}, nil) // $ Alert // BAD } func josev3_2() (interface{}, error) { key2 := []byte("key5") @@ -78,7 +78,7 @@ func josev3_2() (interface{}, error) { "", jose_v3.Recipient{ Algorithm: "", - Key: key2, // BAD + Key: key2, // $ Alert // BAD }, nil) } @@ -88,14 +88,14 @@ func josev2() (interface{}, error) { return jose_v2.NewEncrypter( "", - jose_v2.Recipient{Algorithm: "", Key: key}, // BAD + jose_v2.Recipient{Algorithm: "", Key: key}, // $ Alert // BAD nil, ) } func jose_v2_2() (interface{}, error) { key2 := []byte("key7") - return jose_v2.NewSigner(jose_v2.SigningKey{Algorithm: "", Key: key2}, nil) // BAD + return jose_v2.NewSigner(jose_v2.SigningKey{Algorithm: "", Key: key2}, nil) // $ Alert // BAD } func go_kit() interface{} { @@ -106,24 +106,24 @@ func go_kit() interface{} { mapClaims = gjwt.MapClaims{"user": "go-kit"} ) - return gokit.NewSigner(kid, key, nil, mapClaims) // BAD + return gokit.NewSigner(kid, key, nil, mapClaims) // $ Alert // BAD } func lejwt() (interface{}, error) { sharedKey := []byte("key9") - return le.New(sharedKey) // BAD + return le.New(sharedKey) // $ Alert // BAD } var sharedKeyglobal = []byte("key10") func lejwt2() (interface{}, error) { - return le.New(sharedKeyglobal) // BAD + return le.New(sharedKeyglobal) // $ Alert // BAD } func gogfjwt() interface{} { return &gogf.GfJWTMiddleware{ Realm: "test zone", - Key: []byte("key11"), // BAD + Key: []byte("key11"), // $ Alert // BAD Timeout: time.Minute * 5, MaxRefresh: time.Minute * 5, IdentityKey: "id", @@ -140,7 +140,7 @@ func gogfjwt() interface{} { func irisjwt() interface{} { key := []byte("key12") token := iris.NewTokenWithClaims(nil, nil) - tokenString, _ := token.SignedString(key) // BAD + tokenString, _ := token.SignedString(key) // $ Alert // BAD return tokenString } @@ -149,7 +149,7 @@ func iris12jwt2() interface{} { s := &iris12.Signer{ Alg: nil, - Key: key, // BAD + Key: key, // $ Alert // BAD MaxAge: 3 * time.Second, } return s @@ -157,31 +157,31 @@ func iris12jwt2() interface{} { func irisjwt3() interface{} { key := []byte("key14") - signer := iris12.NewSigner(nil, key, 3*time.Second) // BAD + signer := iris12.NewSigner(nil, key, 3*time.Second) // $ Alert // BAD return signer } func katarasJwt() interface{} { key := []byte("key15") - token, _ := kataras.Sign(nil, key, nil, nil) // BAD + token, _ := kataras.Sign(nil, key, nil, nil) // $ Alert // BAD return token } func katarasJwt2() interface{} { key := []byte("key16") - token, _ := kataras.SignEncrypted(nil, key, nil, nil) // BAD + token, _ := kataras.SignEncrypted(nil, key, nil, nil) // $ Alert // BAD return token } func katarasJwt3() interface{} { key := []byte("key17") - token, _ := kataras.SignEncryptedWithHeader(nil, key, nil, nil, nil) // BAD + token, _ := kataras.SignEncryptedWithHeader(nil, key, nil, nil, nil) // $ Alert // BAD return token } func katarasJwt4() interface{} { key := []byte("key18") - token, _ := kataras.SignWithHeader(nil, key, nil, nil) // BAD + token, _ := kataras.SignWithHeader(nil, key, nil, nil) // $ Alert // BAD return token } @@ -189,5 +189,5 @@ func katarasJwt5() { key := []byte("key19") var keys kataras.Keys var alg kataras.Alg - keys.Register(alg, "api", nil, key) // BAD + keys.Register(alg, "api", nil, key) // $ Alert // BAD } diff --git a/go/ql/test/query-tests/Security/CWE-798/main.go b/go/ql/test/query-tests/Security/CWE-798/main.go index 366933c7693..7934c0d842f 100644 --- a/go/ql/test/query-tests/Security/CWE-798/main.go +++ b/go/ql/test/query-tests/Security/CWE-798/main.go @@ -3,7 +3,7 @@ package main import "fmt" const ( - passwd = "p4ssw0rd" // NOT OK + passwd = "p4ssw0rd" // $ Alert // NOT OK _password = "" // OK ) diff --git a/go/ql/test/query-tests/Security/CWE-798/sanitizer.go b/go/ql/test/query-tests/Security/CWE-798/sanitizer.go index 749642ceb3b..19cd3313987 100644 --- a/go/ql/test/query-tests/Security/CWE-798/sanitizer.go +++ b/go/ql/test/query-tests/Security/CWE-798/sanitizer.go @@ -15,7 +15,7 @@ import ( func check_ok() (interface{}, error) { key := []byte(`some_key`) - return cristal.NewSignerHS(cristal.HS256, key) // BAD + return cristal.NewSignerHS(cristal.HS256, key) // $ Alert // BAD } func GenerateRandomString(size int) string {