From c336a1595d5b8d82e289c58e835e2d3c7d9bf81b Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Tue, 21 Apr 2026 09:04:33 +1000 Subject: [PATCH 01/43] Java: split read-only path sinks into path-injection[read] Introduce a new Models-as-Data sink sub-kind path-injection[read] for models that only read from or inspect a path. The general java/path-injection query and its PathInjectionSanitizer barrier continue to consider both path-injection and path-injection[read] sinks, so no alerts are lost. The java/zipslip query deliberately selects only path-injection sinks, since read-only accesses such as ClassLoader.getResource or FileInputStream are outside the archive extraction threat model. Addresses https://github.com/github/codeql/issues/21606 along the lines proposed on the issue thread: prefer path-injection[read] over a [create] sub-kind so that miscategorizing a sink causes a false positive (easy to spot) rather than a false negative. - shared/mad/codeql/mad/ModelValidation.qll: allow path-injection[...] as a valid sink kind. - java/ql/lib/ext/*.model.yml: relabel the models that PR #12916 migrated from the historical read-file kind (plus the newer ClassLoader resource-lookup variants that share the same read-only semantics). - java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll and PathSanitizer.qll: select both path-injection and path-injection[read] sinks/barriers. - java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll: keep only path-injection, with a comment explaining why path-injection[read] is excluded. - java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java: add m7 regression covering the Dubbo-style classpath lookup from issue #21606 and assert no alert is produced. - Update TaintedPath.expected for the renamed kinds in the models list. - Add change-notes under java/ql/lib/change-notes and java/ql/src/change-notes. --- .../2026-04-21-path-injection-read-subkind.md | 4 ++ .../ql/lib/ext/com.google.common.io.model.yml | 10 ++-- .../ext/com.thoughtworks.xstream.model.yml | 2 +- java/ql/lib/ext/hudson.model.model.yml | 4 +- java/ql/lib/ext/hudson.model.yml | 10 ++-- java/ql/lib/ext/hudson.scm.model.yml | 6 +-- java/ql/lib/ext/hudson.util.jna.model.yml | 2 +- java/ql/lib/ext/hudson.util.model.yml | 12 ++--- ...tty.handler.codec.http.multipart.model.yml | 2 +- .../ql/lib/ext/io.netty.handler.ssl.model.yml | 4 +- .../lib/ext/io.netty.handler.stream.model.yml | 2 +- java/ql/lib/ext/java.io.model.yml | 16 +++--- java/ql/lib/ext/java.lang.model.yml | 18 +++---- java/ql/lib/ext/java.nio.file.model.yml | 24 ++++----- java/ql/lib/ext/javax.servlet.model.yml | 2 +- java/ql/lib/ext/kotlin.io.model.yml | 6 +-- .../lib/ext/org.apache.commons.io.model.yml | 2 +- .../lib/ext/org.apache.commons.net.model.yml | 6 +-- .../ql/lib/ext/org.apache.tools.ant.model.yml | 10 ++-- .../org.apache.tools.ant.taskdefs.model.yml | 6 +-- ...org.kohsuke.stapler.framework.io.model.yml | 2 +- .../ext/org.springframework.util.model.yml | 2 +- .../code/java/security/PathSanitizer.qll | 4 +- .../code/java/security/TaintedPathQuery.qll | 2 +- .../code/java/security/ZipSlipQuery.qll | 5 ++ .../2026-04-21-zipslip-exclude-read-sinks.md | 4 ++ .../CWE-022/semmle/tests/TaintedPath.expected | 52 +++++++++---------- .../CWE-022/semmle/tests/ZipTest.java | 12 +++++ shared/mad/codeql/mad/ModelValidation.qll | 5 ++ 29 files changed, 134 insertions(+), 102 deletions(-) create mode 100644 java/ql/lib/change-notes/2026-04-21-path-injection-read-subkind.md create mode 100644 java/ql/src/change-notes/2026-04-21-zipslip-exclude-read-sinks.md diff --git a/java/ql/lib/change-notes/2026-04-21-path-injection-read-subkind.md b/java/ql/lib/change-notes/2026-04-21-path-injection-read-subkind.md new file mode 100644 index 00000000000..bcd9479d2af --- /dev/null +++ b/java/ql/lib/change-notes/2026-04-21-path-injection-read-subkind.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Introduced a new sink kind `path-injection[read]` for Models-as-Data rows that only read from a path (such as `ClassLoader.getResource`, `FileInputStream`, `FileReader`, `Files.readAllBytes`, and related APIs). The general `java/path-injection` query continues to consider both `path-injection` and `path-injection[read]` sinks. diff --git a/java/ql/lib/ext/com.google.common.io.model.yml b/java/ql/lib/ext/com.google.common.io.model.yml index 8ce06de61b9..a8d2690bf00 100644 --- a/java/ql/lib/ext/com.google.common.io.model.yml +++ b/java/ql/lib/ext/com.google.common.io.model.yml @@ -5,12 +5,12 @@ extensions: data: - ["com.google.common.io", "Files", False, "asByteSink", "(File,FileWriteMode[])", "", "Argument[0]", "path-injection", "ai-manual"] - ["com.google.common.io", "Files", False, "asCharSink", "(File,Charset,FileWriteMode[])", "", "Argument[0]", "path-injection", "ai-manual"] - - ["com.google.common.io", "Files", False, "asCharSource", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["com.google.common.io", "Files", False, "copy", "(File,OutputStream)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["com.google.common.io", "Files", False, "asCharSource", "(File,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["com.google.common.io", "Files", False, "copy", "(File,OutputStream)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["com.google.common.io", "Files", False, "newWriter", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["com.google.common.io", "Files", False, "readLines", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["com.google.common.io", "Files", False, "toByteArray", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["com.google.common.io", "Files", False, "toString", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["com.google.common.io", "Files", False, "readLines", "(File,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["com.google.common.io", "Files", False, "toByteArray", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["com.google.common.io", "Files", False, "toString", "(File,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["com.google.common.io", "Files", False, "write", "(byte[],File)", "", "Argument[0]", "file-content-store", "ai-manual"] - ["com.google.common.io", "Files", False, "write", "(byte[],File)", "", "Argument[1]", "path-injection", "manual"] - addsTo: diff --git a/java/ql/lib/ext/com.thoughtworks.xstream.model.yml b/java/ql/lib/ext/com.thoughtworks.xstream.model.yml index c34bb91d42c..62e17590ebf 100644 --- a/java/ql/lib/ext/com.thoughtworks.xstream.model.yml +++ b/java/ql/lib/ext/com.thoughtworks.xstream.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["com.thoughtworks.xstream", "XStream", True, "fromXML", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["com.thoughtworks.xstream", "XStream", True, "fromXML", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] diff --git a/java/ql/lib/ext/hudson.model.model.yml b/java/ql/lib/ext/hudson.model.model.yml index 253f26fbd24..b52f7195b2b 100644 --- a/java/ql/lib/ext/hudson.model.model.yml +++ b/java/ql/lib/ext/hudson.model.model.yml @@ -5,8 +5,8 @@ extensions: data: - ["hudson.model", "DownloadService", True, "loadJSON", "(URL)", "", "Argument[0]", "request-forgery", "ai-manual"] - ["hudson.model", "DownloadService", True, "loadJSONHTML", "(URL)", "", "Argument[0]", "request-forgery", "ai-manual"] - - ["hudson.model", "DirectoryBrowserSupport", False, "DirectoryBrowserSupport", "(ModelObject,FilePath,String,String,boolean)", "", "Argument[1]", "path-injection", "ai-manual"] - - ["hudson.model", "Items", True, "load", "(ItemGroup,File)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["hudson.model", "DirectoryBrowserSupport", False, "DirectoryBrowserSupport", "(ModelObject,FilePath,String,String,boolean)", "", "Argument[1]", "path-injection[read]", "ai-manual"] + - ["hudson.model", "Items", True, "load", "(ItemGroup,File)", "", "Argument[1]", "path-injection[read]", "ai-manual"] - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "download", "(UpdateCenter$DownloadJob,URL)", "", "Argument[1]", "request-forgery", "ai-manual"] - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "install", "(UpdateCenter$DownloadJob,File,File)", "", "Argument[1]", "path-injection", "ai-manual"] - ["hudson.model", "UpdateCenter$UpdateCenterConfiguration", True, "install", "(UpdateCenter$DownloadJob,File,File)", "", "Argument[2]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/hudson.model.yml b/java/ql/lib/ext/hudson.model.yml index 0dfff091fcd..da2753c86bd 100644 --- a/java/ql/lib/ext/hudson.model.yml +++ b/java/ql/lib/ext/hudson.model.yml @@ -6,14 +6,14 @@ extensions: - ["hudson", "FilePath", False, "tar", "(OutputStream,String)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson", "FilePath", False, "unzipFrom", "(InputStream)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson", "FilePath", True, "copyFrom", "", "", "Argument[this]", "path-injection", "manual"] - - ["hudson", "FilePath", True, "copyFrom", "(FilePath)", "", "Argument[0]", "path-injection", "manual"] - - ["hudson", "FilePath", True, "copyFrom", "(URL)", "", "Argument[0]", "path-injection", "manual"] - - ["hudson", "FilePath", True, "copyFrom", "(FileItem)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyFrom", "(FilePath)", "", "Argument[0]", "path-injection[read]", "manual"] + - ["hudson", "FilePath", True, "copyFrom", "(URL)", "", "Argument[0]", "path-injection[read]", "manual"] + - ["hudson", "FilePath", True, "copyFrom", "(FileItem)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["hudson", "FilePath", True, "copyRecursiveTo", "", "", "Argument[this]", "path-injection", "ai-manual"] - ["hudson", "FilePath", True, "copyRecursiveTo", "(DirScanner,FilePath,String,FilePath$TarCompression)", "", "Argument[1]", "path-injection", "ai-manual"] - ["hudson", "FilePath", True, "copyRecursiveTo", "(DirScanner,FilePath,String)", "", "Argument[1]", "path-injection", "ai-manual"] - ["hudson", "FilePath", True, "copyRecursiveTo", "(String,FilePath)", "", "Argument[1]", "path-injection", "ai-manual"] - - ["hudson", "FilePath", True, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["hudson", "FilePath", True, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[2]", "path-injection", "ai-manual"] - ["hudson", "FilePath", True, "copyTo", "", "", "Argument[this]", "path-injection", "manual"] - ["hudson", "FilePath", True, "copyTo", "(FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] @@ -21,7 +21,7 @@ extensions: - ["hudson", "FilePath", True, "copyToWithPermission", "(FilePath)", "", "Argument[0]", "path-injection", "manual"] - ["hudson", "FilePath", True, "exists", "()", "", "Argument[this]", "path-injection", "manual"] - ["hudson", "FilePath", True, "installIfNecessaryFrom", "(URL,TaskListener,String)", "", "Argument[0]", "request-forgery", "ai-manual"] - - ["hudson", "FilePath", True, "newInputStreamDenyingSymlinkAsNeeded", "(File,String,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson", "FilePath", True, "newInputStreamDenyingSymlinkAsNeeded", "(File,String,boolean)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["hudson", "FilePath", True, "openInputStream", "(File,OpenOption[])", "", "Argument[0]", "path-injection", "manual"] - ["hudson", "FilePath", True, "read", "", "", "Argument[this]", "path-injection", "manual"] - ["hudson", "FilePath", True, "read", "(FilePath,OpenOption[])", "", "Argument[0]", "path-injection", "manual"] diff --git a/java/ql/lib/ext/hudson.scm.model.yml b/java/ql/lib/ext/hudson.scm.model.yml index dc6e0bfa5bb..a6cf1532b6b 100644 --- a/java/ql/lib/ext/hudson.scm.model.yml +++ b/java/ql/lib/ext/hudson.scm.model.yml @@ -3,11 +3,11 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson.scm", "ChangeLogParser", True, "parse", "(AbstractBuild,File)", "", "Argument[1]", "path-injection", "ai-manual"] - - ["hudson.scm", "ChangeLogParser", True, "parse", "(Run,RepositoryBrowser,File)", "", "Argument[2]", "path-injection", "ai-manual"] + - ["hudson.scm", "ChangeLogParser", True, "parse", "(AbstractBuild,File)", "", "Argument[1]", "path-injection[read]", "ai-manual"] + - ["hudson.scm", "ChangeLogParser", True, "parse", "(Run,RepositoryBrowser,File)", "", "Argument[2]", "path-injection[read]", "ai-manual"] - ["hudson.scm", "SCM", True, "checkout", "(AbstractBuild,Launcher,FilePath,BuildListener,File)", "", "Argument[2]", "path-injection", "ai-manual"] - ["hudson.scm", "SCM", True, "checkout", "(Run,Launcher,FilePath,TaskListener,File,SCMRevisionState)", "", "Argument[2]", "path-injection", "ai-manual"] - - ["hudson.scm", "SCM", True, "compareRemoteRevisionWith", "(Job,Launcher,FilePath,TaskListener,SCMRevisionState)", "", "Argument[2]", "path-injection", "ai-manual"] + - ["hudson.scm", "SCM", True, "compareRemoteRevisionWith", "(Job,Launcher,FilePath,TaskListener,SCMRevisionState)", "", "Argument[2]", "path-injection[read]", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/hudson.util.jna.model.yml b/java/ql/lib/ext/hudson.util.jna.model.yml index c840d0f4725..11efc9ace86 100644 --- a/java/ql/lib/ext/hudson.util.jna.model.yml +++ b/java/ql/lib/ext/hudson.util.jna.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["hudson.util.jna", "GNUCLibrary", True, "open", "(String,int)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util.jna", "GNUCLibrary", True, "open", "(String,int)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["hudson.util.jna", "Kernel32", True, "MoveFileExA", "(String,String,int)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson.util.jna", "Kernel32", True, "MoveFileExA", "(String,String,int)", "", "Argument[1]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/hudson.util.model.yml b/java/ql/lib/ext/hudson.util.model.yml index 1ac3aa8c10a..0fcf7b0cbfb 100644 --- a/java/ql/lib/ext/hudson.util.model.yml +++ b/java/ql/lib/ext/hudson.util.model.yml @@ -6,7 +6,7 @@ extensions: - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset,boolean,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["hudson.util", "ClasspathBuilder", True, "add", "(FilePath)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["hudson.util", "ClasspathBuilder", True, "add", "(FilePath)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["hudson.util", "FormValidation", True, "errorWithMarkup", "", "", "Argument[0]", "html-injection", "manual"] - ["hudson.util", "FormValidation", True, "okWithMarkup", "", "", "Argument[0]", "html-injection", "manual"] - ["hudson.util", "FormValidation", True, "respond", "", "", "Argument[1]", "html-injection", "manual"] @@ -14,11 +14,11 @@ extensions: - ["hudson.util", "IOUtils", True, "mkdirs", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson.util", "StreamTaskListener", True, "StreamTaskListener", "(File,boolean,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - ["hudson.util", "TextFile", True, "delete", "()", "", "Argument[this]", "path-injection", "manual"] - - ["hudson.util", "TextFile", True, "fastTail", "", "", "Argument[this]", "path-injection", "manual"] - - ["hudson.util", "TextFile", True, "head", "", "", "Argument[this]", "path-injection", "manual"] - - ["hudson.util", "TextFile", True, "lines", "()", "", "Argument[this]", "path-injection", "manual"] - - ["hudson.util", "TextFile", True, "read", "()", "", "Argument[this]", "path-injection", "manual"] - - ["hudson.util", "TextFile", True, "readTrim", "()", "", "Argument[this]", "path-injection", "manual"] + - ["hudson.util", "TextFile", True, "fastTail", "", "", "Argument[this]", "path-injection[read]", "manual"] + - ["hudson.util", "TextFile", True, "head", "", "", "Argument[this]", "path-injection[read]", "manual"] + - ["hudson.util", "TextFile", True, "lines", "()", "", "Argument[this]", "path-injection[read]", "manual"] + - ["hudson.util", "TextFile", True, "read", "()", "", "Argument[this]", "path-injection[read]", "manual"] + - ["hudson.util", "TextFile", True, "readTrim", "()", "", "Argument[this]", "path-injection[read]", "manual"] - ["hudson.util", "TextFile", True, "write", "(String)", "", "Argument[this]", "path-injection", "manual"] - ["hudson.util", "TextFile", True, "write", "(String)", "", "Argument[0]", "file-content-store", "manual"] - ["hudson.util", "HttpResponses", True, "staticResource", "(File)", "", "Argument[0]", "path-injection", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml index a44a2c6c400..04f1c2ebc19 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.handler.codec.http.multipart", "HttpPostRequestEncoder", True, "addBodyFileUpload", "(String,File,String,boolean)", "", "Argument[1]", "path-injection", "ai-manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestEncoder", True, "addBodyFileUpload", "(String,File,String,boolean)", "", "Argument[1]", "path-injection[read]", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/io.netty.handler.ssl.model.yml b/java/ql/lib/ext/io.netty.handler.ssl.model.yml index f63a7a3906f..2df3ddd6fbc 100644 --- a/java/ql/lib/ext/io.netty.handler.ssl.model.yml +++ b/java/ql/lib/ext/io.netty.handler.ssl.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.handler.ssl", "OpenSslServerContext", False, "OpenSslServerContext", "(File,File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["io.netty.handler.ssl", "SslContextBuilder", False, "forServer", "(File,File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["io.netty.handler.ssl", "OpenSslServerContext", False, "OpenSslServerContext", "(File,File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["io.netty.handler.ssl", "SslContextBuilder", False, "forServer", "(File,File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["io.netty.handler.ssl", "SslContextBuilder", False, "trustManager", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["io.netty.handler.ssl", "SslContextBuilder", False, "trustManager", "(InputStream)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/lib/ext/io.netty.handler.stream.model.yml b/java/ql/lib/ext/io.netty.handler.stream.model.yml index f4e635f4437..1a154c59192 100644 --- a/java/ql/lib/ext/io.netty.handler.stream.model.yml +++ b/java/ql/lib/ext/io.netty.handler.stream.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["io.netty.handler.stream", "ChunkedFile", True, "ChunkedFile", "(RandomAccessFile,long,long,int)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["io.netty.handler.stream", "ChunkedFile", True, "ChunkedFile", "(RandomAccessFile,long,long,int)", "", "Argument[0]", "path-injection[read]", "ai-manual"] diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index 07e39c9e12f..a611135f5db 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -23,16 +23,16 @@ extensions: - ["java.io", "File", True, "setReadable", "", "", "Argument[this]", "path-injection", "manual"] - ["java.io", "File", True, "setReadOnly", "", "", "Argument[this]", "path-injection", "manual"] - ["java.io", "File", True, "setWritable", "", "", "Argument[this]", "path-injection", "manual"] - - ["java.io", "FileInputStream", True, "FileInputStream", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.io", "FileInputStream", True, "FileInputStream", "(FileDescriptor)", "", "Argument[0]", "path-injection", "manual"] - - ["java.io", "FileInputStream", True, "FileInputStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.io", "FileInputStream", True, "FileInputStream", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.io", "FileInputStream", True, "FileInputStream", "(FileDescriptor)", "", "Argument[0]", "path-injection[read]", "manual"] + - ["java.io", "FileInputStream", True, "FileInputStream", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.io", "FileOutputStream", False, "FileOutputStream", "", "", "Argument[0]", "path-injection", "manual"] - ["java.io", "FileOutputStream", False, "write", "", "", "Argument[0]", "file-content-store", "manual"] - - ["java.io", "FileReader", True, "FileReader", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.io", "FileReader", True, "FileReader", "(FileDescriptor)", "", "Argument[0]", "path-injection", "manual"] - - ["java.io", "FileReader", True, "FileReader", "(File,Charset)", "", "Argument[0]", "path-injection", "manual"] - - ["java.io", "FileReader", True, "FileReader", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.io", "FileReader", True, "FileReader", "(String,Charset)", "", "Argument[0]", "path-injection", "manual"] + - ["java.io", "FileReader", True, "FileReader", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.io", "FileReader", True, "FileReader", "(FileDescriptor)", "", "Argument[0]", "path-injection[read]", "manual"] + - ["java.io", "FileReader", True, "FileReader", "(File,Charset)", "", "Argument[0]", "path-injection[read]", "manual"] + - ["java.io", "FileReader", True, "FileReader", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.io", "FileReader", True, "FileReader", "(String,Charset)", "", "Argument[0]", "path-injection[read]", "manual"] - ["java.io", "FileSystem", True, "createDirectory", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.io", "FileWriter", False, "FileWriter", "", "", "Argument[0]", "path-injection", "manual"] - ["java.io", "PrintStream", False, "PrintStream", "(File)", "", "Argument[0]", "path-injection", "manual"] diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index 8c2c448f4c2..9e3d9e8cee5 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -3,15 +3,15 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.lang", "Class", False, "getResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.lang", "Class", False, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.lang", "ClassLoader", False, "getSystemResources", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.lang", "ClassLoader", True, "getResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.lang", "ClassLoader", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.lang", "ClassLoader", True, "getResources", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.lang", "ClassLoader", True, "getSystemResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.lang", "ClassLoader", True, "getSystemResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.lang", "Class", False, "getResource", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.lang", "Class", False, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.lang", "ClassLoader", False, "getSystemResources", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.lang", "ClassLoader", True, "getResource", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.lang", "ClassLoader", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.lang", "ClassLoader", True, "getResources", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.lang", "ClassLoader", True, "getSystemResource", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.lang", "ClassLoader", True, "getSystemResourceAsStream", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.lang", "ProcessBuilder", False, "command", "(List)", "", "Argument[0]", "command-injection", "manual"] - ["java.lang", "ProcessBuilder", False, "command", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"] - ["java.lang", "ProcessBuilder", False, "directory", "(File)", "", "Argument[0]", "command-injection", "ai-manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 8d7db676e53..b74bdc4c290 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -3,8 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "path-injection", "manual"] - - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "path-injection[read]", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[0]", "path-injection[read]", "manual"] - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[1]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[0]", "file-content-store", "manual"] - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[1]", "path-injection", "manual"] @@ -19,22 +19,22 @@ extensions: - ["java.nio.file", "Files", False, "deleteIfExists", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "getFileStore", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] # the FileStore class is unlikely to be used for later sanitization - ["java.nio.file", "Files", False, "exists", "(Path,LinkOption[])", "", "Argument[0]", "path-injection", "manual"] - - ["java.nio.file", "Files", False, "lines", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.nio.file", "Files", False, "lines", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "lines", "(Path,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.nio.file", "Files", False, "lines", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "move", "", "", "Argument[1]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "move", "(Path,Path,CopyOption[])", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.nio.file", "Files", False, "newBufferedReader", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.nio.file", "Files", False, "newBufferedReader", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "newBufferedReader", "(Path,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.nio.file", "Files", False, "newBufferedReader", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "newBufferedWriter", "", "", "Argument[0]", "path-injection", "manual"] - - ["java.nio.file", "Files", False, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "newOutputStream", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "notExists", "(Path,LinkOption[])", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "probeContentType", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] # accesses the file based on user input, but only reads its content type from it - - ["java.nio.file", "Files", False, "readAllBytes", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.nio.file", "Files", False, "readAllLines", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.nio.file", "Files", False, "readAllLines", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.nio.file", "Files", False, "readString", "(Path,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.nio.file", "Files", False, "readString", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["java.nio.file", "Files", False, "readAllBytes", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.nio.file", "Files", False, "readAllLines", "(Path,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.nio.file", "Files", False, "readAllLines", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.nio.file", "Files", False, "readString", "(Path,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["java.nio.file", "Files", False, "readString", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "write", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "write", "", "", "Argument[1]", "file-content-store", "manual"] - ["java.nio.file", "Files", False, "writeString", "", "", "Argument[0]", "path-injection", "manual"] diff --git a/java/ql/lib/ext/javax.servlet.model.yml b/java/ql/lib/ext/javax.servlet.model.yml index cbf99dcd97e..19a6690858e 100644 --- a/java/ql/lib/ext/javax.servlet.model.yml +++ b/java/ql/lib/ext/javax.servlet.model.yml @@ -14,7 +14,7 @@ extensions: extensible: sinkModel data: - ["javax.servlet", "ServletContext", True, "getResource", "(String)", "", "Argument[0]", "path-injection", "manual"] - - ["javax.servlet", "ServletContext", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["javax.servlet", "ServletContext", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["javax.servlet", "ServletContext", True, "getRequestDispatcher", "(String)", "", "Argument[0]", "url-forward", "manual"] - ["javax.servlet", "ServletRequest", True, "getRequestDispatcher", "(String)", "", "Argument[0]", "url-forward", "manual"] - addsTo: diff --git a/java/ql/lib/ext/kotlin.io.model.yml b/java/ql/lib/ext/kotlin.io.model.yml index b748e04a292..550ba509a09 100644 --- a/java/ql/lib/ext/kotlin.io.model.yml +++ b/java/ql/lib/ext/kotlin.io.model.yml @@ -4,9 +4,9 @@ extensions: extensible: sinkModel data: - ["kotlin.io", "FilesKt", False, "deleteRecursively", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["kotlin.io", "FilesKt", False, "inputStream", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["kotlin.io", "FilesKt", False, "readBytes", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["kotlin.io", "FilesKt", False, "readText", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["kotlin.io", "FilesKt", False, "inputStream", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["kotlin.io", "FilesKt", False, "readBytes", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["kotlin.io", "FilesKt", False, "readText", "(File,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - addsTo: pack: codeql/java-all extensible: summaryModel diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml index 9c75ce8b41a..de4085a4455 100644 --- a/java/ql/lib/ext/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -36,7 +36,7 @@ extensions: - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[1]", "path-injection", "manual"] - ["org.apache.commons.io", "FileUtils", True, "copyToFile", "(InputStream,File)", "", "Argument[0]", "file-content-store", "ai-manual"] - ["org.apache.commons.io", "FileUtils", True, "copyToFile", "(InputStream,File)", "", "Argument[1]", "path-injection", "manual"] - - ["org.apache.commons.io", "FileUtils", True, "openInputStream", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.commons.io", "FileUtils", True, "openInputStream", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["org.apache.commons.io", "FileUtils", True, "delete", "(File)", "", "Argument[0]", "path-injection", "manual"] - ["org.apache.commons.io", "FileUtils", True, "deleteDirectory", "(File)", "", "Argument[0]", "path-injection", "manual"] - ["org.apache.commons.io", "FileUtils", True, "deleteQuietly", "(File)", "", "Argument[0]", "path-injection", "manual"] diff --git a/java/ql/lib/ext/org.apache.commons.net.model.yml b/java/ql/lib/ext/org.apache.commons.net.model.yml index 0a4c46e6a3c..689aa873d96 100644 --- a/java/ql/lib/ext/org.apache.commons.net.model.yml +++ b/java/ql/lib/ext/org.apache.commons.net.model.yml @@ -9,9 +9,9 @@ extensions: - ["org.apache.commons.net", "SocketClient", true, "connect", "(String)", "", "Argument[0]", "request-forgery", "manual"] - ["org.apache.commons.net", "SocketClient", true, "connect", "(String,int)", "", "Argument[0]", "request-forgery", "df-manual"] - ["org.apache.commons.net", "SocketClient", true, "connect", "(String,int,InetAddress,int)", "", "Argument[0]", "request-forgery", "manual"] - - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(File,String)", "", "Argument[0]", "path-injection", "df-manual"] - - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(File,String,String)", "", "Argument[0]", "path-injection", "df-manual"] - - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(String,File,String,String,String)", "", "Argument[1]", "path-injection", "df-manual"] + - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(File,String)", "", "Argument[0]", "path-injection[read]", "df-manual"] + - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(File,String,String)", "", "Argument[0]", "path-injection[read]", "df-manual"] + - ["org.apache.commons.net.util", "KeyManagerUtils", false, "createClientKeyManager", "(String,File,String,String,String)", "", "Argument[1]", "path-injection[read]", "df-manual"] - addsTo: pack: codeql/java-all extensible: sourceModel diff --git a/java/ql/lib/ext/org.apache.tools.ant.model.yml b/java/ql/lib/ext/org.apache.tools.ant.model.yml index 474429db030..cd1b6e198a4 100644 --- a/java/ql/lib/ext/org.apache.tools.ant.model.yml +++ b/java/ql/lib/ext/org.apache.tools.ant.model.yml @@ -3,8 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.tools.ant", "AntClassLoader", True, "addPathComponent", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(ClassLoader,Project,Path,boolean)", "", "Argument[2]", "path-injection", "ai-manual"] - - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(Project,Path,boolean)", "", "Argument[1]", "path-injection", "ai-manual"] - - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(Project,Path)", "", "Argument[1]", "path-injection", "ai-manual"] - - ["org.apache.tools.ant", "DirectoryScanner", True, "setBasedir", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant", "AntClassLoader", True, "addPathComponent", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(ClassLoader,Project,Path,boolean)", "", "Argument[2]", "path-injection[read]", "ai-manual"] + - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(Project,Path,boolean)", "", "Argument[1]", "path-injection[read]", "ai-manual"] + - ["org.apache.tools.ant", "AntClassLoader", True, "AntClassLoader", "(Project,Path)", "", "Argument[1]", "path-injection[read]", "ai-manual"] + - ["org.apache.tools.ant", "DirectoryScanner", True, "setBasedir", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] diff --git a/java/ql/lib/ext/org.apache.tools.ant.taskdefs.model.yml b/java/ql/lib/ext/org.apache.tools.ant.taskdefs.model.yml index 2695c2881f7..5d930f387e9 100644 --- a/java/ql/lib/ext/org.apache.tools.ant.taskdefs.model.yml +++ b/java/ql/lib/ext/org.apache.tools.ant.taskdefs.model.yml @@ -3,12 +3,12 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.apache.tools.ant.taskdefs", "Copy", True, "addFileset", "(FileSet)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["org.apache.tools.ant.taskdefs", "Copy", True, "setFile", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant.taskdefs", "Copy", True, "addFileset", "(FileSet)", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["org.apache.tools.ant.taskdefs", "Copy", True, "setFile", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["org.apache.tools.ant.taskdefs", "Copy", True, "setTodir", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["org.apache.tools.ant.taskdefs", "Copy", True, "setTofile", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["org.apache.tools.ant.taskdefs", "Execute", False, "runCommand", "(Task,String[])", "", "Argument[1]", "command-injection", "ai-manual"] - ["org.apache.tools.ant.taskdefs", "Expand", True, "setDest", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["org.apache.tools.ant.taskdefs", "Expand", True, "setSrc", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.tools.ant.taskdefs", "Expand", True, "setSrc", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["org.apache.tools.ant.taskdefs", "Property", True, "setFile", "(File)", "", "Argument[0]", "path-injection", "manual"] - ["org.apache.tools.ant.taskdefs", "Property", True, "setResource", "(String)", "", "Argument[0]", "path-injection", "manual"] diff --git a/java/ql/lib/ext/org.kohsuke.stapler.framework.io.model.yml b/java/ql/lib/ext/org.kohsuke.stapler.framework.io.model.yml index 49cd049cdfa..de662c04011 100644 --- a/java/ql/lib/ext/org.kohsuke.stapler.framework.io.model.yml +++ b/java/ql/lib/ext/org.kohsuke.stapler.framework.io.model.yml @@ -3,4 +3,4 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["org.kohsuke.stapler.framework.io", "LargeText", True, "LargeText", "(File,Charset,boolean,boolean)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.kohsuke.stapler.framework.io", "LargeText", True, "LargeText", "(File,Charset,boolean,boolean)", "", "Argument[0]", "path-injection[read]", "ai-manual"] diff --git a/java/ql/lib/ext/org.springframework.util.model.yml b/java/ql/lib/ext/org.springframework.util.model.yml index fffcebb72f8..a3c5e7448d8 100644 --- a/java/ql/lib/ext/org.springframework.util.model.yml +++ b/java/ql/lib/ext/org.springframework.util.model.yml @@ -4,7 +4,7 @@ extensions: extensible: sinkModel data: - ["org.springframework.util", "FileCopyUtils", False, "copy", "(byte[],File)", "", "Argument[1]", "path-injection", "manual"] - - ["org.springframework.util", "FileCopyUtils", False, "copy", "(File,File)", "", "Argument[0]", "path-injection", "manual"] + - ["org.springframework.util", "FileCopyUtils", False, "copy", "(File,File)", "", "Argument[0]", "path-injection[read]", "manual"] - ["org.springframework.util", "FileCopyUtils", False, "copy", "(File,File)", "", "Argument[1]", "path-injection", "manual"] - addsTo: diff --git a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll index 788cd542939..c88ef718768 100644 --- a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll +++ b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll @@ -290,7 +290,9 @@ private Method getSourceMethod(Method m) { } private class ExternalPathInjectionSanitizer extends PathInjectionSanitizer { - ExternalPathInjectionSanitizer() { barrierNode(this, "path-injection") } + ExternalPathInjectionSanitizer() { + barrierNode(this, ["path-injection", "path-injection[read]"]) + } } /** Holds if `g` is a guard that checks for `..` components. */ diff --git a/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll b/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll index 6726bcc3508..cb04f39101c 100644 --- a/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll @@ -12,7 +12,7 @@ private import semmle.code.java.security.Sanitizers abstract class TaintedPathSink extends DataFlow::Node { } private class DefaultTaintedPathSink extends TaintedPathSink { - DefaultTaintedPathSink() { sinkNode(this, "path-injection") } + DefaultTaintedPathSink() { sinkNode(this, ["path-injection", "path-injection[read]"]) } } /** diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index 9e2e5e4a6c7..84a94d87dce 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -52,6 +52,11 @@ module ZipSlipFlow = TaintTracking::Global; /** * A sink that represents a file creation, such as a file write, copy or move operation. + * + * This deliberately selects only the `path-injection` sink kind and excludes + * `path-injection[read]`: Zip Slip is an archive-extraction vulnerability, so + * read-only path sinks (e.g. `ClassLoader.getResource`, `FileInputStream`, + * `File.exists`) are outside the threat model. */ private class FileCreationSink extends DataFlow::Node { FileCreationSink() { sinkNode(this, "path-injection") } diff --git a/java/ql/src/change-notes/2026-04-21-zipslip-exclude-read-sinks.md b/java/ql/src/change-notes/2026-04-21-zipslip-exclude-read-sinks.md new file mode 100644 index 00000000000..ee688924052 --- /dev/null +++ b/java/ql/src/change-notes/2026-04-21-zipslip-exclude-read-sinks.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `java/zipslip` query no longer reports archive entry names that flow only to read-only path sinks such as `ClassLoader.getResource`, `FileInputStream`, and `FileReader`. The query now restricts its sinks to the `path-injection` kind and deliberately excludes the new `path-injection[read]` sub-kind, matching the Zip Slip threat model of unsafe archive extraction. diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected index aee29733bca..5a6fc6dab46 100644 --- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected +++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected @@ -255,20 +255,20 @@ models | 18 | Sink: java.io; File; true; setReadOnly; ; ; Argument[this]; path-injection; manual | | 19 | Sink: java.io; File; true; setReadable; ; ; Argument[this]; path-injection; manual | | 20 | Sink: java.io; File; true; setWritable; ; ; Argument[this]; path-injection; manual | -| 21 | Sink: java.io; FileInputStream; true; FileInputStream; (File); ; Argument[0]; path-injection; ai-manual | -| 22 | Sink: java.io; FileInputStream; true; FileInputStream; (FileDescriptor); ; Argument[0]; path-injection; manual | -| 23 | Sink: java.io; FileInputStream; true; FileInputStream; (String); ; Argument[0]; path-injection; ai-manual | -| 24 | Sink: java.io; FileReader; true; FileReader; (File); ; Argument[0]; path-injection; ai-manual | -| 25 | Sink: java.io; FileReader; true; FileReader; (File,Charset); ; Argument[0]; path-injection; manual | -| 26 | Sink: java.io; FileReader; true; FileReader; (FileDescriptor); ; Argument[0]; path-injection; manual | -| 27 | Sink: java.io; FileReader; true; FileReader; (String); ; Argument[0]; path-injection; ai-manual | -| 28 | Sink: java.io; FileReader; true; FileReader; (String,Charset); ; Argument[0]; path-injection; manual | -| 29 | Sink: java.lang; Class; false; getResource; (String); ; Argument[0]; path-injection; ai-manual | -| 30 | Sink: java.lang; ClassLoader; true; getSystemResourceAsStream; (String); ; Argument[0]; path-injection; ai-manual | -| 31 | Sink: java.lang; Module; true; getResourceAsStream; (String); ; Argument[0]; path-injection; ai-manual | +| 21 | Sink: java.io; FileInputStream; true; FileInputStream; (File); ; Argument[0]; path-injection[read]; ai-manual | +| 22 | Sink: java.io; FileInputStream; true; FileInputStream; (FileDescriptor); ; Argument[0]; path-injection[read]; manual | +| 23 | Sink: java.io; FileInputStream; true; FileInputStream; (String); ; Argument[0]; path-injection[read]; ai-manual | +| 24 | Sink: java.io; FileReader; true; FileReader; (File); ; Argument[0]; path-injection[read]; ai-manual | +| 25 | Sink: java.io; FileReader; true; FileReader; (File,Charset); ; Argument[0]; path-injection[read]; manual | +| 26 | Sink: java.io; FileReader; true; FileReader; (FileDescriptor); ; Argument[0]; path-injection[read]; manual | +| 27 | Sink: java.io; FileReader; true; FileReader; (String); ; Argument[0]; path-injection[read]; ai-manual | +| 28 | Sink: java.io; FileReader; true; FileReader; (String,Charset); ; Argument[0]; path-injection[read]; manual | +| 29 | Sink: java.lang; Class; false; getResource; (String); ; Argument[0]; path-injection[read]; ai-manual | +| 30 | Sink: java.lang; ClassLoader; true; getSystemResourceAsStream; (String); ; Argument[0]; path-injection[read]; ai-manual | +| 31 | Sink: java.lang; Module; true; getResourceAsStream; (String); ; Argument[0]; path-injection[read]; ai-manual | | 32 | Sink: java.nio.file; Files; false; copy; (InputStream,Path,CopyOption[]); ; Argument[1]; path-injection; manual | -| 33 | Sink: java.nio.file; Files; false; copy; (Path,OutputStream); ; Argument[0]; path-injection; manual | -| 34 | Sink: java.nio.file; Files; false; copy; (Path,Path,CopyOption[]); ; Argument[0]; path-injection; manual | +| 33 | Sink: java.nio.file; Files; false; copy; (Path,OutputStream); ; Argument[0]; path-injection[read]; manual | +| 34 | Sink: java.nio.file; Files; false; copy; (Path,Path,CopyOption[]); ; Argument[0]; path-injection[read]; manual | | 35 | Sink: java.nio.file; Files; false; copy; (Path,Path,CopyOption[]); ; Argument[1]; path-injection; manual | | 36 | Sink: java.nio.file; Files; false; createDirectories; ; ; Argument[0]; path-injection; manual | | 37 | Sink: java.nio.file; Files; false; createDirectory; ; ; Argument[0]; path-injection; manual | @@ -279,31 +279,31 @@ models | 42 | Sink: java.nio.file; Files; false; createTempFile; (Path,String,String,FileAttribute[]); ; Argument[0]; path-injection; manual | | 43 | Sink: java.nio.file; Files; false; delete; (Path); ; Argument[0]; path-injection; ai-manual | | 44 | Sink: java.nio.file; Files; false; deleteIfExists; (Path); ; Argument[0]; path-injection; ai-manual | -| 45 | Sink: java.nio.file; Files; false; lines; (Path,Charset); ; Argument[0]; path-injection; ai-manual | +| 45 | Sink: java.nio.file; Files; false; lines; (Path,Charset); ; Argument[0]; path-injection[read]; ai-manual | | 46 | Sink: java.nio.file; Files; false; move; ; ; Argument[1]; path-injection; manual | -| 47 | Sink: java.nio.file; Files; false; newBufferedReader; (Path,Charset); ; Argument[0]; path-injection; ai-manual | +| 47 | Sink: java.nio.file; Files; false; newBufferedReader; (Path,Charset); ; Argument[0]; path-injection[read]; ai-manual | | 48 | Sink: java.nio.file; Files; false; newBufferedWriter; ; ; Argument[0]; path-injection; manual | | 49 | Sink: java.nio.file; Files; false; newOutputStream; ; ; Argument[0]; path-injection; manual | | 50 | Sink: java.nio.file; Files; false; write; ; ; Argument[0]; path-injection; manual | | 51 | Sink: java.nio.file; Files; false; writeString; ; ; Argument[0]; path-injection; manual | | 52 | Sink: javax.xml.transform.stream; StreamResult; true; StreamResult; (File); ; Argument[0]; path-injection; ai-manual | -| 53 | Sink: org.apache.commons.io; FileUtils; true; openInputStream; (File); ; Argument[0]; path-injection; ai-manual | -| 54 | Sink: org.apache.tools.ant.taskdefs; Copy; true; addFileset; (FileSet); ; Argument[0]; path-injection; ai-manual | -| 55 | Sink: org.apache.tools.ant.taskdefs; Copy; true; setFile; (File); ; Argument[0]; path-injection; ai-manual | +| 53 | Sink: org.apache.commons.io; FileUtils; true; openInputStream; (File); ; Argument[0]; path-injection[read]; ai-manual | +| 54 | Sink: org.apache.tools.ant.taskdefs; Copy; true; addFileset; (FileSet); ; Argument[0]; path-injection[read]; ai-manual | +| 55 | Sink: org.apache.tools.ant.taskdefs; Copy; true; setFile; (File); ; Argument[0]; path-injection[read]; ai-manual | | 56 | Sink: org.apache.tools.ant.taskdefs; Copy; true; setTodir; (File); ; Argument[0]; path-injection; ai-manual | | 57 | Sink: org.apache.tools.ant.taskdefs; Copy; true; setTofile; (File); ; Argument[0]; path-injection; ai-manual | | 58 | Sink: org.apache.tools.ant.taskdefs; Expand; true; setDest; (File); ; Argument[0]; path-injection; ai-manual | -| 59 | Sink: org.apache.tools.ant.taskdefs; Expand; true; setSrc; (File); ; Argument[0]; path-injection; ai-manual | -| 60 | Sink: org.apache.tools.ant; AntClassLoader; true; AntClassLoader; (ClassLoader,Project,Path,boolean); ; Argument[2]; path-injection; ai-manual | -| 61 | Sink: org.apache.tools.ant; AntClassLoader; true; AntClassLoader; (Project,Path); ; Argument[1]; path-injection; ai-manual | -| 62 | Sink: org.apache.tools.ant; AntClassLoader; true; AntClassLoader; (Project,Path,boolean); ; Argument[1]; path-injection; ai-manual | -| 63 | Sink: org.apache.tools.ant; AntClassLoader; true; addPathComponent; (File); ; Argument[0]; path-injection; ai-manual | -| 64 | Sink: org.apache.tools.ant; DirectoryScanner; true; setBasedir; (File); ; Argument[0]; path-injection; ai-manual | +| 59 | Sink: org.apache.tools.ant.taskdefs; Expand; true; setSrc; (File); ; Argument[0]; path-injection[read]; ai-manual | +| 60 | Sink: org.apache.tools.ant; AntClassLoader; true; AntClassLoader; (ClassLoader,Project,Path,boolean); ; Argument[2]; path-injection[read]; ai-manual | +| 61 | Sink: org.apache.tools.ant; AntClassLoader; true; AntClassLoader; (Project,Path); ; Argument[1]; path-injection[read]; ai-manual | +| 62 | Sink: org.apache.tools.ant; AntClassLoader; true; AntClassLoader; (Project,Path,boolean); ; Argument[1]; path-injection[read]; ai-manual | +| 63 | Sink: org.apache.tools.ant; AntClassLoader; true; addPathComponent; (File); ; Argument[0]; path-injection[read]; ai-manual | +| 64 | Sink: org.apache.tools.ant; DirectoryScanner; true; setBasedir; (File); ; Argument[0]; path-injection[read]; ai-manual | | 65 | Sink: org.codehaus.cargo.container.installer; ZipURLInstaller; true; ZipURLInstaller; (URL,String,String); ; Argument[1]; path-injection; ai-manual | | 66 | Sink: org.codehaus.cargo.container.installer; ZipURLInstaller; true; ZipURLInstaller; (URL,String,String); ; Argument[2]; path-injection; ai-manual | -| 67 | Sink: org.kohsuke.stapler.framework.io; LargeText; true; LargeText; (File,Charset,boolean,boolean); ; Argument[0]; path-injection; ai-manual | +| 67 | Sink: org.kohsuke.stapler.framework.io; LargeText; true; LargeText; (File,Charset,boolean,boolean); ; Argument[0]; path-injection[read]; ai-manual | | 68 | Sink: org.openjdk.jmh.runner.options; ChainedOptionsBuilder; true; result; (String); ; Argument[0]; path-injection; ai-manual | -| 69 | Sink: org.springframework.util; FileCopyUtils; false; copy; (File,File); ; Argument[0]; path-injection; manual | +| 69 | Sink: org.springframework.util; FileCopyUtils; false; copy; (File,File); ; Argument[0]; path-injection[read]; manual | | 70 | Sink: org.springframework.util; FileCopyUtils; false; copy; (File,File); ; Argument[1]; path-injection; manual | | 71 | Sink: org.springframework.util; FileCopyUtils; false; copy; (byte[],File); ; Argument[1]; path-injection; manual | | 72 | Source: java.net; Socket; false; getInputStream; (); ; ReturnValue; remote; manual | diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java b/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java index b5bee61b965..2c5e1cd9d53 100644 --- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java +++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java @@ -60,4 +60,16 @@ public class ZipTest { throw new Exception(); OutputStream os = Files.newOutputStream(target); // OK } + + // Regression for https://github.com/github/codeql/issues/21606: archive entry + // names flowing into read-only classpath/resource lookups are outside the + // Zip Slip threat model. + public void m7(ZipEntry entry) throws Exception { + String name = entry.getName(); + ClassLoader.getSystemResources(name); // OK - read-only resource lookup + getClass().getResource(name); // OK - read-only resource lookup + getClass().getResourceAsStream(name); // OK - read-only resource lookup + new FileInputStream(name); // OK - read-only file open + new FileReader(name); // OK - read-only file open + } } diff --git a/shared/mad/codeql/mad/ModelValidation.qll b/shared/mad/codeql/mad/ModelValidation.qll index 5eaa78626ab..b5f3e078a52 100644 --- a/shared/mad/codeql/mad/ModelValidation.qll +++ b/shared/mad/codeql/mad/ModelValidation.qll @@ -54,6 +54,11 @@ module KindValidation { this.matches([ // shared "credentials-%", "encryption-%", "qltest%", "test-%", "regex-use%", + // shared: path-injection[read] identifies sinks that only read from a path + // (e.g. ClassLoader.getResource, FileInputStream, File.exists). Queries such + // as java/zipslip that only care about write/extraction deliberately exclude + // this sub-kind. + "path-injection[%]", // Swift-only currently, but may be shared in the future "%string-%length", "weak-hash-input-%", // Go-only currently, but may be shared in the future From 6d10b1582fbb3c6107c7cb0947c2963748ef97ea Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Tue, 21 Apr 2026 19:45:13 +0800 Subject: [PATCH 02/43] Java: update regression-test expectations for path-injection[read] The sink-model generator and the experimental java/file-path-injection query now observe the new path-injection[read] sub-kind for the FileInputStream and Files.copy source-argument models. - CWE-073 FilePathInjection.expected: refresh the models table for the renamed kind on FileInputStream(File); alerts unchanged. - modelgenerator Sinks.java: update the inline sink annotation for copyFileToDirectory(Path,Path,CopyOption[]) Argument[0] to the new path-injection[read] sub-kind, mirroring the library change. --- .../query-tests/security/CWE-073/FilePathInjection.expected | 2 +- java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected b/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected index 9ddb2082948..5752ac764df 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected @@ -10,7 +10,7 @@ edges | FilePathInjection.java:217:19:217:22 | file : File | FilePathInjection.java:177:50:177:58 | file : File | provenance | | models | 1 | Sink: java.io; File; true; exists; (); ; Argument[this]; path-injection; manual | -| 2 | Sink: java.io; FileInputStream; true; FileInputStream; (File); ; Argument[0]; path-injection; ai-manual | +| 2 | Sink: java.io; FileInputStream; true; FileInputStream; (File); ; Argument[0]; path-injection[read]; ai-manual | | 3 | Sink: java.io; FileOutputStream; false; FileOutputStream; ; ; Argument[0]; path-injection; manual | | 4 | Source: com.jfinal.core; Controller; true; getPara; ; ; ReturnValue; remote; manual | | 5 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual | diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java b/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java index d9a0d9324f3..13c84954ca0 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java @@ -33,7 +33,7 @@ public class Sinks { return null; } - // sink=p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[0];path-injection;df-generated + // sink=p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[0];path-injection[read];df-generated // sink=p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];path-injection;df-generated // neutral=p;Sinks;copyFileToDirectory;(Path,Path,CopyOption[]);summary;df-generated public Path copyFileToDirectory( From 936f0c650c4efe35ba78005cdfc0308333c13129 Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Thu, 30 Apr 2026 19:06:04 +0800 Subject: [PATCH 03/43] Address review comments on path-injection[read] sub-kind - shared/mad/codeql/mad/ModelValidation.qll: shorten the comment for `path-injection[%]` to `// Java-only currently`, matching the style of other language-scoped entries and dropping API examples and the java/zipslip reference. - java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll: replace the `File.exists` example in the QLDoc with `FileReader`, since `File.exists` is still labelled plain `path-injection`, not `path-injection[read]`. --- java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll | 4 ++-- shared/mad/codeql/mad/ModelValidation.qll | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll index 84a94d87dce..b7bcbcceeb9 100644 --- a/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll @@ -55,8 +55,8 @@ module ZipSlipFlow = TaintTracking::Global; * * This deliberately selects only the `path-injection` sink kind and excludes * `path-injection[read]`: Zip Slip is an archive-extraction vulnerability, so - * read-only path sinks (e.g. `ClassLoader.getResource`, `FileInputStream`, - * `File.exists`) are outside the threat model. + * read-only path sinks (for example `ClassLoader.getResource`, + * `FileInputStream`, and `FileReader`) are outside the threat model. */ private class FileCreationSink extends DataFlow::Node { FileCreationSink() { sinkNode(this, "path-injection") } diff --git a/shared/mad/codeql/mad/ModelValidation.qll b/shared/mad/codeql/mad/ModelValidation.qll index b5f3e078a52..3f11d3ce089 100644 --- a/shared/mad/codeql/mad/ModelValidation.qll +++ b/shared/mad/codeql/mad/ModelValidation.qll @@ -54,10 +54,7 @@ module KindValidation { this.matches([ // shared "credentials-%", "encryption-%", "qltest%", "test-%", "regex-use%", - // shared: path-injection[read] identifies sinks that only read from a path - // (e.g. ClassLoader.getResource, FileInputStream, File.exists). Queries such - // as java/zipslip that only care about write/extraction deliberately exclude - // this sub-kind. + // Java-only currently "path-injection[%]", // Swift-only currently, but may be shared in the future "%string-%length", "weak-hash-input-%", From 119994b59f5fe20a2f64315f763be239c49ee74c Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Fri, 1 May 2026 16:04:29 +0800 Subject: [PATCH 04/43] Java: move File inspection methods to path-injection[read] Per review feedback on #21741: File.canRead/canWrite/canExecute, exists/isDirectory/isFile/isHidden only inspect a path, so move them under the path-injection[read] sub-kind. Update TaintedPath.expected and the experimental CWE-073 expected to match. --- java/ql/lib/ext/java.io.model.yml | 14 +++++++------- .../security/CWE-073/FilePathInjection.expected | 2 +- .../CWE-022/semmle/tests/TaintedPath.expected | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index a611135f5db..dd47342d590 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -3,17 +3,17 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.io", "File", True, "canExecute", "()", "", "Argument[this]", "path-injection", "manual"] - - ["java.io", "File", True, "canRead", "()", "", "Argument[this]", "path-injection", "manual"] - - ["java.io", "File", True, "canWrite", "()", "", "Argument[this]", "path-injection", "manual"] + - ["java.io", "File", True, "canExecute", "()", "", "Argument[this]", "path-injection[read]", "manual"] + - ["java.io", "File", True, "canRead", "()", "", "Argument[this]", "path-injection[read]", "manual"] + - ["java.io", "File", True, "canWrite", "()", "", "Argument[this]", "path-injection[read]", "manual"] - ["java.io", "File", True, "createNewFile", "()", "", "Argument[this]", "path-injection", "ai-manual"] - ["java.io", "File", True, "createTempFile", "(String,String,File)", "", "Argument[2]", "path-injection", "ai-manual"] - ["java.io", "File", True, "delete", "()", "", "Argument[this]", "path-injection", "manual"] - ["java.io", "File", True, "deleteOnExit", "()", "", "Argument[this]", "path-injection", "manual"] - - ["java.io", "File", True, "exists", "()", "", "Argument[this]", "path-injection", "manual"] - - ["java.io", "File", True, "isDirectory", "()", "", "Argument[this]", "path-injection", "manual"] - - ["java.io", "File", True, "isFile", "()", "", "Argument[this]", "path-injection", "manual"] - - ["java.io", "File", True, "isHidden", "()", "", "Argument[this]", "path-injection", "manual"] + - ["java.io", "File", True, "exists", "()", "", "Argument[this]", "path-injection[read]", "manual"] + - ["java.io", "File", True, "isDirectory", "()", "", "Argument[this]", "path-injection[read]", "manual"] + - ["java.io", "File", True, "isFile", "()", "", "Argument[this]", "path-injection[read]", "manual"] + - ["java.io", "File", True, "isHidden", "()", "", "Argument[this]", "path-injection[read]", "manual"] - ["java.io", "File", True, "mkdir", "()", "", "Argument[this]", "path-injection", "manual"] - ["java.io", "File", True, "mkdirs", "()", "", "Argument[this]", "path-injection", "manual"] - ["java.io", "File", True, "renameTo", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] diff --git a/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected b/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected index 5752ac764df..e1567af8ada 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-073/FilePathInjection.expected @@ -9,7 +9,7 @@ edges | FilePathInjection.java:209:24:209:31 | filePath : String | FilePathInjection.java:209:15:209:32 | new File(...) : File | provenance | MaD:6 | | FilePathInjection.java:217:19:217:22 | file : File | FilePathInjection.java:177:50:177:58 | file : File | provenance | | models -| 1 | Sink: java.io; File; true; exists; (); ; Argument[this]; path-injection; manual | +| 1 | Sink: java.io; File; true; exists; (); ; Argument[this]; path-injection[read]; manual | | 2 | Sink: java.io; FileInputStream; true; FileInputStream; (File); ; Argument[0]; path-injection[read]; ai-manual | | 3 | Sink: java.io; FileOutputStream; false; FileOutputStream; ; ; Argument[0]; path-injection; manual | | 4 | Source: com.jfinal.core; Controller; true; getPara; ; ; ReturnValue; remote; manual | diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected index 5a6fc6dab46..06ab1d6340d 100644 --- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected +++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected @@ -235,17 +235,17 @@ edges | Test.java:199:26:199:33 | source(...) : String | Test.java:199:19:199:33 | (...)... | provenance | Sink:MaD:59 | | Test.java:204:29:204:36 | source(...) : String | Test.java:204:20:204:36 | (...)... | provenance | Sink:MaD:68 | models -| 1 | Sink: java.io; File; true; canExecute; (); ; Argument[this]; path-injection; manual | -| 2 | Sink: java.io; File; true; canRead; (); ; Argument[this]; path-injection; manual | -| 3 | Sink: java.io; File; true; canWrite; (); ; Argument[this]; path-injection; manual | +| 1 | Sink: java.io; File; true; canExecute; (); ; Argument[this]; path-injection[read]; manual | +| 2 | Sink: java.io; File; true; canRead; (); ; Argument[this]; path-injection[read]; manual | +| 3 | Sink: java.io; File; true; canWrite; (); ; Argument[this]; path-injection[read]; manual | | 4 | Sink: java.io; File; true; createNewFile; (); ; Argument[this]; path-injection; ai-manual | | 5 | Sink: java.io; File; true; createTempFile; (String,String,File); ; Argument[2]; path-injection; ai-manual | | 6 | Sink: java.io; File; true; delete; (); ; Argument[this]; path-injection; manual | | 7 | Sink: java.io; File; true; deleteOnExit; (); ; Argument[this]; path-injection; manual | -| 8 | Sink: java.io; File; true; exists; (); ; Argument[this]; path-injection; manual | -| 9 | Sink: java.io; File; true; isDirectory; (); ; Argument[this]; path-injection; manual | -| 10 | Sink: java.io; File; true; isFile; (); ; Argument[this]; path-injection; manual | -| 11 | Sink: java.io; File; true; isHidden; (); ; Argument[this]; path-injection; manual | +| 8 | Sink: java.io; File; true; exists; (); ; Argument[this]; path-injection[read]; manual | +| 9 | Sink: java.io; File; true; isDirectory; (); ; Argument[this]; path-injection[read]; manual | +| 10 | Sink: java.io; File; true; isFile; (); ; Argument[this]; path-injection[read]; manual | +| 11 | Sink: java.io; File; true; isHidden; (); ; Argument[this]; path-injection[read]; manual | | 12 | Sink: java.io; File; true; mkdir; (); ; Argument[this]; path-injection; manual | | 13 | Sink: java.io; File; true; mkdirs; (); ; Argument[this]; path-injection; manual | | 14 | Sink: java.io; File; true; renameTo; (File); ; Argument[0]; path-injection; ai-manual | From 3ad2d8ca3d69e7005e1d4bb228d6e8557c7d2f16 Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Sun, 3 May 2026 14:04:35 +0800 Subject: [PATCH 05/43] Update java/ql/lib/ext/java.nio.file.model.yml Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- java/ql/lib/ext/java.nio.file.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index b74bdc4c290..cf630a4b48a 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -18,7 +18,7 @@ extensions: - ["java.nio.file", "Files", False, "delete", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "deleteIfExists", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "getFileStore", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] # the FileStore class is unlikely to be used for later sanitization - - ["java.nio.file", "Files", False, "exists", "(Path,LinkOption[])", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "exists", "(Path,LinkOption[])", "", "Argument[0]", "path-injection[read]", "manual"] - ["java.nio.file", "Files", False, "lines", "(Path,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "lines", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "move", "", "", "Argument[1]", "path-injection", "manual"] From 62a0a3e384788b281a05936a38d3646f1041ad60 Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Sun, 3 May 2026 14:08:12 +0800 Subject: [PATCH 06/43] Update java/ql/lib/ext/java.nio.file.model.yml Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- java/ql/lib/ext/java.nio.file.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index cf630a4b48a..45c30426e08 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -28,7 +28,7 @@ extensions: - ["java.nio.file", "Files", False, "newBufferedWriter", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "newOutputStream", "", "", "Argument[0]", "path-injection", "manual"] - - ["java.nio.file", "Files", False, "notExists", "(Path,LinkOption[])", "", "Argument[0]", "path-injection", "manual"] + - ["java.nio.file", "Files", False, "notExists", "(Path,LinkOption[])", "", "Argument[0]", "path-injection[read]", "manual"] - ["java.nio.file", "Files", False, "probeContentType", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] # accesses the file based on user input, but only reads its content type from it - ["java.nio.file", "Files", False, "readAllBytes", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "readAllLines", "(Path,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] From 7050241a54161945b2193b277b15594f4672e6e9 Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Sun, 3 May 2026 14:08:21 +0800 Subject: [PATCH 07/43] Update java/ql/lib/ext/java.nio.file.model.yml Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- java/ql/lib/ext/java.nio.file.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 45c30426e08..4fb29e9e055 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -29,7 +29,7 @@ extensions: - ["java.nio.file", "Files", False, "newInputStream", "(Path,OpenOption[])", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "newOutputStream", "", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "notExists", "(Path,LinkOption[])", "", "Argument[0]", "path-injection[read]", "manual"] - - ["java.nio.file", "Files", False, "probeContentType", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] # accesses the file based on user input, but only reads its content type from it + - ["java.nio.file", "Files", False, "probeContentType", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] # accesses the file based on user input, but only reads its content type from it - ["java.nio.file", "Files", False, "readAllBytes", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "readAllLines", "(Path,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "readAllLines", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] From 9194cdad9c0d4d6375692a3409ee981e7f15f7e0 Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Sun, 3 May 2026 14:08:31 +0800 Subject: [PATCH 08/43] Update java/ql/lib/ext/java.nio.file.model.yml Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- java/ql/lib/ext/java.nio.file.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 4fb29e9e055..66cbe2da7b4 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -17,7 +17,7 @@ extensions: - ["java.nio.file", "Files", False, "createTempFile", "(Path,String,String,FileAttribute[])", "", "Argument[0]", "path-injection", "manual"] - ["java.nio.file", "Files", False, "delete", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - ["java.nio.file", "Files", False, "deleteIfExists", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["java.nio.file", "Files", False, "getFileStore", "(Path)", "", "Argument[0]", "path-injection", "ai-manual"] # the FileStore class is unlikely to be used for later sanitization + - ["java.nio.file", "Files", False, "getFileStore", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] # the FileStore class is unlikely to be used for later sanitization - ["java.nio.file", "Files", False, "exists", "(Path,LinkOption[])", "", "Argument[0]", "path-injection[read]", "manual"] - ["java.nio.file", "Files", False, "lines", "(Path,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["java.nio.file", "Files", False, "lines", "(Path)", "", "Argument[0]", "path-injection[read]", "ai-manual"] From dbc9d0de4a17ac5fa39ffe1deea4ec2448c615fb Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Sun, 3 May 2026 14:14:07 +0800 Subject: [PATCH 09/43] Update java/ql/lib/ext/org.apache.commons.io.model.yml Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- java/ql/lib/ext/org.apache.commons.io.model.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml index de4085a4455..98a7788983f 100644 --- a/java/ql/lib/ext/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -29,7 +29,8 @@ extensions: - ["org.apache.commons.io", "FileUtils", False, "forceMkdir", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "moveDirectory", "(File,File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "readFileToByteArray", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - - ["org.apache.commons.io", "FileUtils", False, "readFileToString", "(File,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] +- ["org.apache.commons.io", "FileUtils", False, "readFileToByteArray", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] +- ["org.apache.commons.io", "FileUtils", False, "readFileToString", "(File,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "writeLines", "(File,String,Collection,String)", "", "Argument[3]", "file-content-store", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "writeStringToFile", "(File,String,Charset,boolean)", "", "Argument[1]", "file-content-store", "ai-manual"] - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[0]", "file-content-store", "ai-manual"] From 8710e63011121f1fd15233d9f816cc5eceb40ef0 Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Sun, 3 May 2026 14:14:15 +0800 Subject: [PATCH 10/43] Update java/ql/lib/ext/javax.servlet.model.yml Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- java/ql/lib/ext/javax.servlet.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/javax.servlet.model.yml b/java/ql/lib/ext/javax.servlet.model.yml index 19a6690858e..3d4a580edfc 100644 --- a/java/ql/lib/ext/javax.servlet.model.yml +++ b/java/ql/lib/ext/javax.servlet.model.yml @@ -13,7 +13,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["javax.servlet", "ServletContext", True, "getResource", "(String)", "", "Argument[0]", "path-injection", "manual"] + - ["javax.servlet", "ServletContext", True, "getResource", "(String)", "", "Argument[0]", "path-injection[read]", "manual"] - ["javax.servlet", "ServletContext", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["javax.servlet", "ServletContext", True, "getRequestDispatcher", "(String)", "", "Argument[0]", "url-forward", "manual"] - ["javax.servlet", "ServletRequest", True, "getRequestDispatcher", "(String)", "", "Argument[0]", "url-forward", "manual"] From c10a05f26a218afd202af4e58f9ef7b7b5afc700 Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Sun, 3 May 2026 14:14:48 +0800 Subject: [PATCH 11/43] Update java/ql/lib/ext/org.apache.commons.io.model.yml Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- java/ql/lib/ext/org.apache.commons.io.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml index 98a7788983f..910635ce19d 100644 --- a/java/ql/lib/ext/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -44,4 +44,4 @@ extensions: - ["org.apache.commons.io", "FileUtils", True, "forceDelete", "(File)", "", "Argument[0]", "path-injection", "manual"] - ["org.apache.commons.io", "FileUtils", True, "forceDeleteOnExit", "(File)", "", "Argument[0]", "path-injection", "manual"] - ["org.apache.commons.io", "FileUtils", True, "forceMkdirParent", "(File)", "", "Argument[0]", "path-injection", "manual"] - - ["org.apache.commons.io", "IOUtils", False, "resourceToString", "(String,Charset)", "", "Argument[0]", "path-injection", "ai-manual"] + - ["org.apache.commons.io", "IOUtils", False, "resourceToString", "", "", "Argument[0]", "path-injection[read]", "ai-manual"] From 49e5886a06f8f8904f050c09f7ee30b206f8a469 Mon Sep 17 00:00:00 2001 From: MarkLee131 Date: Mon, 4 May 2026 12:56:11 +0800 Subject: [PATCH 12/43] Update java/ql/lib/ext/org.apache.commons.io.model.yml Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- java/ql/lib/ext/org.apache.commons.io.model.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml index 910635ce19d..f6ced2d2b85 100644 --- a/java/ql/lib/ext/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -29,8 +29,7 @@ extensions: - ["org.apache.commons.io", "FileUtils", False, "forceMkdir", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "moveDirectory", "(File,File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "readFileToByteArray", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] -- ["org.apache.commons.io", "FileUtils", False, "readFileToByteArray", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"] -- ["org.apache.commons.io", "FileUtils", False, "readFileToString", "(File,Charset)", "", "Argument[0]", "path-injection[read]", "ai-manual"] +- ["org.apache.commons.io", "FileUtils", False, "readFileToByteArray", "", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "writeLines", "(File,String,Collection,String)", "", "Argument[3]", "file-content-store", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "writeStringToFile", "(File,String,Charset,boolean)", "", "Argument[1]", "file-content-store", "ai-manual"] - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[0]", "file-content-store", "ai-manual"] From 88e1d86c27cc5d9ca6062cd645d7c59a7cf9b73c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 5 May 2026 09:34:30 +0000 Subject: [PATCH 13/43] Release preparation for version 2.25.4 --- actions/ql/lib/CHANGELOG.md | 4 ++ .../ql/lib/change-notes/released/0.4.35.md | 3 ++ actions/ql/lib/codeql-pack.release.yml | 2 +- actions/ql/lib/qlpack.yml | 2 +- actions/ql/src/CHANGELOG.md | 6 ++- .../ql/src/change-notes/released/0.6.27.md | 3 ++ actions/ql/src/codeql-pack.release.yml | 2 +- actions/ql/src/qlpack.yml | 2 +- cpp/ql/lib/CHANGELOG.md | 11 ++++++ .../2026-03-20-data-extensions-barriers.md | 4 -- .../change-notes/2026-03-28-switch-stmt.md | 4 -- cpp/ql/lib/change-notes/2026-04-28-strsafe.md | 4 -- cpp/ql/lib/change-notes/released/10.1.0.md | 10 +++++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 6 ++- cpp/ql/src/change-notes/released/1.6.2.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.66.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.66.md | 3 ++ .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 39 +++++++++++++++++++ ...26-03-06-compound-assignment-operations.md | 4 -- .../2026-03-20-data-extensions-barriers.md | 4 -- .../2026-04-01-asp-remote-sources.md | 4 -- .../2026-04-10-nuget-feed-usage-in-bmn.md | 4 -- csharp/ql/lib/change-notes/2026-04-13-cfg.md | 20 ---------- .../2026-05-01-ssa-replacement.md | 4 -- csharp/ql/lib/change-notes/released/6.0.0.md | 38 ++++++++++++++++++ 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.2.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.49.md | 3 ++ .../codeql-pack.release.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 6 +++ .../7.1.0.md} | 7 ++-- 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.2.md | 3 ++ go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 15 +++++++ .../2026-03-20-data-extensions-barriers.md | 4 -- .../2026-04-04-path-injection-torealpath.md | 4 -- .../2026-04-04-sensitive-log-fp-reduction.md | 4 -- ...2026-04-04-sensitive-log-hash-sanitizer.md | 4 -- ...026-04-04-trust-boundary-regexp-barrier.md | 4 -- .../2026-04-18-partial-path-traversal-fix.md | 4 -- ...026-04-23-hibernate-queryproducer-sinks.md | 4 -- java/ql/lib/change-notes/released/9.1.0.md | 14 +++++++ 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.2.md | 3 ++ java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 7 ++++ .../2026-03-20-data-extensions-barriers.md | 4 -- .../2.7.0.md} | 8 ++-- 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.9.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.49.md | 3 ++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 10 +++++ .../2026-03-20-data-extensions-barriers.md | 4 -- ...6-04-10-support-comprehension-unpacking.md | 5 --- python/ql/lib/change-notes/released/7.1.0.md | 9 +++++ 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.2.md | 3 ++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 6 +++ .../5.2.0.md} | 7 ++-- 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.2.md | 3 ++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- rust/ql/lib/CHANGELOG.md | 6 +++ .../0.2.13.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.34.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.23.md | 3 ++ shared/concepts/codeql-pack.release.yml | 2 +- shared/concepts/qlpack.yml | 2 +- shared/controlflow/CHANGELOG.md | 4 ++ .../change-notes/released/2.0.33.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.5.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.49.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.27.md | 3 ++ shared/quantum/codeql-pack.release.yml | 2 +- shared/quantum/qlpack.yml | 2 +- shared/rangeanalysis/CHANGELOG.md | 4 ++ .../change-notes/released/1.0.49.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.49.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.25.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.49.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.49.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.49.md | 3 ++ shared/typeflow/codeql-pack.release.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typeinference/CHANGELOG.md | 4 ++ .../change-notes/released/0.0.30.md | 3 ++ shared/typeinference/codeql-pack.release.yml | 2 +- shared/typeinference/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ++ .../change-notes/released/2.0.33.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.49.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.36.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.49.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.49.md | 3 ++ shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/CHANGELOG.md | 10 +++++ .../change-notes/2026-04-20-swift-6.3.1.md | 4 -- .../6.5.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.2.md | 3 ++ swift/ql/src/codeql-pack.release.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 184 files changed, 514 insertions(+), 196 deletions(-) create mode 100644 actions/ql/lib/change-notes/released/0.4.35.md create mode 100644 actions/ql/src/change-notes/released/0.6.27.md delete mode 100644 cpp/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md delete mode 100644 cpp/ql/lib/change-notes/2026-03-28-switch-stmt.md delete mode 100644 cpp/ql/lib/change-notes/2026-04-28-strsafe.md create mode 100644 cpp/ql/lib/change-notes/released/10.1.0.md create mode 100644 cpp/ql/src/change-notes/released/1.6.2.md create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.66.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.66.md delete mode 100644 csharp/ql/lib/change-notes/2026-03-06-compound-assignment-operations.md delete mode 100644 csharp/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md delete mode 100644 csharp/ql/lib/change-notes/2026-04-01-asp-remote-sources.md delete mode 100644 csharp/ql/lib/change-notes/2026-04-10-nuget-feed-usage-in-bmn.md delete mode 100644 csharp/ql/lib/change-notes/2026-04-13-cfg.md delete mode 100644 csharp/ql/lib/change-notes/2026-05-01-ssa-replacement.md create mode 100644 csharp/ql/lib/change-notes/released/6.0.0.md create mode 100644 csharp/ql/src/change-notes/released/1.7.2.md create mode 100644 go/ql/consistency-queries/change-notes/released/1.0.49.md rename go/ql/lib/change-notes/{2026-03-20-data-extensions-barriers.md => released/7.1.0.md} (89%) create mode 100644 go/ql/src/change-notes/released/1.6.2.md delete mode 100644 java/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md delete mode 100644 java/ql/lib/change-notes/2026-04-04-path-injection-torealpath.md delete mode 100644 java/ql/lib/change-notes/2026-04-04-sensitive-log-fp-reduction.md delete mode 100644 java/ql/lib/change-notes/2026-04-04-sensitive-log-hash-sanitizer.md delete mode 100644 java/ql/lib/change-notes/2026-04-04-trust-boundary-regexp-barrier.md delete mode 100644 java/ql/lib/change-notes/2026-04-18-partial-path-traversal-fix.md delete mode 100644 java/ql/lib/change-notes/2026-04-23-hibernate-queryproducer-sinks.md create mode 100644 java/ql/lib/change-notes/released/9.1.0.md create mode 100644 java/ql/src/change-notes/released/1.11.2.md delete mode 100644 javascript/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md rename javascript/ql/lib/change-notes/{2026-04-12-vercel-node.md => released/2.7.0.md} (58%) create mode 100644 javascript/ql/src/change-notes/released/2.3.9.md create mode 100644 misc/suite-helpers/change-notes/released/1.0.49.md delete mode 100644 python/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md delete mode 100644 python/ql/lib/change-notes/2026-04-10-support-comprehension-unpacking.md create mode 100644 python/ql/lib/change-notes/released/7.1.0.md create mode 100644 python/ql/src/change-notes/released/1.8.2.md rename ruby/ql/lib/change-notes/{2026-03-20-data-extensions-barriers.md => released/5.2.0.md} (89%) create mode 100644 ruby/ql/src/change-notes/released/1.6.2.md rename rust/ql/lib/change-notes/{2026-03-20-data-extensions-barriers.md => released/0.2.13.md} (73%) create mode 100644 rust/ql/src/change-notes/released/0.1.34.md create mode 100644 shared/concepts/change-notes/released/0.0.23.md create mode 100644 shared/controlflow/change-notes/released/2.0.33.md create mode 100644 shared/dataflow/change-notes/released/2.1.5.md create mode 100644 shared/mad/change-notes/released/1.0.49.md create mode 100644 shared/quantum/change-notes/released/0.0.27.md create mode 100644 shared/rangeanalysis/change-notes/released/1.0.49.md create mode 100644 shared/regex/change-notes/released/1.0.49.md create mode 100644 shared/ssa/change-notes/released/2.0.25.md create mode 100644 shared/threat-models/change-notes/released/1.0.49.md create mode 100644 shared/tutorial/change-notes/released/1.0.49.md create mode 100644 shared/typeflow/change-notes/released/1.0.49.md create mode 100644 shared/typeinference/change-notes/released/0.0.30.md create mode 100644 shared/typetracking/change-notes/released/2.0.33.md create mode 100644 shared/typos/change-notes/released/1.0.49.md create mode 100644 shared/util/change-notes/released/2.0.36.md create mode 100644 shared/xml/change-notes/released/1.0.49.md create mode 100644 shared/yaml/change-notes/released/1.0.49.md delete mode 100644 swift/ql/lib/change-notes/2026-04-20-swift-6.3.1.md rename swift/ql/lib/change-notes/{2026-04-17-fixed-array.md => released/6.5.0.md} (63%) create mode 100644 swift/ql/src/change-notes/released/1.3.2.md diff --git a/actions/ql/lib/CHANGELOG.md b/actions/ql/lib/CHANGELOG.md index e84ba38d180..011af903a2a 100644 --- a/actions/ql/lib/CHANGELOG.md +++ b/actions/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.35 + +No user-facing changes. + ## 0.4.34 ### Minor Analysis Improvements diff --git a/actions/ql/lib/change-notes/released/0.4.35.md b/actions/ql/lib/change-notes/released/0.4.35.md new file mode 100644 index 00000000000..3274ffc88e4 --- /dev/null +++ b/actions/ql/lib/change-notes/released/0.4.35.md @@ -0,0 +1,3 @@ +## 0.4.35 + +No user-facing changes. diff --git a/actions/ql/lib/codeql-pack.release.yml b/actions/ql/lib/codeql-pack.release.yml index 69fb16e4c39..524302c92d3 100644 --- a/actions/ql/lib/codeql-pack.release.yml +++ b/actions/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.34 +lastReleaseVersion: 0.4.35 diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml index 6e78fc546b3..a20f2e7a507 100644 --- a/actions/ql/lib/qlpack.yml +++ b/actions/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-all -version: 0.4.35-dev +version: 0.4.35 library: true warnOnImplicitThis: true dependencies: diff --git a/actions/ql/src/CHANGELOG.md b/actions/ql/src/CHANGELOG.md index 96f8d266206..0a7fa1ce830 100644 --- a/actions/ql/src/CHANGELOG.md +++ b/actions/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.27 + +No user-facing changes. + ## 0.6.26 ### Major Analysis Improvements @@ -173,7 +177,7 @@ No user-facing changes. * `actions/if-expression-always-true/critical` * `actions/if-expression-always-true/high` * `actions/unnecessary-use-of-advanced-config` - + * The following query has been moved from the `code-scanning` suite to the `security-extended` suite. Any existing alerts for this query will be closed automatically unless the analysis is configured to use the `security-extended` suite. diff --git a/actions/ql/src/change-notes/released/0.6.27.md b/actions/ql/src/change-notes/released/0.6.27.md new file mode 100644 index 00000000000..52d3a10fd1f --- /dev/null +++ b/actions/ql/src/change-notes/released/0.6.27.md @@ -0,0 +1,3 @@ +## 0.6.27 + +No user-facing changes. diff --git a/actions/ql/src/codeql-pack.release.yml b/actions/ql/src/codeql-pack.release.yml index e83bac0046e..0748b12112f 100644 --- a/actions/ql/src/codeql-pack.release.yml +++ b/actions/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.26 +lastReleaseVersion: 0.6.27 diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml index c815afc498c..bcc7fe06a3b 100644 --- a/actions/ql/src/qlpack.yml +++ b/actions/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-queries -version: 0.6.27-dev +version: 0.6.27 library: false warnOnImplicitThis: true groups: [actions, queries] diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 2cd1bcede35..828b8779117 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,14 @@ +## 10.1.0 + +### New Features + +* A new predicate `getSwitchCase` was added to the `SwitchStmt` class, which yields the `n`th `case` statement from a `switch` statement. +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C and C++](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-cpp/). + +### Minor Analysis Improvements + +* Added taint flow models for the `Strsafe.h` header from the Windows SDK. + ## 10.0.0 ### Breaking Changes diff --git a/cpp/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md b/cpp/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md deleted file mode 100644 index 30f0092a4e9..00000000000 --- a/cpp/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C and C++](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-cpp/). diff --git a/cpp/ql/lib/change-notes/2026-03-28-switch-stmt.md b/cpp/ql/lib/change-notes/2026-03-28-switch-stmt.md deleted file mode 100644 index 4b0d7528d47..00000000000 --- a/cpp/ql/lib/change-notes/2026-03-28-switch-stmt.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* A new predicate `getSwitchCase` was added to the `SwitchStmt` class, which yields the `n`th `case` statement from a `switch` statement. diff --git a/cpp/ql/lib/change-notes/2026-04-28-strsafe.md b/cpp/ql/lib/change-notes/2026-04-28-strsafe.md deleted file mode 100644 index 9ef3fab0853..00000000000 --- a/cpp/ql/lib/change-notes/2026-04-28-strsafe.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added taint flow models for the `Strsafe.h` header from the Windows SDK. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/released/10.1.0.md b/cpp/ql/lib/change-notes/released/10.1.0.md new file mode 100644 index 00000000000..45d153b4896 --- /dev/null +++ b/cpp/ql/lib/change-notes/released/10.1.0.md @@ -0,0 +1,10 @@ +## 10.1.0 + +### New Features + +* A new predicate `getSwitchCase` was added to the `SwitchStmt` class, which yields the `n`th `case` statement from a `switch` statement. +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C and C++](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-cpp/). + +### Minor Analysis Improvements + +* Added taint flow models for the `Strsafe.h` header from the Windows SDK. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 28758256b94..a85b2d36d7c 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 10.0.0 +lastReleaseVersion: 10.1.0 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 8a9d60a7fa9..e3b9f7c3363 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 10.0.1-dev +version: 10.1.0 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index e677f584416..3a9d4fae927 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.2 + +No user-facing changes. + ## 1.6.1 ### Minor Analysis Improvements @@ -366,7 +370,7 @@ No user-facing changes. ### Minor Analysis Improvements * The "non-constant format string" query (`cpp/non-constant-format`) has been updated to produce fewer false positives. -* Added dataflow models for the `gettext` function variants. +* Added dataflow models for the `gettext` function variants. ## 0.9.4 diff --git a/cpp/ql/src/change-notes/released/1.6.2.md b/cpp/ql/src/change-notes/released/1.6.2.md new file mode 100644 index 00000000000..bbe3747556f --- /dev/null +++ b/cpp/ql/src/change-notes/released/1.6.2.md @@ -0,0 +1,3 @@ +## 1.6.2 + +No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index ef7a789e0cf..5f5beb68311 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.1 +lastReleaseVersion: 1.6.2 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 714167434c8..83d7a32e6d4 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.6.2-dev +version: 1.6.2 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 166a94bd88d..4cb7b556968 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.66 + +No user-facing changes. + ## 1.7.65 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.66.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.66.md new file mode 100644 index 00000000000..7fc1a46a66e --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.66.md @@ -0,0 +1,3 @@ +## 1.7.66 + +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 bf581427d29..7d0a2c0bc07 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.65 +lastReleaseVersion: 1.7.66 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 9d0e0ffd4f9..88ba74212c7 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.66-dev +version: 1.7.66 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 166a94bd88d..4cb7b556968 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.66 + +No user-facing changes. + ## 1.7.65 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.66.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.66.md new file mode 100644 index 00000000000..7fc1a46a66e --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.66.md @@ -0,0 +1,3 @@ +## 1.7.66 + +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 bf581427d29..7d0a2c0bc07 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.65 +lastReleaseVersion: 1.7.66 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index f5203f4e443..fee050486c9 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.66-dev +version: 1.7.66 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 2e3f6c137ee..1d7f42a9075 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,42 @@ +## 6.0.0 + +### Breaking Changes + +* The C# control flow graph (CFG) implementation has been completely + rewritten. The CFG now includes additional nodes to more accurately represent + certain constructs. This also means that any existing code that implicitly + relies on very specific details about the CFG may need to be updated. + The CFG no longer uses splitting, which means that AST nodes now have a unique + CFG node representation. + Additionally, the following breaking changes have been made: + - `ControlFlow::Node` has been renamed to `ControlFlowNode`. + - `ControlFlow::Nodes` has been renamed to `ControlFlowNodes`. + - `BasicBlock.getCallable` has been renamed to `BasicBlock.getEnclosingCallable`. + - `BasicBlocks.qll` has been deleted. + - `ControlFlowNode.getAstNode` has changed its meaning. The AST-to-CFG + mapping remains one-to-many, but now for a different reason. It used to be + because of splitting, but now it's because of additional "helper" CFG + nodes. To get the (now canonical) CFG node for a given AST node, use + `ControlFlowNode.asExpr()` or `ControlFlowNode.asStmt()` or + `ControlFlowElement.getControlFlowNode()` instead. + +### Deprecated APIs + +* The QL classes in the C# SSA library have been renamed to improve consistency between languages. Any custom QL code that makes use of SSA needs to be updated. The old classes have been deprecated and include more detailed migration instructions in their qldoc. + +### New Features + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C#](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-csharp/). + +### Major Analysis Improvements + +* When resolving dependencies in `build-mode: none`, `dotnet restore` now explicitly receives reachable NuGet feeds configured in `nuget.config` when feed responsiveness checking is enabled (the default), and any private registries directly, improving reliability when default feeds are unavailable or restricted. + +### Minor Analysis Improvements + +* Expanded ASP and ASP.NET remote source modeling to cover additional sources, including fields of tainted parameters as well as properties and fields that become tainted transitively. +* C# 14: Added support for user-defined compound assignment operators. + ## 5.5.0 ### Deprecated APIs diff --git a/csharp/ql/lib/change-notes/2026-03-06-compound-assignment-operations.md b/csharp/ql/lib/change-notes/2026-03-06-compound-assignment-operations.md deleted file mode 100644 index f7e68b9b7d7..00000000000 --- a/csharp/ql/lib/change-notes/2026-03-06-compound-assignment-operations.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* C# 14: Added support for user-defined compound assignment operators. diff --git a/csharp/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md b/csharp/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md deleted file mode 100644 index 6408acc7dae..00000000000 --- a/csharp/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C#](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-csharp/). diff --git a/csharp/ql/lib/change-notes/2026-04-01-asp-remote-sources.md b/csharp/ql/lib/change-notes/2026-04-01-asp-remote-sources.md deleted file mode 100644 index 52f3f721e9f..00000000000 --- a/csharp/ql/lib/change-notes/2026-04-01-asp-remote-sources.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Expanded ASP and ASP.NET remote source modeling to cover additional sources, including fields of tainted parameters as well as properties and fields that become tainted transitively. diff --git a/csharp/ql/lib/change-notes/2026-04-10-nuget-feed-usage-in-bmn.md b/csharp/ql/lib/change-notes/2026-04-10-nuget-feed-usage-in-bmn.md deleted file mode 100644 index a4282d0468d..00000000000 --- a/csharp/ql/lib/change-notes/2026-04-10-nuget-feed-usage-in-bmn.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* When resolving dependencies in `build-mode: none`, `dotnet restore` now explicitly receives reachable NuGet feeds configured in `nuget.config` when feed responsiveness checking is enabled (the default), and any private registries directly, improving reliability when default feeds are unavailable or restricted. diff --git a/csharp/ql/lib/change-notes/2026-04-13-cfg.md b/csharp/ql/lib/change-notes/2026-04-13-cfg.md deleted file mode 100644 index 9c588fbcfa8..00000000000 --- a/csharp/ql/lib/change-notes/2026-04-13-cfg.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -category: breaking ---- -* The C# control flow graph (CFG) implementation has been completely - rewritten. The CFG now includes additional nodes to more accurately represent - certain constructs. This also means that any existing code that implicitly - relies on very specific details about the CFG may need to be updated. - The CFG no longer uses splitting, which means that AST nodes now have a unique - CFG node representation. - Additionally, the following breaking changes have been made: - - `ControlFlow::Node` has been renamed to `ControlFlowNode`. - - `ControlFlow::Nodes` has been renamed to `ControlFlowNodes`. - - `BasicBlock.getCallable` has been renamed to `BasicBlock.getEnclosingCallable`. - - `BasicBlocks.qll` has been deleted. - - `ControlFlowNode.getAstNode` has changed its meaning. The AST-to-CFG - mapping remains one-to-many, but now for a different reason. It used to be - because of splitting, but now it's because of additional "helper" CFG - nodes. To get the (now canonical) CFG node for a given AST node, use - `ControlFlowNode.asExpr()` or `ControlFlowNode.asStmt()` or - `ControlFlowElement.getControlFlowNode()` instead. diff --git a/csharp/ql/lib/change-notes/2026-05-01-ssa-replacement.md b/csharp/ql/lib/change-notes/2026-05-01-ssa-replacement.md deleted file mode 100644 index 27988f36f2f..00000000000 --- a/csharp/ql/lib/change-notes/2026-05-01-ssa-replacement.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: deprecated ---- -* The QL classes in the C# SSA library have been renamed to improve consistency between languages. Any custom QL code that makes use of SSA needs to be updated. The old classes have been deprecated and include more detailed migration instructions in their qldoc. diff --git a/csharp/ql/lib/change-notes/released/6.0.0.md b/csharp/ql/lib/change-notes/released/6.0.0.md new file mode 100644 index 00000000000..e249567d095 --- /dev/null +++ b/csharp/ql/lib/change-notes/released/6.0.0.md @@ -0,0 +1,38 @@ +## 6.0.0 + +### Breaking Changes + +* The C# control flow graph (CFG) implementation has been completely + rewritten. The CFG now includes additional nodes to more accurately represent + certain constructs. This also means that any existing code that implicitly + relies on very specific details about the CFG may need to be updated. + The CFG no longer uses splitting, which means that AST nodes now have a unique + CFG node representation. + Additionally, the following breaking changes have been made: + - `ControlFlow::Node` has been renamed to `ControlFlowNode`. + - `ControlFlow::Nodes` has been renamed to `ControlFlowNodes`. + - `BasicBlock.getCallable` has been renamed to `BasicBlock.getEnclosingCallable`. + - `BasicBlocks.qll` has been deleted. + - `ControlFlowNode.getAstNode` has changed its meaning. The AST-to-CFG + mapping remains one-to-many, but now for a different reason. It used to be + because of splitting, but now it's because of additional "helper" CFG + nodes. To get the (now canonical) CFG node for a given AST node, use + `ControlFlowNode.asExpr()` or `ControlFlowNode.asStmt()` or + `ControlFlowElement.getControlFlowNode()` instead. + +### Deprecated APIs + +* The QL classes in the C# SSA library have been renamed to improve consistency between languages. Any custom QL code that makes use of SSA needs to be updated. The old classes have been deprecated and include more detailed migration instructions in their qldoc. + +### New Features + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C#](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-csharp/). + +### Major Analysis Improvements + +* When resolving dependencies in `build-mode: none`, `dotnet restore` now explicitly receives reachable NuGet feeds configured in `nuget.config` when feed responsiveness checking is enabled (the default), and any private registries directly, improving reliability when default feeds are unavailable or restricted. + +### Minor Analysis Improvements + +* Expanded ASP and ASP.NET remote source modeling to cover additional sources, including fields of tainted parameters as well as properties and fields that become tainted transitively. +* C# 14: Added support for user-defined compound assignment operators. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 4b8cf9533c1..f8c4fa43ccb 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.5.0 +lastReleaseVersion: 6.0.0 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 26e332652cd..daded1ee71e 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 5.5.1-dev +version: 6.0.0 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index cdab7134185..32243acfb97 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.2 + +No user-facing changes. + ## 1.7.1 ### Minor Analysis Improvements diff --git a/csharp/ql/src/change-notes/released/1.7.2.md b/csharp/ql/src/change-notes/released/1.7.2.md new file mode 100644 index 00000000000..b950385c16d --- /dev/null +++ b/csharp/ql/src/change-notes/released/1.7.2.md @@ -0,0 +1,3 @@ +## 1.7.2 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 7bdec0d85c7..39bbba86c19 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.1 +lastReleaseVersion: 1.7.2 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 25b04cf2dc6..72d951194c3 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.7.2-dev +version: 1.7.2 groups: - csharp - queries diff --git a/go/ql/consistency-queries/CHANGELOG.md b/go/ql/consistency-queries/CHANGELOG.md index a3aa00d4872..a6b6055373a 100644 --- a/go/ql/consistency-queries/CHANGELOG.md +++ b/go/ql/consistency-queries/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/go/ql/consistency-queries/change-notes/released/1.0.49.md b/go/ql/consistency-queries/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/go/ql/consistency-queries/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +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 6db79f2c397..596617977df 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.48 +lastReleaseVersion: 1.0.49 diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index a82ec95583b..73a837bd0e0 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.49-dev +version: 1.0.49 groups: - go - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 737d08654b8..5043d924be0 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 7.1.0 + +### New Features + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Go](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-go/). + ## 7.0.6 No user-facing changes. diff --git a/go/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md b/go/ql/lib/change-notes/released/7.1.0.md similarity index 89% rename from go/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md rename to go/ql/lib/change-notes/released/7.1.0.md index ee1b51de861..b1f6efbf001 100644 --- a/go/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md +++ b/go/ql/lib/change-notes/released/7.1.0.md @@ -1,4 +1,5 @@ ---- -category: feature ---- +## 7.1.0 + +### New Features + * Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Go](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-go/). diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index c7cff8c5378..dcaaa76112a 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.0.6 +lastReleaseVersion: 7.1.0 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index e191e0da688..1d1682d6108 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 7.0.7-dev +version: 7.1.0 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 971d478d56e..ddda5dc4829 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.2 + +No user-facing changes. + ## 1.6.1 No user-facing changes. diff --git a/go/ql/src/change-notes/released/1.6.2.md b/go/ql/src/change-notes/released/1.6.2.md new file mode 100644 index 00000000000..bbe3747556f --- /dev/null +++ b/go/ql/src/change-notes/released/1.6.2.md @@ -0,0 +1,3 @@ +## 1.6.2 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index ef7a789e0cf..5f5beb68311 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.1 +lastReleaseVersion: 1.6.2 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index fa7e934382a..78c75459387 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.6.2-dev +version: 1.6.2 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 2d34c791c92..2187f00c399 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,18 @@ +## 9.1.0 + +### New Features + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Java and Kotlin](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/). + +### Minor Analysis Improvements + +* Added `sql-injection` sink models for the Hibernate `org.hibernate.query.QueryProducer` methods `createNativeMutationQuery`, `createMutationQuery`, and `createSelectionQuery`. +* The `java/partial-path-traversal` and `java/partial-path-traversal-from-remote` queries now correctly recognize file separator appends using `+=`. +* The `java/path-injection` and `java/zipslip` queries now recognize `Path.toRealPath()` as a path normalization sanitizer, consistent with the existing treatment of `Path.normalize()` and `File.getCanonicalPath()`. This reduces false positives for code that uses the NIO.2 API for path canonicalization. +* The `java/sensitive-log` query now excludes additional common variable naming patterns that do not hold sensitive data, reducing false positives. This includes pagination/iteration tokens (`nextToken`, `pageToken`, `continuationToken`), token metadata (`tokenType`, `tokenEndpoint`, `tokenCount`), and secret metadata (`secretName`, `secretId`, `secretVersion`). +* The `java/sensitive-log` query now treats method calls whose names contain "encrypt", "hash", or "digest" as sanitizers, consistent with the existing treatment in `java/cleartext-storage-in-log`. This reduces false positives when sensitive data is hashed or encrypted before logging. +* The `java/trust-boundary-violation` query now recognizes regular expression checks (including `String.matches()` guards and `@javax.validation.constraints.Pattern` annotations) as sanitizers, consistent with the existing treatment of ESAPI validators. This reduces false positives when input is validated against a pattern before being stored in a session. + ## 9.0.4 ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md b/java/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md deleted file mode 100644 index f8bcbb1fcb2..00000000000 --- a/java/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Java and Kotlin](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/). diff --git a/java/ql/lib/change-notes/2026-04-04-path-injection-torealpath.md b/java/ql/lib/change-notes/2026-04-04-path-injection-torealpath.md deleted file mode 100644 index 8856d419bce..00000000000 --- a/java/ql/lib/change-notes/2026-04-04-path-injection-torealpath.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `java/path-injection` and `java/zipslip` queries now recognize `Path.toRealPath()` as a path normalization sanitizer, consistent with the existing treatment of `Path.normalize()` and `File.getCanonicalPath()`. This reduces false positives for code that uses the NIO.2 API for path canonicalization. diff --git a/java/ql/lib/change-notes/2026-04-04-sensitive-log-fp-reduction.md b/java/ql/lib/change-notes/2026-04-04-sensitive-log-fp-reduction.md deleted file mode 100644 index 15fc811360b..00000000000 --- a/java/ql/lib/change-notes/2026-04-04-sensitive-log-fp-reduction.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `java/sensitive-log` query now excludes additional common variable naming patterns that do not hold sensitive data, reducing false positives. This includes pagination/iteration tokens (`nextToken`, `pageToken`, `continuationToken`), token metadata (`tokenType`, `tokenEndpoint`, `tokenCount`), and secret metadata (`secretName`, `secretId`, `secretVersion`). diff --git a/java/ql/lib/change-notes/2026-04-04-sensitive-log-hash-sanitizer.md b/java/ql/lib/change-notes/2026-04-04-sensitive-log-hash-sanitizer.md deleted file mode 100644 index 7323ab09737..00000000000 --- a/java/ql/lib/change-notes/2026-04-04-sensitive-log-hash-sanitizer.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `java/sensitive-log` query now treats method calls whose names contain "encrypt", "hash", or "digest" as sanitizers, consistent with the existing treatment in `java/cleartext-storage-in-log`. This reduces false positives when sensitive data is hashed or encrypted before logging. diff --git a/java/ql/lib/change-notes/2026-04-04-trust-boundary-regexp-barrier.md b/java/ql/lib/change-notes/2026-04-04-trust-boundary-regexp-barrier.md deleted file mode 100644 index b80c0611b6d..00000000000 --- a/java/ql/lib/change-notes/2026-04-04-trust-boundary-regexp-barrier.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `java/trust-boundary-violation` query now recognizes regular expression checks (including `String.matches()` guards and `@javax.validation.constraints.Pattern` annotations) as sanitizers, consistent with the existing treatment of ESAPI validators. This reduces false positives when input is validated against a pattern before being stored in a session. diff --git a/java/ql/lib/change-notes/2026-04-18-partial-path-traversal-fix.md b/java/ql/lib/change-notes/2026-04-18-partial-path-traversal-fix.md deleted file mode 100644 index 8c15a346552..00000000000 --- a/java/ql/lib/change-notes/2026-04-18-partial-path-traversal-fix.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `java/partial-path-traversal` and `java/partial-path-traversal-from-remote` queries now correctly recognize file separator appends using `+=`. diff --git a/java/ql/lib/change-notes/2026-04-23-hibernate-queryproducer-sinks.md b/java/ql/lib/change-notes/2026-04-23-hibernate-queryproducer-sinks.md deleted file mode 100644 index 018ce8d348e..00000000000 --- a/java/ql/lib/change-notes/2026-04-23-hibernate-queryproducer-sinks.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added `sql-injection` sink models for the Hibernate `org.hibernate.query.QueryProducer` methods `createNativeMutationQuery`, `createMutationQuery`, and `createSelectionQuery`. diff --git a/java/ql/lib/change-notes/released/9.1.0.md b/java/ql/lib/change-notes/released/9.1.0.md new file mode 100644 index 00000000000..aed1a85e63f --- /dev/null +++ b/java/ql/lib/change-notes/released/9.1.0.md @@ -0,0 +1,14 @@ +## 9.1.0 + +### New Features + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Java and Kotlin](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/). + +### Minor Analysis Improvements + +* Added `sql-injection` sink models for the Hibernate `org.hibernate.query.QueryProducer` methods `createNativeMutationQuery`, `createMutationQuery`, and `createSelectionQuery`. +* The `java/partial-path-traversal` and `java/partial-path-traversal-from-remote` queries now correctly recognize file separator appends using `+=`. +* The `java/path-injection` and `java/zipslip` queries now recognize `Path.toRealPath()` as a path normalization sanitizer, consistent with the existing treatment of `Path.normalize()` and `File.getCanonicalPath()`. This reduces false positives for code that uses the NIO.2 API for path canonicalization. +* The `java/sensitive-log` query now excludes additional common variable naming patterns that do not hold sensitive data, reducing false positives. This includes pagination/iteration tokens (`nextToken`, `pageToken`, `continuationToken`), token metadata (`tokenType`, `tokenEndpoint`, `tokenCount`), and secret metadata (`secretName`, `secretId`, `secretVersion`). +* The `java/sensitive-log` query now treats method calls whose names contain "encrypt", "hash", or "digest" as sanitizers, consistent with the existing treatment in `java/cleartext-storage-in-log`. This reduces false positives when sensitive data is hashed or encrypted before logging. +* The `java/trust-boundary-violation` query now recognizes regular expression checks (including `String.matches()` guards and `@javax.validation.constraints.Pattern` annotations) as sanitizers, consistent with the existing treatment of ESAPI validators. This reduces false positives when input is validated against a pattern before being stored in a session. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 4bbe4f75b58..83ec2b42fcd 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 9.0.4 +lastReleaseVersion: 9.1.0 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index d256d2a84c1..e57412ee1fc 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 9.0.5-dev +version: 9.1.0 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 1b5d2bdad8a..fd13cbdcf83 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.11.2 + +No user-facing changes. + ## 1.11.1 No user-facing changes. diff --git a/java/ql/src/change-notes/released/1.11.2.md b/java/ql/src/change-notes/released/1.11.2.md new file mode 100644 index 00000000000..93a8b73f6b9 --- /dev/null +++ b/java/ql/src/change-notes/released/1.11.2.md @@ -0,0 +1,3 @@ +## 1.11.2 + +No user-facing changes. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 4ae123153bf..3e341cf85d5 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.11.1 +lastReleaseVersion: 1.11.2 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 2f2233460ba..bdaaf77ec9e 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.11.2-dev +version: 1.11.2 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 77837f46c5e..53708faed09 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 2.7.0 + +### New Features + +* Added support for [`@vercel/node`](https://www.npmjs.com/package/@vercel/node) Vercel serverless functions. Handlers are recognized via the `VercelRequest`/`VercelResponse` TypeScript parameter types, and standard security queries (`js/reflected-xss`, `js/request-forgery`, `js/sql-injection`, `js/command-line-injection`, etc.) now detect vulnerabilities in Vercel API route files. +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for JavaScript](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-javascript/). + ## 2.6.28 No user-facing changes. diff --git a/javascript/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md b/javascript/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md deleted file mode 100644 index d849f4c0c69..00000000000 --- a/javascript/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for JavaScript](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-javascript/). diff --git a/javascript/ql/lib/change-notes/2026-04-12-vercel-node.md b/javascript/ql/lib/change-notes/released/2.7.0.md similarity index 58% rename from javascript/ql/lib/change-notes/2026-04-12-vercel-node.md rename to javascript/ql/lib/change-notes/released/2.7.0.md index 39802258b02..c6f46c8c0d4 100644 --- a/javascript/ql/lib/change-notes/2026-04-12-vercel-node.md +++ b/javascript/ql/lib/change-notes/released/2.7.0.md @@ -1,4 +1,6 @@ ---- -category: feature ---- +## 2.7.0 + +### New Features + * Added support for [`@vercel/node`](https://www.npmjs.com/package/@vercel/node) Vercel serverless functions. Handlers are recognized via the `VercelRequest`/`VercelResponse` TypeScript parameter types, and standard security queries (`js/reflected-xss`, `js/request-forgery`, `js/sql-injection`, `js/command-line-injection`, etc.) now detect vulnerabilities in Vercel API route files. +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for JavaScript](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-javascript/). diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 2456457874e..6a6c87f537d 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.6.28 +lastReleaseVersion: 2.7.0 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index b62abbbe101..97c3de6a8eb 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.6.29-dev +version: 2.7.0 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 9b122364ffa..615c030de52 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.3.9 + +No user-facing changes. + ## 2.3.8 ### Minor Analysis Improvements diff --git a/javascript/ql/src/change-notes/released/2.3.9.md b/javascript/ql/src/change-notes/released/2.3.9.md new file mode 100644 index 00000000000..fac422eb6b8 --- /dev/null +++ b/javascript/ql/src/change-notes/released/2.3.9.md @@ -0,0 +1,3 @@ +## 2.3.9 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index c68b70cb8be..079eb5bfb0c 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.3.8 +lastReleaseVersion: 2.3.9 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 9081791d0e0..417df72e5ba 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 2.3.9-dev +version: 2.3.9 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 897533f6450..d6d070a91bb 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/1.0.49.md b/misc/suite-helpers/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/misc/suite-helpers/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 778284fbe9a..52fc453aa32 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.49-dev +version: 1.0.49 groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 69fa60a6675..8ede35e9bdc 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 7.1.0 + +### New Features + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Python](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-python/). + +### Minor Analysis Improvements + +- The Python extractor now supports unpacking in comprehensions, e.g. `[*x for x in nested]` (as defined in [PEP-798](https://peps.python.org/pep-0798/)) that will be part of Python 3.15. + ## 7.0.5 ### Minor Analysis Improvements diff --git a/python/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md b/python/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md deleted file mode 100644 index 522801a0e46..00000000000 --- a/python/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Python](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-python/). diff --git a/python/ql/lib/change-notes/2026-04-10-support-comprehension-unpacking.md b/python/ql/lib/change-notes/2026-04-10-support-comprehension-unpacking.md deleted file mode 100644 index d7406d0a606..00000000000 --- a/python/ql/lib/change-notes/2026-04-10-support-comprehension-unpacking.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- - -- The Python extractor now supports unpacking in comprehensions, e.g. `[*x for x in nested]` (as defined in [PEP-798](https://peps.python.org/pep-0798/)) that will be part of Python 3.15. diff --git a/python/ql/lib/change-notes/released/7.1.0.md b/python/ql/lib/change-notes/released/7.1.0.md new file mode 100644 index 00000000000..553b5fe4cee --- /dev/null +++ b/python/ql/lib/change-notes/released/7.1.0.md @@ -0,0 +1,9 @@ +## 7.1.0 + +### New Features + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Python](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-python/). + +### Minor Analysis Improvements + +- The Python extractor now supports unpacking in comprehensions, e.g. `[*x for x in nested]` (as defined in [PEP-798](https://peps.python.org/pep-0798/)) that will be part of Python 3.15. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 2cff21d59fe..dcaaa76112a 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.0.5 +lastReleaseVersion: 7.1.0 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 8564a098594..2cd96a3e443 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 7.0.6-dev +version: 7.1.0 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 38018f09856..8676d754d01 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.8.2 + +No user-facing changes. + ## 1.8.1 ### Minor Analysis Improvements diff --git a/python/ql/src/change-notes/released/1.8.2.md b/python/ql/src/change-notes/released/1.8.2.md new file mode 100644 index 00000000000..12e641fd720 --- /dev/null +++ b/python/ql/src/change-notes/released/1.8.2.md @@ -0,0 +1,3 @@ +## 1.8.2 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 28a7c123ae8..559af8348bb 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.8.1 +lastReleaseVersion: 1.8.2 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 2d99bcd0c7a..46e7203a953 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.8.2-dev +version: 1.8.2 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 8315b641369..e8dd84283c6 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 5.2.0 + +### New Features + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Ruby](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-ruby/). + ## 5.1.16 No user-facing changes. diff --git a/ruby/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md b/ruby/ql/lib/change-notes/released/5.2.0.md similarity index 89% rename from ruby/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md rename to ruby/ql/lib/change-notes/released/5.2.0.md index da53d584e11..c17c834f18d 100644 --- a/ruby/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md +++ b/ruby/ql/lib/change-notes/released/5.2.0.md @@ -1,4 +1,5 @@ ---- -category: feature ---- +## 5.2.0 + +### New Features + * Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for Ruby](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-ruby/). diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 735f742e9af..9e57a36a7dc 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.1.16 +lastReleaseVersion: 5.2.0 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 1ac5090098a..261a9890d44 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 5.1.17-dev +version: 5.2.0 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 5266fc1d5d9..927a40e596d 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.2 + +No user-facing changes. + ## 1.6.1 No user-facing changes. diff --git a/ruby/ql/src/change-notes/released/1.6.2.md b/ruby/ql/src/change-notes/released/1.6.2.md new file mode 100644 index 00000000000..bbe3747556f --- /dev/null +++ b/ruby/ql/src/change-notes/released/1.6.2.md @@ -0,0 +1,3 @@ +## 1.6.2 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index ef7a789e0cf..5f5beb68311 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.1 +lastReleaseVersion: 1.6.2 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 978102bb82a..34f5d14c39c 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.6.2-dev +version: 1.6.2 groups: - ruby - queries diff --git a/rust/ql/lib/CHANGELOG.md b/rust/ql/lib/CHANGELOG.md index 8e515660f29..30ae7d73b67 100644 --- a/rust/ql/lib/CHANGELOG.md +++ b/rust/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.13 + +### New Features + +* Data flow barriers and barrier guards can now be added using data extensions. + ## 0.2.12 No user-facing changes. diff --git a/rust/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md b/rust/ql/lib/change-notes/released/0.2.13.md similarity index 73% rename from rust/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md rename to rust/ql/lib/change-notes/released/0.2.13.md index 5e97a1533a9..9c390c9ca09 100644 --- a/rust/ql/lib/change-notes/2026-03-20-data-extensions-barriers.md +++ b/rust/ql/lib/change-notes/released/0.2.13.md @@ -1,4 +1,5 @@ ---- -category: feature ---- +## 0.2.13 + +### New Features + * Data flow barriers and barrier guards can now be added using data extensions. diff --git a/rust/ql/lib/codeql-pack.release.yml b/rust/ql/lib/codeql-pack.release.yml index da1cea93393..979eb20092e 100644 --- a/rust/ql/lib/codeql-pack.release.yml +++ b/rust/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.12 +lastReleaseVersion: 0.2.13 diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 7eb159e4b50..96b825fd949 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-all -version: 0.2.13-dev +version: 0.2.13 groups: rust extractor: rust dbscheme: rust.dbscheme diff --git a/rust/ql/src/CHANGELOG.md b/rust/ql/src/CHANGELOG.md index 14034c9877d..4b735337c90 100644 --- a/rust/ql/src/CHANGELOG.md +++ b/rust/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.34 + +No user-facing changes. + ## 0.1.33 No user-facing changes. diff --git a/rust/ql/src/change-notes/released/0.1.34.md b/rust/ql/src/change-notes/released/0.1.34.md new file mode 100644 index 00000000000..a3a4edb1e1d --- /dev/null +++ b/rust/ql/src/change-notes/released/0.1.34.md @@ -0,0 +1,3 @@ +## 0.1.34 + +No user-facing changes. diff --git a/rust/ql/src/codeql-pack.release.yml b/rust/ql/src/codeql-pack.release.yml index d9c9e819daa..a1d4333b19b 100644 --- a/rust/ql/src/codeql-pack.release.yml +++ b/rust/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.33 +lastReleaseVersion: 0.1.34 diff --git a/rust/ql/src/qlpack.yml b/rust/ql/src/qlpack.yml index 7b2bd73728a..3fde632f1ac 100644 --- a/rust/ql/src/qlpack.yml +++ b/rust/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-queries -version: 0.1.34-dev +version: 0.1.34 groups: - rust - queries diff --git a/shared/concepts/CHANGELOG.md b/shared/concepts/CHANGELOG.md index e8b920847e9..59942922ea0 100644 --- a/shared/concepts/CHANGELOG.md +++ b/shared/concepts/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.23 + +No user-facing changes. + ## 0.0.22 No user-facing changes. diff --git a/shared/concepts/change-notes/released/0.0.23.md b/shared/concepts/change-notes/released/0.0.23.md new file mode 100644 index 00000000000..e89a1284bb8 --- /dev/null +++ b/shared/concepts/change-notes/released/0.0.23.md @@ -0,0 +1,3 @@ +## 0.0.23 + +No user-facing changes. diff --git a/shared/concepts/codeql-pack.release.yml b/shared/concepts/codeql-pack.release.yml index 11aaa2243f5..cc2195603d8 100644 --- a/shared/concepts/codeql-pack.release.yml +++ b/shared/concepts/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.22 +lastReleaseVersion: 0.0.23 diff --git a/shared/concepts/qlpack.yml b/shared/concepts/qlpack.yml index 947826f7dfd..95f898e6a70 100644 --- a/shared/concepts/qlpack.yml +++ b/shared/concepts/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/concepts -version: 0.0.23-dev +version: 0.0.23 groups: shared library: true dependencies: diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index df00c6146d8..9c6d7c09d17 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.33 + +No user-facing changes. + ## 2.0.32 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/2.0.33.md b/shared/controlflow/change-notes/released/2.0.33.md new file mode 100644 index 00000000000..d33a61332cf --- /dev/null +++ b/shared/controlflow/change-notes/released/2.0.33.md @@ -0,0 +1,3 @@ +## 2.0.33 + +No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index 483a0d5db8e..92e23200b4d 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.32 +lastReleaseVersion: 2.0.33 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index adc4aedc5c3..fa246d14d69 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 2.0.33-dev +version: 2.0.33 groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index ed60239f3de..9e4ca0a0ea8 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.5 + +No user-facing changes. + ## 2.1.4 No user-facing changes. diff --git a/shared/dataflow/change-notes/released/2.1.5.md b/shared/dataflow/change-notes/released/2.1.5.md new file mode 100644 index 00000000000..7e559ea5dd0 --- /dev/null +++ b/shared/dataflow/change-notes/released/2.1.5.md @@ -0,0 +1,3 @@ +## 2.1.5 + +No user-facing changes. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index 896b46fda9b..a890ff0111c 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.1.4 +lastReleaseVersion: 2.1.5 diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index a18b746e4b4..700651f8de6 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 2.1.5-dev +version: 2.1.5 groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index ff868403d0c..5d5551d10a3 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/shared/mad/change-notes/released/1.0.49.md b/shared/mad/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/shared/mad/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index dd5fcf54034..472719d4127 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.49-dev +version: 1.0.49 groups: shared library: true dependencies: diff --git a/shared/quantum/CHANGELOG.md b/shared/quantum/CHANGELOG.md index eccc65c6041..be06e2108a8 100644 --- a/shared/quantum/CHANGELOG.md +++ b/shared/quantum/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.27 + +No user-facing changes. + ## 0.0.26 No user-facing changes. diff --git a/shared/quantum/change-notes/released/0.0.27.md b/shared/quantum/change-notes/released/0.0.27.md new file mode 100644 index 00000000000..ff6e274427b --- /dev/null +++ b/shared/quantum/change-notes/released/0.0.27.md @@ -0,0 +1,3 @@ +## 0.0.27 + +No user-facing changes. diff --git a/shared/quantum/codeql-pack.release.yml b/shared/quantum/codeql-pack.release.yml index c576d2d7db2..dbab90d6989 100644 --- a/shared/quantum/codeql-pack.release.yml +++ b/shared/quantum/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.26 +lastReleaseVersion: 0.0.27 diff --git a/shared/quantum/qlpack.yml b/shared/quantum/qlpack.yml index c4e5d41dfaa..d29cac4faa1 100644 --- a/shared/quantum/qlpack.yml +++ b/shared/quantum/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/quantum -version: 0.0.27-dev +version: 0.0.27 groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/CHANGELOG.md b/shared/rangeanalysis/CHANGELOG.md index 9afb612f18a..8b457ef5927 100644 --- a/shared/rangeanalysis/CHANGELOG.md +++ b/shared/rangeanalysis/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/shared/rangeanalysis/change-notes/released/1.0.49.md b/shared/rangeanalysis/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/shared/rangeanalysis/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/shared/rangeanalysis/codeql-pack.release.yml b/shared/rangeanalysis/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/shared/rangeanalysis/codeql-pack.release.yml +++ b/shared/rangeanalysis/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index ed3b4a66239..4261dfb4991 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.49-dev +version: 1.0.49 groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index 2375b7b56ab..639cede00af 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/shared/regex/change-notes/released/1.0.49.md b/shared/regex/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/shared/regex/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 3d569c7d429..3d6feafbf39 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.49-dev +version: 1.0.49 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index dd21ba6d38b..9cfbb004657 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.25 + +No user-facing changes. + ## 2.0.24 No user-facing changes. diff --git a/shared/ssa/change-notes/released/2.0.25.md b/shared/ssa/change-notes/released/2.0.25.md new file mode 100644 index 00000000000..ca39dd50c69 --- /dev/null +++ b/shared/ssa/change-notes/released/2.0.25.md @@ -0,0 +1,3 @@ +## 2.0.25 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index 1460df314d5..f54d8620118 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.24 +lastReleaseVersion: 2.0.25 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index c1fd261e070..517a79c557c 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 2.0.25-dev +version: 2.0.25 groups: shared library: true dependencies: diff --git a/shared/threat-models/CHANGELOG.md b/shared/threat-models/CHANGELOG.md index a3aa00d4872..a6b6055373a 100644 --- a/shared/threat-models/CHANGELOG.md +++ b/shared/threat-models/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/shared/threat-models/change-notes/released/1.0.49.md b/shared/threat-models/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/shared/threat-models/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/shared/threat-models/codeql-pack.release.yml b/shared/threat-models/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/shared/threat-models/codeql-pack.release.yml +++ b/shared/threat-models/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 59ce8c06727..71e6b70a313 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.49-dev +version: 1.0.49 library: true groups: shared dataExtensions: diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index 9350e8a04eb..5fcacc0b8b5 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/1.0.49.md b/shared/tutorial/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/shared/tutorial/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 36b8181e0bf..c1df7d67b85 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.49-dev +version: 1.0.49 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/CHANGELOG.md b/shared/typeflow/CHANGELOG.md index 035c2aa456e..fbfdb431161 100644 --- a/shared/typeflow/CHANGELOG.md +++ b/shared/typeflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/shared/typeflow/change-notes/released/1.0.49.md b/shared/typeflow/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/shared/typeflow/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/shared/typeflow/codeql-pack.release.yml b/shared/typeflow/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/shared/typeflow/codeql-pack.release.yml +++ b/shared/typeflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index 0734b2b722e..2f22c6655a5 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.49-dev +version: 1.0.49 groups: shared library: true dependencies: diff --git a/shared/typeinference/CHANGELOG.md b/shared/typeinference/CHANGELOG.md index c8b656e4f35..1652285654a 100644 --- a/shared/typeinference/CHANGELOG.md +++ b/shared/typeinference/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.30 + +No user-facing changes. + ## 0.0.29 No user-facing changes. diff --git a/shared/typeinference/change-notes/released/0.0.30.md b/shared/typeinference/change-notes/released/0.0.30.md new file mode 100644 index 00000000000..10c7a0c5c13 --- /dev/null +++ b/shared/typeinference/change-notes/released/0.0.30.md @@ -0,0 +1,3 @@ +## 0.0.30 + +No user-facing changes. diff --git a/shared/typeinference/codeql-pack.release.yml b/shared/typeinference/codeql-pack.release.yml index c81f1813120..0c61b463bab 100644 --- a/shared/typeinference/codeql-pack.release.yml +++ b/shared/typeinference/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.29 +lastReleaseVersion: 0.0.30 diff --git a/shared/typeinference/qlpack.yml b/shared/typeinference/qlpack.yml index 2bf5c49d97e..039107b5ef9 100644 --- a/shared/typeinference/qlpack.yml +++ b/shared/typeinference/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeinference -version: 0.0.30-dev +version: 0.0.30 groups: shared library: true dependencies: diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index 75d8938e6a1..ecdded5ceda 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.33 + +No user-facing changes. + ## 2.0.32 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/2.0.33.md b/shared/typetracking/change-notes/released/2.0.33.md new file mode 100644 index 00000000000..d33a61332cf --- /dev/null +++ b/shared/typetracking/change-notes/released/2.0.33.md @@ -0,0 +1,3 @@ +## 2.0.33 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index 483a0d5db8e..92e23200b4d 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.32 +lastReleaseVersion: 2.0.33 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index fe35cf5955b..4f8f21fd569 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 2.0.33-dev +version: 2.0.33 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 35825098a63..617fa5638b4 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/shared/typos/change-notes/released/1.0.49.md b/shared/typos/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/shared/typos/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index a8c85168f20..441404e19f3 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.49-dev +version: 1.0.49 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index d1becc8ba2c..51488029e96 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.36 + +No user-facing changes. + ## 2.0.35 No user-facing changes. diff --git a/shared/util/change-notes/released/2.0.36.md b/shared/util/change-notes/released/2.0.36.md new file mode 100644 index 00000000000..8acdd12366e --- /dev/null +++ b/shared/util/change-notes/released/2.0.36.md @@ -0,0 +1,3 @@ +## 2.0.36 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index 27eb8ef8ece..7e4aaa0dd67 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.35 +lastReleaseVersion: 2.0.36 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 99f8c5374dc..f3b6b7f3ff8 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.36-dev +version: 2.0.36 groups: shared library: true dependencies: null diff --git a/shared/xml/CHANGELOG.md b/shared/xml/CHANGELOG.md index 131bf7afd2a..9f60f66ff72 100644 --- a/shared/xml/CHANGELOG.md +++ b/shared/xml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/shared/xml/change-notes/released/1.0.49.md b/shared/xml/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/shared/xml/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/shared/xml/codeql-pack.release.yml b/shared/xml/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/shared/xml/codeql-pack.release.yml +++ b/shared/xml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index 2c44df63e7e..718c36108f6 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.49-dev +version: 1.0.49 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 1c420b31355..a13e3308874 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.49 + +No user-facing changes. + ## 1.0.48 No user-facing changes. diff --git a/shared/yaml/change-notes/released/1.0.49.md b/shared/yaml/change-notes/released/1.0.49.md new file mode 100644 index 00000000000..df67fb8cc76 --- /dev/null +++ b/shared/yaml/change-notes/released/1.0.49.md @@ -0,0 +1,3 @@ +## 1.0.49 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index 6db79f2c397..596617977df 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.48 +lastReleaseVersion: 1.0.49 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 6778ee5a156..4bb6e173ab6 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.49-dev +version: 1.0.49 groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index e2cb45f9769..e7979dbf0ed 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 6.5.0 + +### New Features + +* The `BuiltinFixedArrayType` class now defines the predicates `getSize` and `getElementType`, which yield the size of the array and the type of elements stored in the array, respectively. + +### Major Analysis Improvements + +* Upgraded to allow analysis of Swift 6.3.1. + ## 6.4.0 ### Major Analysis Improvements diff --git a/swift/ql/lib/change-notes/2026-04-20-swift-6.3.1.md b/swift/ql/lib/change-notes/2026-04-20-swift-6.3.1.md deleted file mode 100644 index acc4bc73861..00000000000 --- a/swift/ql/lib/change-notes/2026-04-20-swift-6.3.1.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Upgraded to allow analysis of Swift 6.3.1. diff --git a/swift/ql/lib/change-notes/2026-04-17-fixed-array.md b/swift/ql/lib/change-notes/released/6.5.0.md similarity index 63% rename from swift/ql/lib/change-notes/2026-04-17-fixed-array.md rename to swift/ql/lib/change-notes/released/6.5.0.md index 3fd91627544..5b390d1bfd4 100644 --- a/swift/ql/lib/change-notes/2026-04-17-fixed-array.md +++ b/swift/ql/lib/change-notes/released/6.5.0.md @@ -1,4 +1,9 @@ ---- -category: feature ---- +## 6.5.0 + +### New Features + * The `BuiltinFixedArrayType` class now defines the predicates `getSize` and `getElementType`, which yield the size of the array and the type of elements stored in the array, respectively. + +### Major Analysis Improvements + +* Upgraded to allow analysis of Swift 6.3.1. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 3098c5db6c3..2813c8e210f 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 6.4.0 +lastReleaseVersion: 6.5.0 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 595a2804df5..ff088e209fa 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 6.4.1-dev +version: 6.5.0 groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index af70cebc1e4..f7b81101037 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.2 + +No user-facing changes. + ## 1.3.1 No user-facing changes. diff --git a/swift/ql/src/change-notes/released/1.3.2.md b/swift/ql/src/change-notes/released/1.3.2.md new file mode 100644 index 00000000000..14f14807ef5 --- /dev/null +++ b/swift/ql/src/change-notes/released/1.3.2.md @@ -0,0 +1,3 @@ +## 1.3.2 + +No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index e71b6d081f1..86a9cb32d86 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.1 +lastReleaseVersion: 1.3.2 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 6b4dc1f65e5..26d9123f050 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.3.2-dev +version: 1.3.2 groups: - swift - queries From 76102771996713aaa935d824f32575d37b983109 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 5 May 2026 10:10:06 +0000 Subject: [PATCH 14/43] Post-release preparation for codeql-cli-2.25.4 --- 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 a20f2e7a507..cf1232c01fb 100644 --- a/actions/ql/lib/qlpack.yml +++ b/actions/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-all -version: 0.4.35 +version: 0.4.36-dev library: true warnOnImplicitThis: true dependencies: diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml index bcc7fe06a3b..2c9811c780a 100644 --- a/actions/ql/src/qlpack.yml +++ b/actions/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-queries -version: 0.6.27 +version: 0.6.28-dev library: false warnOnImplicitThis: true groups: [actions, queries] diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index e3b9f7c3363..88d4dafaebb 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 10.1.0 +version: 10.1.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 83d7a32e6d4..ddd0014f2e0 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.6.2 +version: 1.6.3-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 88ba74212c7..c5cfa0dcd89 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.66 +version: 1.7.67-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index fee050486c9..c9f0acac983 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.66 +version: 1.7.67-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index daded1ee71e..0e03db99ca9 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 6.0.0 +version: 6.0.1-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 72d951194c3..de201743065 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.7.2 +version: 1.7.3-dev groups: - csharp - queries diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 73a837bd0e0..49572c215bb 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.49 +version: 1.0.50-dev groups: - go - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 1d1682d6108..16ddb133517 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 7.1.0 +version: 7.1.1-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 78c75459387..5fdc63fe363 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.6.2 +version: 1.6.3-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index e57412ee1fc..e5ebb1d2131 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 9.1.0 +version: 9.1.1-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index bdaaf77ec9e..3776af914c2 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.11.2 +version: 1.11.3-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 97c3de6a8eb..623a7f4db2f 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.7.0 +version: 2.7.1-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 417df72e5ba..593c0032466 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 2.3.9 +version: 2.3.10-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 52fc453aa32..802112d0fc8 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.49 +version: 1.0.50-dev groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 2cd96a3e443..724d270b4e8 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 7.1.0 +version: 7.1.1-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 46e7203a953..0544fddc168 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.8.2 +version: 1.8.3-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 261a9890d44..cfdaf454426 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 5.2.0 +version: 5.2.1-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 34f5d14c39c..beaf92c0d8a 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.6.2 +version: 1.6.3-dev groups: - ruby - queries diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 96b825fd949..47f846eb02b 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-all -version: 0.2.13 +version: 0.2.14-dev groups: rust extractor: rust dbscheme: rust.dbscheme diff --git a/rust/ql/src/qlpack.yml b/rust/ql/src/qlpack.yml index 3fde632f1ac..ec76e8f1265 100644 --- a/rust/ql/src/qlpack.yml +++ b/rust/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-queries -version: 0.1.34 +version: 0.1.35-dev groups: - rust - queries diff --git a/shared/concepts/qlpack.yml b/shared/concepts/qlpack.yml index 95f898e6a70..6943387bae2 100644 --- a/shared/concepts/qlpack.yml +++ b/shared/concepts/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/concepts -version: 0.0.23 +version: 0.0.24-dev groups: shared library: true dependencies: diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index fa246d14d69..7fbe2fd4ea9 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 2.0.33 +version: 2.0.34-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 700651f8de6..34336f4c322 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 2.1.5 +version: 2.1.6-dev groups: shared library: true dependencies: diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index 472719d4127..5631fbf1a73 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.49 +version: 1.0.50-dev groups: shared library: true dependencies: diff --git a/shared/quantum/qlpack.yml b/shared/quantum/qlpack.yml index d29cac4faa1..794f238b6e9 100644 --- a/shared/quantum/qlpack.yml +++ b/shared/quantum/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/quantum -version: 0.0.27 +version: 0.0.28-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index 4261dfb4991..e43819bf36e 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.49 +version: 1.0.50-dev groups: shared library: true dependencies: diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 3d6feafbf39..242382c6a1f 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.49 +version: 1.0.50-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 517a79c557c..9e510c43dd0 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 2.0.25 +version: 2.0.26-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 71e6b70a313..14e33e435d1 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.49 +version: 1.0.50-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index c1df7d67b85..10b77ca0438 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.49 +version: 1.0.50-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index 2f22c6655a5..9301be5228f 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.49 +version: 1.0.50-dev groups: shared library: true dependencies: diff --git a/shared/typeinference/qlpack.yml b/shared/typeinference/qlpack.yml index 039107b5ef9..1db3c0e95ac 100644 --- a/shared/typeinference/qlpack.yml +++ b/shared/typeinference/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeinference -version: 0.0.30 +version: 0.0.31-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 4f8f21fd569..436b35815f0 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 2.0.33 +version: 2.0.34-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 441404e19f3..4057cfb5784 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.49 +version: 1.0.50-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index f3b6b7f3ff8..cff240056a4 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.36 +version: 2.0.37-dev groups: shared library: true dependencies: null diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index 718c36108f6..748ac73e0f8 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.49 +version: 1.0.50-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 4bb6e173ab6..54d582bb9fa 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.49 +version: 1.0.50-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index ff088e209fa..921af77ca70 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 6.5.0 +version: 6.5.1-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 26d9123f050..5354c5ee4d5 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.3.2 +version: 1.3.3-dev groups: - swift - queries From 04f587190e42c852823d2a340854c2d1649a26fd Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 4 May 2026 13:13:08 +0000 Subject: [PATCH 15/43] yeast: AST desugaring framework with proc-macro DSL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit YEAST (YEAST Elaborates Abstract Syntax Trees) is a framework for transforming tree-sitter parse trees before CodeQL extraction. Core components: - shared/yeast/ — Ast, Node, Schema, query matching engine, captures, FreshScope, BuildCtx - shared/yeast-macros/ — proc macros: query!, tree!, trees!, rule! The query language is inspired by tree-sitter queries: (assignment left: (_) @lhs right: (_) @rhs) Templates support embedded Rust ({expr}), splicing ({..expr}), computed literals (#{expr}), and fresh identifiers ($name). The rule! macro combines query and transform: rule!((for pattern: (_) @pat ...) => (call receiver: {val} ...)) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Cargo.lock | 40 +- Cargo.toml | 2 + shared/yeast-macros/Cargo.toml | 12 + shared/yeast-macros/src/lib.rs | 105 ++++ shared/yeast-macros/src/parse.rs | 838 +++++++++++++++++++++++++++++++ shared/yeast/Cargo.toml | 15 + shared/yeast/src/bin/main.rs | 26 + shared/yeast/src/build.rs | 91 ++++ shared/yeast/src/captures.rs | 105 ++++ shared/yeast/src/cursor.rs | 8 + shared/yeast/src/lib.rs | 727 +++++++++++++++++++++++++++ shared/yeast/src/query.rs | 228 +++++++++ shared/yeast/src/range.rs | 21 + shared/yeast/src/schema.rs | 167 ++++++ shared/yeast/src/tree_builder.rs | 43 ++ shared/yeast/src/visitor.rs | 111 ++++ 16 files changed, 2535 insertions(+), 4 deletions(-) create mode 100644 shared/yeast-macros/Cargo.toml create mode 100644 shared/yeast-macros/src/lib.rs create mode 100644 shared/yeast-macros/src/parse.rs create mode 100644 shared/yeast/Cargo.toml create mode 100644 shared/yeast/src/bin/main.rs create mode 100644 shared/yeast/src/build.rs create mode 100644 shared/yeast/src/captures.rs create mode 100644 shared/yeast/src/cursor.rs create mode 100644 shared/yeast/src/lib.rs create mode 100644 shared/yeast/src/query.rs create mode 100644 shared/yeast/src/range.rs create mode 100644 shared/yeast/src/schema.rs create mode 100644 shared/yeast/src/tree_builder.rs create mode 100644 shared/yeast/src/visitor.rs diff --git a/Cargo.lock b/Cargo.lock index b6456c84106..38a3c806fb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,6 +416,7 @@ dependencies = [ "tree-sitter", "tree-sitter-json", "tree-sitter-ql", + "yeast", "zstd", ] @@ -2470,7 +2471,6 @@ version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.11.4", "itoa", "memchr", "ryu", @@ -2853,14 +2853,13 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.25.9" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd2a058a86cfece0bf96f7cce1021efef9c8ed0e892ab74639173e5ed7a34fa" +checksum = "a5387dffa7ffc7d2dae12b50c6f7aab8ff79d6210147c6613561fc3d474c6f75" dependencies = [ "cc", "regex", "regex-syntax", - "serde_json", "streaming-iterator", "tree-sitter-language", ] @@ -2891,6 +2890,16 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4013970217383f67b18aef68f6fb2e8d409bc5755227092d32efb0422ba24b8" +[[package]] +name = "tree-sitter-python" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d065aaa27f3aaceaf60c1f0e0ac09e1cb9eb8ed28e7bcdaa52129cffc7f4b04" +dependencies = [ + "cc", + "tree-sitter-language", +] + [[package]] name = "tree-sitter-ql" version = "0.23.1" @@ -3367,6 +3376,29 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "yeast" +version = "0.1.0" +dependencies = [ + "clap", + "serde", + "serde_json", + "serde_yaml", + "tree-sitter", + "tree-sitter-python", + "tree-sitter-ruby", + "yeast-macros", +] + +[[package]] +name = "yeast-macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "yoke" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 58a755340b9..1e2be0d9ca5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,8 @@ resolver = "2" members = [ "shared/tree-sitter-extractor", + "shared/yeast", + "shared/yeast-macros", "ruby/extractor", "rust/extractor", "rust/extractor/macros", diff --git a/shared/yeast-macros/Cargo.toml b/shared/yeast-macros/Cargo.toml new file mode 100644 index 00000000000..30c82d03b6e --- /dev/null +++ b/shared/yeast-macros/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "yeast-macros" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0" +quote = "1.0" +syn = "2.0" diff --git a/shared/yeast-macros/src/lib.rs b/shared/yeast-macros/src/lib.rs new file mode 100644 index 00000000000..0c264ee13c8 --- /dev/null +++ b/shared/yeast-macros/src/lib.rs @@ -0,0 +1,105 @@ +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; + +mod parse; + +/// Proc macro for constructing a `QueryNode` from a tree-sitter-inspired pattern. +/// +/// # Syntax +/// +/// ```text +/// (_) - match any named node (skips unnamed tokens) +/// (kind) - match a named node of the given kind +/// ("literal") - match an unnamed token by its text +/// (kind field: (pattern)) - match with named field +/// (kind (pat) (pat)...) - match unnamed children (after all fields) +/// (pattern) @capture - capture the matched node +/// (pattern)* @capture - capture each repeated match +/// (pattern)? - zero or one +/// ``` +#[proc_macro] +pub fn query(input: TokenStream) -> TokenStream { + let input2: TokenStream2 = input.into(); + match parse::parse_query_top(input2) { + Ok(output) => output.into(), + Err(err) => err.to_compile_error().into(), + } +} + +/// Build a single AST node from a template, returning its `Id`. +/// +/// # Template syntax +/// +/// ```text +/// (kind "literal") - leaf with static content +/// (kind #{expr}) - leaf with computed content (expr.to_string()) +/// (kind $fresh) - leaf with auto-generated unique name +/// {expr} - embed a Rust expression returning Id +/// {..expr} - splice an iterable of Id (in child/field position) +/// field: {..expr} - splice into a named field +/// ``` +/// +/// Can be called with an explicit context or using the implicit context +/// from an enclosing `rule!`: +/// +/// ```text +/// tree!(ctx, (kind ...)) // explicit BuildCtx +/// tree!((kind ...)) // implicit context from rule! +/// ``` +#[proc_macro] +pub fn tree(input: TokenStream) -> TokenStream { + let input2: TokenStream2 = input.into(); + match parse::parse_tree_top(input2) { + Ok(output) => output.into(), + Err(err) => err.to_compile_error().into(), + } +} + +/// Build a list of AST nodes from a template, returning `Vec`. +/// +/// Like `tree!` but returns `Vec` and supports multiple top-level +/// elements. All syntax from `tree!` is available. +/// +/// Can be called with an explicit context or using the implicit context +/// from an enclosing `rule!`: +/// +/// ```text +/// trees!(ctx, (node1 ...) (node2 ...)) // explicit BuildCtx +/// trees!((node1 ...) (node2 ...)) // implicit context from rule! +/// ``` +#[proc_macro] +pub fn trees(input: TokenStream) -> TokenStream { + let input2: TokenStream2 = input.into(); + match parse::parse_trees_top(input2) { + Ok(output) => output.into(), + Err(err) => err.to_compile_error().into(), + } +} + +/// Define a desugaring rule with query and transform in one declaration. +/// +/// ```text +/// rule!( +/// (query_pattern field: (_) @name (kind)* @repeated (_)? @optional) +/// => +/// (output_template field: {name} {..repeated}) +/// ) +/// +/// // Shorthand: captures become fields on the output node +/// rule!((query ...) => output_kind) +/// ``` +/// +/// Captures become Rust variables automatically: +/// - `@name` (no quantifier) → `name: Id` +/// - `@name` (after `*`/`+`) → `name: Vec` +/// - `@name` (after `?`) → `name: Option` +/// +/// `tree!` and `trees!` can be used without explicit context inside `{...}`. +#[proc_macro] +pub fn rule(input: TokenStream) -> TokenStream { + let input2: TokenStream2 = input.into(); + match parse::parse_rule_top(input2) { + Ok(output) => output.into(), + Err(err) => err.to_compile_error().into(), + } +} diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs new file mode 100644 index 00000000000..f8554f3178c --- /dev/null +++ b/shared/yeast-macros/src/parse.rs @@ -0,0 +1,838 @@ +use proc_macro2::{Delimiter, Ident, Literal, Span, TokenStream, TokenTree}; +use quote::quote; +use std::iter::Peekable; + +type Tokens = Peekable; +type Result = std::result::Result; + +// --------------------------------------------------------------------------- +// Query parsing +// --------------------------------------------------------------------------- + +/// Top-level entry: parse a single query node from the full input. +pub fn parse_query_top(input: TokenStream) -> Result { + let mut tokens = input.into_iter().peekable(); + let result = parse_query_node(&mut tokens)?; + if let Some(tok) = tokens.next() { + return Err(syn::Error::new_spanned(tok, "unexpected token after query")); + } + Ok(result) +} + +/// Parse a single query node (possibly with a trailing `@capture`). +fn parse_query_node(tokens: &mut Tokens) -> Result { + let base = parse_query_atom(tokens)?; + // Check for trailing @capture + if peek_is_at(tokens) { + tokens.next(); // consume @ + let capture_name = expect_ident(tokens, "expected capture name after @")?; + let name_str = capture_name.to_string(); + Ok(quote! { + yeast::query::QueryNode::Capture { + capture: #name_str, + node: Box::new(#base), + } + }) + } else { + Ok(base) + } +} + +/// Parse a query atom: `(kind fields...)` or `(kind fields... bare_children...)`. +/// Does not handle `@capture` — that's handled by the caller as a postfix. +fn parse_query_atom(tokens: &mut Tokens) -> Result { + match tokens.peek() { + None => Err(syn::Error::new( + Span::call_site(), + "unexpected end of query", + )), + Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis => { + let group = expect_group(tokens, Delimiter::Parenthesis)?; + let mut inner = group.stream().into_iter().peekable(); + let result = parse_query_node_inner(&mut inner)?; + if let Some(tok) = inner.next() { + return Err(syn::Error::new_spanned( + tok, + "unexpected token in query node", + )); + } + Ok(result) + } + Some(tok) => Err(syn::Error::new_spanned( + tok.clone(), + "expected `(` in query; use `(_) @name` to capture a wildcard", + )), + } +} + +/// Parse the inside of a parenthesized query node: `kind fields...` or `_` or `"lit"`. +fn parse_query_node_inner(tokens: &mut Tokens) -> Result { + match tokens.peek() { + None => Err(syn::Error::new( + Span::call_site(), + "empty parenthesized group in query", + )), + Some(TokenTree::Ident(id)) if *id == "_" => { + tokens.next(); + Ok(quote! { yeast::query::QueryNode::Any() }) + } + Some(TokenTree::Literal(_)) => { + let lit = expect_literal(tokens)?; + Ok(quote! { yeast::query::QueryNode::UnnamedNode { kind: #lit } }) + } + Some(TokenTree::Ident(_)) => { + let kind = expect_ident(tokens, "expected node kind")?; + let kind_str = kind.to_string(); + let fields = parse_query_fields(tokens)?; + Ok(quote! { + yeast::query::QueryNode::Node { + kind: #kind_str, + children: vec![#(#fields),*], + } + }) + } + Some(tok) => Err(syn::Error::new_spanned( + tok.clone(), + "expected node kind, `_`, or string literal", + )), + } +} + +/// Parse zero or more field specifications and trailing bare patterns. +/// Named fields: `name: pattern` or `name*: (list...)`. +/// Bare patterns (no field name) become implicit `child` field entries. +fn parse_query_fields(tokens: &mut Tokens) -> Result> { + let mut fields = Vec::new(); + while tokens.peek().is_some() { + if peek_is_field(tokens) { + let field_name = expect_ident(tokens, "expected field name")?; + let field_str = field_name.to_string(); + + expect_punct(tokens, ':', "expected `:` after field name")?; + + let child = parse_query_node(tokens)?; + fields.push(quote! { + (#field_str, vec![yeast::query::QueryListElem::SingleNode(#child)]) + }); + } else { + // Bare patterns — collect as implicit `child` field + let elems = parse_query_list(tokens)?; + if !elems.is_empty() { + fields.push(quote! { + ("child", vec![#(#elems),*]) + }); + } + break; + } + } + Ok(fields) +} + +/// Parse a list of query elements (bare children). +/// Each element is a node pattern, possibly followed by `*`, `+`, `?`. +fn parse_query_list(tokens: &mut Tokens) -> Result> { + let mut elems = Vec::new(); + while tokens.peek().is_some() { + // Check for parenthesized group + if peek_is_group(tokens, Delimiter::Parenthesis) { + let group = expect_group(tokens, Delimiter::Parenthesis)?; + let mut inner = group.stream().into_iter().peekable(); + + // Check for repetition after the group + if peek_is_repetition(tokens) { + let rep = expect_repetition(tokens)?; + // Determine if the group is a single node pattern or a list + // of patterns. If it starts with an identifier (node kind) or + // `_`, treat it as a single repeated node. Otherwise, parse + // as a repeated list of sub-patterns. + let is_single_node = matches!(inner.peek(), Some(TokenTree::Ident(_))); + if is_single_node { + let node = parse_query_node_inner(&mut inner)?; + let elem = quote! { + yeast::query::QueryListElem::Repeated { + children: vec![yeast::query::QueryListElem::SingleNode(#node)], + rep: #rep, + } + }; + let elem = maybe_wrap_list_capture(tokens, elem)?; + elems.push(elem); + } else { + let sub_elems = parse_query_list(&mut inner)?; + let elem = quote! { + yeast::query::QueryListElem::Repeated { + children: vec![#(#sub_elems),*], + rep: #rep, + } + }; + let elem = maybe_wrap_list_capture(tokens, elem)?; + elems.push(elem); + } + } else { + // Single parenthesized node, possibly followed by @capture + let node = parse_query_node_inner(&mut inner)?; + let node = maybe_wrap_capture(tokens, node)?; + elems.push(quote! { + yeast::query::QueryListElem::SingleNode(#node) + }); + } + continue; + } + + // Check for string literal (unnamed node) + if peek_is_literal(tokens) { + let lit = expect_literal(tokens)?; + let node = quote! { yeast::query::QueryNode::UnnamedNode { kind: #lit } }; + let elem = maybe_wrap_repetition( + tokens, + quote! { + yeast::query::QueryListElem::SingleNode(#node) + }, + )?; + elems.push(elem); + continue; + } + + // Check for bare _ (wildcard), possibly followed by @capture + if peek_is_underscore(tokens) { + tokens.next(); + let node = quote! { yeast::query::QueryNode::Any() }; + let node = maybe_wrap_capture(tokens, node)?; + let elem = maybe_wrap_repetition( + tokens, + quote! { + yeast::query::QueryListElem::SingleNode(#node) + }, + )?; + elems.push(elem); + continue; + } + + break; + } + Ok(elems) +} + +// --------------------------------------------------------------------------- +// tree! / trees! parsing — direct code generation against BuildCtx +// --------------------------------------------------------------------------- + +const IMPLICIT_CTX: &str = "__yeast_ctx"; + +/// Determine the context identifier: either explicit `ctx,` or the implicit +/// `__yeast_ctx` from an enclosing `rule!`. +fn parse_ctx_or_implicit(tokens: &mut Tokens) -> Ident { + // Check if first token is an ident followed by a comma + let mut lookahead = tokens.clone(); + let is_explicit = matches!(lookahead.next(), Some(TokenTree::Ident(_))) + && matches!(lookahead.next(), Some(TokenTree::Punct(p)) if p.as_char() == ','); + + if is_explicit { + let ctx = expect_ident(tokens, "").unwrap(); + let _ = tokens.next(); // consume comma + ctx + } else { + Ident::new(IMPLICIT_CTX, Span::call_site()) + } +} + +/// Parse `tree!(ctx, (template))` or `tree!((template))` — returns single `Id`. +pub fn parse_tree_top(input: TokenStream) -> Result { + let mut tokens = input.into_iter().peekable(); + let ctx = parse_ctx_or_implicit(&mut tokens); + + let first = parse_direct_node(&mut tokens, &ctx)?; + + if let Some(tok) = tokens.next() { + return Err(syn::Error::new_spanned( + tok, + "unexpected tokens after tree! template; use trees! for multiple nodes", + )); + } + + Ok(quote! { { #first } }) +} + +/// Parse `trees!(ctx, ...)` or `trees!(...)` — returns `Vec`. +pub fn parse_trees_top(input: TokenStream) -> Result { + let mut tokens = input.into_iter().peekable(); + let ctx = parse_ctx_or_implicit(&mut tokens); + let items = parse_direct_list(&mut tokens, &ctx)?; + if let Some(tok) = tokens.next() { + return Err(syn::Error::new_spanned( + tok, + "unexpected token after trees! template", + )); + } + Ok(quote! { + { + let mut __nodes: Vec = Vec::new(); + #(#items)* + __nodes + } + }) +} + +/// Parse a single node template and generate code that returns an `Id`. +/// Handles: `(kind fields... children...)` and `{expr}`. +fn parse_direct_node(tokens: &mut Tokens, ctx: &Ident) -> Result { + match tokens.peek() { + Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Brace => { + let group = expect_group(tokens, Delimiter::Brace)?; + let expr = group.stream(); + Ok(quote! { #expr }) + } + Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis => { + let group = expect_group(tokens, Delimiter::Parenthesis)?; + let mut inner = group.stream().into_iter().peekable(); + parse_direct_node_inner(&mut inner, ctx) + } + Some(tok) => Err(syn::Error::new_spanned( + tok.clone(), + "expected `(` or `{` in tree template", + )), + None => Err(syn::Error::new( + Span::call_site(), + "unexpected end of tree template", + )), + } +} + +/// Parse the inside of a parenthesized node: `kind fields... children...` +/// or `kind "literal"` or `kind $fresh`. +fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result { + let kind = expect_ident(tokens, "expected node kind")?; + let kind_str = kind.to_string(); + + // Check for (kind "literal") + if peek_is_literal(tokens) { + let lit = expect_literal(tokens)?; + return Ok(quote! { #ctx.literal(#kind_str, #lit) }); + } + + // Check for (kind #{expr}) — computed literal, expr converted via .to_string() + if peek_is_hash(tokens) { + tokens.next(); // consume # + let group = expect_group(tokens, Delimiter::Brace)?; + let expr = group.stream(); + return Ok(quote! { #ctx.literal(#kind_str, &(#expr).to_string()) }); + } + + // Check for (kind $fresh) + if peek_is_dollar(tokens) { + tokens.next(); + let name = expect_ident(tokens, "expected fresh variable name after $")?; + let name_str = name.to_string(); + return Ok(quote! { #ctx.fresh(#kind_str, #name_str) }); + } + + // Parse named fields + let mut stmts = Vec::new(); + let mut field_args = Vec::new(); + let mut field_counter = 0usize; + + // Named fields — compute each value into a temp, then reference it + while peek_is_field(tokens) { + let field_name = expect_ident(tokens, "expected field name")?; + let field_str = field_name.to_string(); + expect_punct(tokens, ':', "expected `:` after field name")?; + let temp = Ident::new( + &format!("__field_{field_str}_{field_counter}"), + Span::call_site(), + ); + field_counter += 1; + + // Check for field: {..expr} — splice a Vec into the field + if peek_is_group(tokens, Delimiter::Brace) { + let group_clone = tokens.clone().next().unwrap(); + if let TokenTree::Group(g) = &group_clone { + let mut inner_check = g.stream().into_iter(); + let is_splice = matches!(inner_check.next(), Some(TokenTree::Punct(p)) if p.as_char() == '.') + && matches!(inner_check.next(), Some(TokenTree::Punct(p)) if p.as_char() == '.'); + if is_splice { + let group = expect_group(tokens, Delimiter::Brace)?; + let mut inner = group.stream().into_iter().peekable(); + inner.next(); // consume first . + inner.next(); // consume second . + let expr: proc_macro2::TokenStream = inner.collect(); + stmts.push(quote! { let #temp: Vec = #expr; }); + field_args.push(quote! { (#field_str, #temp) }); + continue; + } + } + } + + let value = parse_direct_node(tokens, ctx)?; + stmts.push(quote! { let #temp = #value; }); + field_args.push(quote! { (#field_str, vec![#temp]) }); + } + + // After all named fields, no other tokens are allowed. + // Output templates require all children to be in named fields. + if let Some(tok) = tokens.peek() { + return Err(syn::Error::new_spanned( + tok.clone(), + "expected named field (`name:`) or end of node template; \ + output templates do not support unnamed children", + )); + } + + Ok(quote! { + { + #(#stmts)* + #ctx.node(#kind_str, vec![#(#field_args),*]) + } + }) +} + +/// Parse the top-level list of a `trees!` template. +/// Each item is a node template or `{expr}` splice. +fn parse_direct_list(tokens: &mut Tokens, ctx: &Ident) -> Result> { + let mut items = Vec::new(); + while tokens.peek().is_some() { + if peek_is_group(tokens, Delimiter::Parenthesis) { + let group = expect_group(tokens, Delimiter::Parenthesis)?; + let mut inner = group.stream().into_iter().peekable(); + + // Regular node + let node = parse_direct_node_inner(&mut inner, ctx)?; + items.push(quote! { __nodes.push(#node); }); + continue; + } + + // {expr} or {..expr} — single node or splice + if peek_is_group(tokens, Delimiter::Brace) { + let group = expect_group(tokens, Delimiter::Brace)?; + let mut inner = group.stream().into_iter().peekable(); + if peek_is_dotdot(&inner) { + inner.next(); // consume first . + inner.next(); // consume second . + let expr: TokenStream = inner.collect(); + items.push(quote! { __nodes.extend(#expr); }); + } else { + let expr = group.stream(); + items.push(quote! { __nodes.push(#expr); }); + } + continue; + } + + break; + } + Ok(items) +} + +// --------------------------------------------------------------------------- +// rule! parsing +// --------------------------------------------------------------------------- + +/// A captured variable from a query pattern. +struct CaptureInfo { + name: String, + multiplicity: CaptureMultiplicity, +} + +#[derive(Clone, Copy, PartialEq)] +enum CaptureMultiplicity { + /// Exactly one match (bare pattern or after no quantifier) + Single, + /// Zero or one match (after `?`) + Optional, + /// Zero or more matches (after `*` or `+`, or inside a repeated group) + Repeated, +} + +/// Walk a token stream and extract all `@name` captures, noting whether +/// they appear after `*` or `+` (repeated) or not. +fn extract_captures(stream: &TokenStream) -> Vec { + let mut captures = Vec::new(); + extract_captures_inner( + &mut stream.clone().into_iter().peekable(), + &mut captures, + CaptureMultiplicity::Single, + ); + captures +} + +fn extract_captures_inner( + tokens: &mut Tokens, + captures: &mut Vec, + parent_mult: CaptureMultiplicity, +) { + let mut last_mult = CaptureMultiplicity::Single; + while let Some(tok) = tokens.next() { + match tok { + TokenTree::Group(g) => { + let mut inner = g.stream().into_iter().peekable(); + let group_mult = match tokens.peek() { + Some(TokenTree::Punct(p)) if p.as_char() == '*' || p.as_char() == '+' => { + CaptureMultiplicity::Repeated + } + Some(TokenTree::Punct(p)) if p.as_char() == '?' => { + CaptureMultiplicity::Optional + } + _ => CaptureMultiplicity::Single, + }; + last_mult = group_mult; + let child_mult = if parent_mult == CaptureMultiplicity::Repeated + || group_mult == CaptureMultiplicity::Repeated + { + CaptureMultiplicity::Repeated + } else if parent_mult == CaptureMultiplicity::Optional + || group_mult == CaptureMultiplicity::Optional + { + CaptureMultiplicity::Optional + } else { + CaptureMultiplicity::Single + }; + extract_captures_inner(&mut inner, captures, child_mult); + } + TokenTree::Punct(p) if p.as_char() == '@' => { + if let Some(TokenTree::Ident(name)) = tokens.next() { + let mult = if parent_mult == CaptureMultiplicity::Repeated + || last_mult == CaptureMultiplicity::Repeated + { + CaptureMultiplicity::Repeated + } else if parent_mult == CaptureMultiplicity::Optional + || last_mult == CaptureMultiplicity::Optional + { + CaptureMultiplicity::Optional + } else { + CaptureMultiplicity::Single + }; + captures.push(CaptureInfo { + name: name.to_string(), + multiplicity: mult, + }); + } + last_mult = CaptureMultiplicity::Single; + } + TokenTree::Punct(p) if matches!(p.as_char(), '*' | '+' | '?') => { + // Keep last_mult — the @capture follows + } + _ => { + last_mult = CaptureMultiplicity::Single; + } + } + } +} + +/// Parse `rule!( query => transform )`. +pub fn parse_rule_top(input: TokenStream) -> Result { + let mut tokens = input.into_iter().peekable(); + + // Collect query tokens up to `=>` + let mut query_tokens = Vec::new(); + loop { + match tokens.peek() { + None => return Err(syn::Error::new(Span::call_site(), "expected `=>` in rule!")), + Some(TokenTree::Punct(p)) if p.as_char() == '=' => { + let eq = tokens.next().unwrap(); + match tokens.peek() { + Some(TokenTree::Punct(p)) if p.as_char() == '>' => { + tokens.next(); // consume > + break; + } + _ => { + query_tokens.push(eq); + continue; + } + } + } + _ => { + query_tokens.push(tokens.next().unwrap()); + } + } + } + + let query_stream: TokenStream = query_tokens.into_iter().collect(); + + // Extract captures from query + let captures = extract_captures(&query_stream); + + // Parse query + let query_code = parse_query_top(query_stream.clone())?; + + // Generate capture bindings + let ctx_ident = Ident::new(IMPLICIT_CTX, Span::call_site()); + let bindings: Vec = captures + .iter() + .map(|cap| { + let name = Ident::new(&cap.name, Span::call_site()); + let name_str = &cap.name; + match cap.multiplicity { + CaptureMultiplicity::Repeated => { + quote! { let #name: Vec = __captures.get_all(#name_str); } + } + CaptureMultiplicity::Optional => { + quote! { let #name: Option = __captures.get_opt(#name_str); } + } + CaptureMultiplicity::Single => { + quote! { let #name: usize = __captures.get_var(#name_str).unwrap(); } + } + } + }) + .collect(); + + // Parse transform: either shorthand `=> kind_name` or full `=> (template ...)` + let transform_body = if peek_is_field(&mut tokens) && { + // Shorthand form: bare identifier = output node kind. + // Auto-generate template from captures. + let mut lookahead = tokens.clone(); + lookahead.next(); // skip ident + lookahead.peek().is_none() // nothing after = shorthand + } { + let output_kind = expect_ident(&mut tokens, "expected output node kind")?; + let output_kind_str = output_kind.to_string(); + + // Generate field assignments from captures + let field_stmts: Vec = captures + .iter() + .map(|cap| { + let name = Ident::new(&cap.name, Span::call_site()); + let name_str = &cap.name; + match cap.multiplicity { + 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); + }, + 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); + } + }, + 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); + }, + } + }) + .collect(); + + quote! { + let __kind = #ctx_ident.ast.id_for_node_kind(#output_kind_str) + .unwrap_or_else(|| panic!("node kind '{}' not found", #output_kind_str)); + let mut __fields = std::collections::BTreeMap::new(); + #(#field_stmts)* + let __id = #ctx_ident.ast.create_node_with_range( + __kind, + yeast::NodeContent::DynamicString(String::new()), + __fields, + true, + __source_range, + ); + vec![__id] + } + } else { + // Full template form + let transform_items = parse_direct_list(&mut tokens, &ctx_ident)?; + + if let Some(tok) = tokens.next() { + return Err(syn::Error::new_spanned( + tok, + "unexpected token after rule! transform", + )); + } + + quote! { + let mut __nodes: Vec = Vec::new(); + #(#transform_items)* + __nodes + } + }; + + Ok(quote! { + { + let __query = #query_code; + yeast::Rule::new(__query, Box::new(|__ast: &mut yeast::Ast, __captures: yeast::captures::Captures, __fresh: &yeast::tree_builder::FreshScope, __source_range: Option| { + #(#bindings)* + let mut #ctx_ident = yeast::build::BuildCtx::with_source_range(__ast, &__captures, __fresh, __source_range); + #transform_body + })) + } + }) +} + +// --------------------------------------------------------------------------- +// Token utilities +// --------------------------------------------------------------------------- + +fn peek_is_at(tokens: &mut Tokens) -> bool { + matches!(tokens.peek(), Some(TokenTree::Punct(p)) if p.as_char() == '@') +} + +fn peek_is_literal(tokens: &mut Tokens) -> bool { + matches!(tokens.peek(), Some(TokenTree::Literal(_))) +} + +fn peek_is_dollar(tokens: &mut Tokens) -> bool { + matches!(tokens.peek(), Some(TokenTree::Punct(p)) if p.as_char() == '$') +} + +fn peek_is_hash(tokens: &mut Tokens) -> bool { + matches!(tokens.peek(), Some(TokenTree::Punct(p)) if p.as_char() == '#') +} + +/// Check for `..` (two consecutive dot punctuation tokens). +fn peek_is_dotdot(tokens: &Tokens) -> bool { + let mut lookahead = tokens.clone(); + matches!(lookahead.next(), Some(TokenTree::Punct(p)) if p.as_char() == '.') + && matches!(lookahead.next(), Some(TokenTree::Punct(p)) if p.as_char() == '.') +} + +fn peek_is_underscore(tokens: &mut Tokens) -> bool { + matches!(tokens.peek(), Some(TokenTree::Ident(id)) if *id == "_") +} + +/// Check if the next tokens form a field specification (ident followed by `:` or `*:`). +/// A bare identifier (other than `_`) at this position is always a field name, since +/// bare child patterns must start with `(`, `@`, `"literal"`, or `_`. +fn peek_is_field(tokens: &mut Tokens) -> bool { + matches!(tokens.peek(), Some(TokenTree::Ident(id)) if *id != "_") +} + +fn peek_is_group(tokens: &mut Tokens, delim: Delimiter) -> bool { + matches!(tokens.peek(), Some(TokenTree::Group(g)) if g.delimiter() == delim) +} + +fn peek_is_repetition(tokens: &mut Tokens) -> bool { + matches!(tokens.peek(), Some(TokenTree::Punct(p)) if matches!(p.as_char(), '*' | '+' | '?')) +} + +fn expect_ident(tokens: &mut Tokens, msg: &str) -> Result { + match tokens.next() { + Some(TokenTree::Ident(id)) => Ok(id), + Some(tok) => Err(syn::Error::new_spanned(tok, msg)), + None => Err(syn::Error::new(Span::call_site(), msg)), + } +} + +fn expect_literal(tokens: &mut Tokens) -> Result { + match tokens.next() { + Some(TokenTree::Literal(lit)) => Ok(lit), + Some(tok) => Err(syn::Error::new_spanned(tok, "expected string literal")), + None => Err(syn::Error::new( + Span::call_site(), + "expected string literal", + )), + } +} + +fn expect_punct(tokens: &mut Tokens, ch: char, msg: &str) -> Result<()> { + match tokens.next() { + Some(TokenTree::Punct(p)) if p.as_char() == ch => Ok(()), + Some(tok) => Err(syn::Error::new_spanned(tok, msg)), + None => Err(syn::Error::new(Span::call_site(), msg)), + } +} + +fn expect_group(tokens: &mut Tokens, delim: Delimiter) -> Result { + match tokens.next() { + Some(TokenTree::Group(g)) if g.delimiter() == delim => Ok(g), + Some(tok) => Err(syn::Error::new_spanned( + tok, + format!("expected {delim:?} group"), + )), + None => Err(syn::Error::new( + Span::call_site(), + format!("expected {delim:?} group"), + )), + } +} + +fn expect_repetition(tokens: &mut Tokens) -> Result { + match tokens.next() { + Some(TokenTree::Punct(p)) => match p.as_char() { + '*' => Ok(quote! { yeast::query::Rep::ZeroOrMore }), + '+' => Ok(quote! { yeast::query::Rep::OneOrMore }), + '?' => Ok(quote! { yeast::query::Rep::ZeroOrOne }), + _ => Err(syn::Error::new(p.span(), "expected `*`, `+`, or `?`")), + }, + Some(tok) => Err(syn::Error::new_spanned( + tok, + "expected repetition quantifier", + )), + None => Err(syn::Error::new( + Span::call_site(), + "expected repetition quantifier", + )), + } +} + +fn maybe_wrap_capture(tokens: &mut Tokens, base: TokenStream) -> Result { + if peek_is_at(tokens) { + tokens.next(); // consume @ + let name = expect_ident(tokens, "expected capture name after @")?; + let name_str = name.to_string(); + Ok(quote! { + yeast::query::QueryNode::Capture { + capture: #name_str, + node: Box::new(#base), + } + }) + } else { + Ok(base) + } +} + +fn maybe_wrap_repetition(tokens: &mut Tokens, single: TokenStream) -> Result { + if peek_is_repetition(tokens) { + let rep = expect_repetition(tokens)?; + Ok(quote! { + yeast::query::QueryListElem::Repeated { + children: vec![#single], + rep: #rep, + } + }) + } else { + Ok(single) + } +} + +/// If `@name` follows a Repeated list element, wrap each child SingleNode +/// inside the repetition with a Capture. This matches tree-sitter semantics +/// where `(_)* @name` captures each matched node. +fn maybe_wrap_list_capture(tokens: &mut Tokens, elem: TokenStream) -> Result { + if peek_is_at(tokens) { + tokens.next(); + let name = expect_ident(tokens, "expected capture name after @")?; + let name_str = name.to_string(); + // Re-parse the element isn't practical, so we generate a wrapper + // that creates a new Repeated with each child wrapped in a capture. + // The simplest approach: generate code that the runtime can interpret. + // Actually, the capture annotation on repeated elements is best handled + // by re-generating the Repeated with captures injected. + // For now, assume the common case: the repetition contains a single + // SingleNode child, and we wrap that node in a capture. + Ok(quote! { + { + let __rep = #elem; + match __rep { + yeast::query::QueryListElem::Repeated { children, rep } => { + yeast::query::QueryListElem::Repeated { + children: children.into_iter().map(|child| { + match child { + yeast::query::QueryListElem::SingleNode(node) => { + yeast::query::QueryListElem::SingleNode( + yeast::query::QueryNode::Capture { + capture: #name_str, + node: Box::new(node), + } + ) + } + other => other, + } + }).collect(), + rep, + } + } + other => other, + } + } + }) + } else { + Ok(elem) + } +} diff --git a/shared/yeast/Cargo.toml b/shared/yeast/Cargo.toml new file mode 100644 index 00000000000..166887c324c --- /dev/null +++ b/shared/yeast/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "yeast" +version = "0.1.0" +edition = "2021" + +[dependencies] +clap = { version = "4.4.10", features = ["derive"] } +serde = { version = "1.0.193", features = ["derive"] } +serde_json = "1.0.108" +serde_yaml = "0.9" +tree-sitter = ">= 0.23.0" +yeast-macros = { path = "../yeast-macros" } + +tree-sitter-ruby = "0.23" +tree-sitter-python = "0.23" diff --git a/shared/yeast/src/bin/main.rs b/shared/yeast/src/bin/main.rs new file mode 100644 index 00000000000..975c8e8b25f --- /dev/null +++ b/shared/yeast/src/bin/main.rs @@ -0,0 +1,26 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(name = "yeast", about = "yeast elaborates abstract syntax trees")] +struct Cli { + file: String, + #[clap(default_value = "ruby")] + language: String, +} + +fn get_language(language: &str) -> tree_sitter::Language { + match language { + "ruby" => tree_sitter_ruby::LANGUAGE.into(), + "python" => tree_sitter_python::LANGUAGE.into(), + _ => panic!("Unsupported language: {language}"), + } +} + +fn main() { + let args = Cli::parse(); + let language = get_language(&args.language); + let source = std::fs::read_to_string(&args.file).unwrap(); + let runner = yeast::Runner::new(language, &[]); + let ast = runner.run(&source).unwrap(); + println!("{}", ast.print(&source, ast.get_root())); +} diff --git a/shared/yeast/src/build.rs b/shared/yeast/src/build.rs new file mode 100644 index 00000000000..bee4c4f7d03 --- /dev/null +++ b/shared/yeast/src/build.rs @@ -0,0 +1,91 @@ +use std::collections::BTreeMap; + +use crate::captures::Captures; +use crate::tree_builder::FreshScope; +use crate::{Ast, FieldId, Id, NodeContent}; + +/// Context for building new AST nodes during a transformation. +/// +/// Used by the `tree!` and `trees!` macros. Holds a mutable reference to the +/// AST, a reference to the captures from a query match, and a `FreshScope` for +/// generating unique identifiers. +pub struct BuildCtx<'a> { + pub ast: &'a mut Ast, + pub captures: &'a Captures, + pub fresh: &'a FreshScope, + /// Source range of the matched node, inherited by synthetic nodes. + pub source_range: Option, +} + +impl<'a> BuildCtx<'a> { + pub fn new(ast: &'a mut Ast, captures: &'a Captures, fresh: &'a FreshScope) -> Self { + Self { + ast, + captures, + fresh, + source_range: None, + } + } + + pub fn with_source_range( + ast: &'a mut Ast, + captures: &'a Captures, + fresh: &'a FreshScope, + source_range: Option, + ) -> Self { + Self { + ast, + captures, + fresh, + source_range, + } + } + + /// Look up a capture variable, returning its node Id. + pub fn capture(&self, name: &str) -> Id { + self.captures + .get_var(name) + .unwrap_or_else(|e| panic!("build: {e}")) + } + + /// Get all values of a repeated capture variable. + pub fn capture_all(&self, name: &str) -> Vec { + self.captures.get_all(name) + } + + /// Create a named AST node with the given kind and fields. + pub fn node(&mut self, kind: &str, fields: Vec<(&str, Vec)>) -> Id { + let kind_id = self + .ast + .id_for_node_kind(kind) + .unwrap_or_else(|| panic!("build: node kind '{kind}' not found")); + let mut field_map: BTreeMap> = BTreeMap::new(); + for (name, ids) in fields { + let field_id = self + .ast + .field_id_for_name(name) + .unwrap_or_else(|| panic!("build: field '{name}' not found")); + field_map.entry(field_id).or_default().extend(ids); + } + self.ast.create_node_with_range( + kind_id, + NodeContent::DynamicString(String::new()), + field_map, + true, + self.source_range, + ) + } + + /// Create a leaf node with a fixed string content. + pub fn literal(&mut self, kind: &'static str, value: &str) -> Id { + self.ast + .create_named_token_with_range(kind, value.to_string(), self.source_range) + } + + /// Create a leaf node with an auto-generated unique name. + pub fn fresh(&mut self, kind: &'static str, name: &str) -> Id { + let generated = self.fresh.resolve(name); + self.ast + .create_named_token_with_range(kind, generated, self.source_range) + } +} diff --git a/shared/yeast/src/captures.rs b/shared/yeast/src/captures.rs new file mode 100644 index 00000000000..a92c5096e94 --- /dev/null +++ b/shared/yeast/src/captures.rs @@ -0,0 +1,105 @@ +use std::collections::{BTreeMap, BTreeSet}; + +use crate::Id; + +#[derive(Debug, Clone)] +pub struct Captures { + captures: BTreeMap<&'static str, Vec>, +} + +impl Default for Captures { + fn default() -> Self { + Self::new() + } +} + +impl Captures { + pub fn new() -> Self { + Captures { + captures: BTreeMap::new(), + } + } + + pub fn get_var(&self, key: &str) -> Result { + let ids = self.captures.get(key); + if let Some(ids) = ids { + if ids.len() == 1 { + Ok(ids[0]) + } else { + Err(format!( + "Variable {} has {} matches, use * to allow repetition", + key, + ids.len() + )) + } + } else { + Err(format!("No variable named {key}")) + } + } + + /// Get all values of a capture variable (for repeated captures). + pub fn get_all(&self, key: &str) -> Vec { + self.captures.get(key).cloned().unwrap_or_default() + } + + /// Get an optional capture variable. Returns None if unmatched, + /// Some(id) if matched exactly once. + pub fn get_opt(&self, key: &str) -> Option { + self.captures + .get(key) + .and_then(|ids| if ids.len() == 1 { Some(ids[0]) } else { None }) + } + + pub fn insert(&mut self, key: &'static str, id: Id) { + self.captures.entry(key).or_default().push(id); + } + + pub fn map_captures(&mut self, kind: &str, f: &mut impl FnMut(Id) -> Id) { + if let Some(ids) = self.captures.get_mut(kind) { + for id in ids { + *id = f(*id); + } + } + } + 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(); + self.captures.insert(to, new_values); + } + } + + pub fn merge(&mut self, other: &Captures) { + for (key, ids) in &other.captures { + self.captures.entry(key).or_default().extend(ids); + } + } + + pub fn un_star<'a>( + &'a self, + children: &'a BTreeSet<&'static str>, + ) -> Result + 'a, String> { + let mut id_iter = children.iter(); + + if let Some(fst) = id_iter.next() { + let repeats = self + .captures + .get(fst) + .ok_or_else(|| format!("No variable named {fst}"))? + .len(); + // TODO: better error on missing capture + if id_iter.any(|id| self.captures.get(id).map(Vec::len).unwrap_or(0) != repeats) { + return Err("Repeated captures must have the same number of matches".to_string()); + } + Ok((0..repeats).map(move |iter| { + let mut new_vars: Captures = Captures::new(); + for id in children { + let child_capture = self.captures.get(id).unwrap()[iter]; + new_vars.captures.insert(id, vec![child_capture]); + } + new_vars + })) + } else { + Err("Repeated captures must have at least one capture".to_string()) + } + } +} diff --git a/shared/yeast/src/cursor.rs b/shared/yeast/src/cursor.rs new file mode 100644 index 00000000000..ef5f6d94f25 --- /dev/null +++ b/shared/yeast/src/cursor.rs @@ -0,0 +1,8 @@ +pub trait Cursor<'a, T, N, F> { + fn node(&self) -> &'a N; + fn field_id(&self) -> Option; + fn field_name(&self) -> Option<&'static str>; + fn goto_first_child(&mut self) -> bool; + fn goto_next_sibling(&mut self) -> bool; + fn goto_parent(&mut self) -> bool; +} diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs new file mode 100644 index 00000000000..46629e19840 --- /dev/null +++ b/shared/yeast/src/lib.rs @@ -0,0 +1,727 @@ +use std::collections::BTreeMap; + +extern crate self as yeast; + +use serde::Serialize; +use serde_json::{json, Value}; + +pub mod build; +pub mod captures; +pub mod cursor; +pub mod dump; +pub mod node_types_yaml; +pub mod query; +mod range; +pub mod schema; +pub mod tree_builder; +mod visitor; + +pub use yeast_macros::{query, rule, tree, trees}; + +use captures::Captures; +pub use cursor::Cursor; +use query::QueryNode; + +/// Node ids are indexes into the arena +type Id = usize; + +/// Field and Kind ids are provided by tree-sitter +type FieldId = u16; +type KindId = u16; + +pub const CHILD_FIELD: u16 = u16::MAX; + +#[derive(Debug)] +pub struct AstCursor<'a> { + ast: &'a Ast, + /// A stack of parents, along with iterators for their children + parents: Vec<(&'a Node, ChildrenIter<'a>)>, + node: &'a Node, +} + +impl<'a> AstCursor<'a> { + pub fn new(ast: &'a Ast) -> Self { + // TODO: handle non-zero root + let node = ast.get_node(ast.root).unwrap(); + Self { + ast, + parents: vec![], + node, + } + } + + fn goto_next_sibling_opt(&mut self) -> Option<()> { + self.node = self.parents.last_mut()?.1.next()?; + Some(()) + } + + fn goto_first_child_opt(&mut self) -> Option<()> { + let parent = self.node; + let mut children = ChildrenIter::new(self.ast, parent); + let first_child = children.next()?; + self.node = first_child; + self.parents.push((parent, children)); + Some(()) + } + + fn goto_parent_opt(&mut self) -> Option<()> { + self.node = self.parents.pop()?.0; + Some(()) + } +} +impl<'a> Cursor<'a, Ast, Node, FieldId> for AstCursor<'a> { + fn node(&self) -> &'a Node { + self.node + } + + fn field_id(&self) -> Option { + let (_, children) = self.parents.last()?; + children.current_field() + } + + fn field_name(&self) -> Option<&'static str> { + if self.field_id() == Some(CHILD_FIELD) { + None + } else { + self.field_id() + .and_then(|id| self.ast.field_name_for_id(id)) + } + } + + fn goto_first_child(&mut self) -> bool { + self.goto_first_child_opt().is_some() + } + + fn goto_next_sibling(&mut self) -> bool { + self.goto_next_sibling_opt().is_some() + } + + fn goto_parent(&mut self) -> bool { + self.goto_parent_opt().is_some() + } +} + +/// An iterator over all the child nodes of a node. +#[derive(Debug)] +struct ChildrenIter<'a> { + ast: &'a Ast, + current_field: Option, + fields: std::collections::btree_map::Iter<'a, FieldId, Vec>, + field_children: Option>, +} + +impl<'a> ChildrenIter<'a> { + fn new(ast: &'a Ast, node: &'a Node) -> Self { + Self { + ast, + current_field: None, + fields: node.fields.iter(), + field_children: None, + } + } + + fn get_node(&self, id: Id) -> &'a Node { + self.ast.get_node(id).unwrap() + } + + fn current_field(&self) -> Option { + self.current_field + } +} + +impl<'a> Iterator for ChildrenIter<'a> { + type Item = &'a Node; + + fn next(&mut self) -> Option { + match self.field_children.as_mut() { + None => match self.fields.next() { + Some((field, children)) => { + self.current_field = Some(*field); + self.field_children = Some(children.iter()); + self.next() + } + None => None, + }, + Some(children) => match children.next() { + None => match self.fields.next() { + None => None, + Some((field, children)) => { + self.current_field = Some(*field); + self.field_children = Some(children.iter()); + self.next() + } + }, + Some(child_id) => Some(self.get_node(*child_id)), + }, + } + } +} + +/// Our AST +pub struct Ast { + root: Id, + nodes: Vec, + schema: schema::Schema, +} + +impl std::fmt::Debug for Ast { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Ast") + .field("root", &self.root) + .field("nodes", &self.nodes.len()) + .finish() + } +} + +impl Ast { + /// Construct an AST from a TS tree + pub fn from_tree(language: tree_sitter::Language, tree: &tree_sitter::Tree) -> Self { + let schema = schema::Schema::from_language(&language); + Self::from_tree_with_schema(schema, tree, &language) + } + + pub fn from_tree_with_schema( + schema: schema::Schema, + tree: &tree_sitter::Tree, + language: &tree_sitter::Language, + ) -> Self { + let mut visitor = visitor::Visitor::new(language.clone()); + visitor.visit(tree); + + visitor.build_with_schema(schema) + } + + pub fn walk(&self) -> AstCursor { + AstCursor::new(self) + } + + pub fn nodes(&self) -> &[Node] { + &self.nodes + } + + pub fn get_root(&self) -> Id { + self.root + } + + pub fn set_root(&mut self, root: Id) { + self.root = root; + } + + pub fn get_node(&self, id: Id) -> Option<&Node> { + self.nodes.get(id) + } + + pub fn print(&self, source: &str, root_id: Id) -> Value { + let root = &self.nodes()[root_id]; + self.print_node(root, source) + } + + pub fn create_node( + &mut self, + kind: KindId, + content: NodeContent, + fields: BTreeMap>, + is_named: bool, + ) -> Id { + self.create_node_with_range(kind, content, fields, is_named, None) + } + + pub fn create_node_with_range( + &mut self, + kind: KindId, + content: NodeContent, + fields: BTreeMap>, + is_named: bool, + source_range: Option, + ) -> Id { + let id = self.nodes.len(); + self.nodes.push(Node { + id, + kind, + kind_name: self.schema.node_kind_for_id(kind).unwrap(), + fields, + content, + is_missing: false, + is_error: false, + is_extra: false, + is_named, + source_range, + }); + id + } + + pub fn create_named_token(&mut self, kind: &'static str, content: String) -> Id { + self.create_named_token_with_range(kind, content, None) + } + + pub fn create_named_token_with_range( + &mut self, + kind: &'static str, + content: String, + source_range: Option, + ) -> Id { + let kind_id = self.schema.id_for_node_kind(kind).unwrap_or_else(|| { + panic!("create_named_token: node kind '{kind}' not found in schema") + }); + let id = self.nodes.len(); + self.nodes.push(Node { + id, + kind: kind_id, + kind_name: kind, + is_named: true, + is_missing: false, + is_error: false, + source_range, + is_extra: false, + fields: BTreeMap::new(), + content: NodeContent::DynamicString(content), + }); + id + } + + pub fn field_name_for_id(&self, id: FieldId) -> Option<&'static str> { + self.schema.field_name_for_id(id) + } + + pub fn field_id_for_name(&self, name: &str) -> Option { + self.schema.field_id_for_name(name) + } + + /// Print a node for debugging + fn print_node(&self, node: &Node, source: &str) -> Value { + let fields: BTreeMap<&'static str, Vec> = node + .fields + .iter() + .map(|(field_id, nodes)| { + let field_name = if field_id == &CHILD_FIELD { + "rest" + } else { + self.field_name_for_id(*field_id).unwrap() + }; + let nodes: Vec = nodes + .iter() + .map(|id| self.print_node(self.get_node(*id).unwrap(), source)) + .collect(); + (field_name, nodes) + }) + .collect(); + let mut value = BTreeMap::new(); + let kind = self.schema.node_kind_for_id(node.kind).unwrap(); + let content = match &node.content { + NodeContent::Range(range) => source[range.start_byte..range.end_byte].to_string(), + NodeContent::String(s) => s.to_string(), + NodeContent::DynamicString(s) => s.clone(), + }; + if fields.is_empty() { + value.insert(kind, json!(content)); + } else { + let mut fields: BTreeMap<_, _> = + fields.into_iter().map(|(k, v)| (k, json!(v))).collect(); + fields.insert("content", json!(content)); + value.insert(kind, json!(fields)); + } + json!(value) + } + + pub fn id_for_node_kind(&self, kind: &str) -> Option { + let id = self.schema.id_for_node_kind(kind).unwrap_or(0); + if id == 0 { + None + } else { + Some(id) + } + } + + fn id_for_unnamed_node_kind(&self, kind: &str) -> Option { + let id = self.schema.id_for_unnamed_node_kind(kind).unwrap_or(0); + if id == 0 { + None + } else { + Some(id) + } + } +} + +/// A node in our AST +#[derive(PartialEq, Eq, Debug, Clone, Serialize)] +pub struct Node { + id: Id, + kind: KindId, + kind_name: &'static str, + pub(crate) fields: BTreeMap>, + pub(crate) content: NodeContent, + /// For synthetic nodes, the source range of the original node they + /// were desugared from. Used for location information in TRAP output. + #[serde(skip)] + source_range: Option, + is_named: bool, + is_missing: bool, + is_extra: bool, + is_error: bool, +} + +impl Node { + pub fn id(&self) -> Id { + self.id + } + + pub fn kind(&self) -> &'static str { + self.kind_name + } + + pub fn kind_name(&self) -> &'static str { + self.kind_name + } + + pub fn is_named(&self) -> bool { + self.is_named + } + + pub fn is_missing(&self) -> bool { + self.is_missing + } + + pub fn is_extra(&self) -> bool { + self.is_extra + } + + pub fn is_error(&self) -> bool { + self.is_error + } + + fn fake_point(&self) -> tree_sitter::Point { + tree_sitter::Point { row: 0, column: 0 } + } + + pub fn start_position(&self) -> tree_sitter::Point { + match self.content { + NodeContent::Range(range) => range.start_point, + _ => self + .source_range + .map_or_else(|| self.fake_point(), |r| r.start_point), + } + } + + pub fn end_position(&self) -> tree_sitter::Point { + match self.content { + NodeContent::Range(range) => range.end_point, + _ => self + .source_range + .map_or_else(|| self.fake_point(), |r| r.end_point), + } + } + + pub fn start_byte(&self) -> usize { + match self.content { + NodeContent::Range(range) => range.start_byte, + _ => self.source_range.map_or(0, |r| r.start_byte), + } + } + + pub fn end_byte(&self) -> usize { + match self.content { + NodeContent::Range(range) => range.end_byte, + _ => self.source_range.map_or(0, |r| r.end_byte), + } + } + + pub fn byte_range(&self) -> std::ops::Range { + self.start_byte()..self.end_byte() + } + + pub fn opt_string_content(&self) -> Option { + match &self.content { + NodeContent::Range(_range) => None, + NodeContent::String(s) => Some(s.to_string()), + NodeContent::DynamicString(s) => Some(s.to_string()), + } + } +} + +/// The contents of a node is either a range in the original source file, +/// or a new string if the node is synthesized. +#[derive(PartialEq, Eq, Debug, Clone, Serialize)] +pub enum NodeContent { + Range(#[serde(with = "range::Range")] tree_sitter::Range), + String(&'static str), + DynamicString(String), +} + +impl From<&'static str> for NodeContent { + fn from(value: &'static str) -> Self { + NodeContent::String(value) + } +} + +impl From for NodeContent { + fn from(value: tree_sitter::Range) -> Self { + NodeContent::Range(value) + } +} + +/// The transform function for a rule: takes the AST, captured variables, a +/// fresh-name scope, and the source range of the matched node, and returns +/// the IDs of the replacement nodes. +pub type Transform = Box< + dyn Fn(&mut Ast, Captures, &tree_builder::FreshScope, Option) -> Vec + + Send + + Sync, +>; + +pub struct Rule { + query: QueryNode, + transform: Transform, +} + +impl Rule { + pub fn new(query: QueryNode, transform: Transform) -> Self { + Self { query, transform } + } + + fn try_rule( + &self, + ast: &mut Ast, + node: Id, + fresh: &tree_builder::FreshScope, + ) -> 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))) + } else { + Ok(None) + } + } +} + +const MAX_REWRITE_DEPTH: usize = 100; + +/// Index of rules by their root query kind for fast lookup. +struct RuleIndex<'a> { + /// Rules indexed by root node kind name. + by_kind: BTreeMap<&'static str, Vec<&'a Rule>>, + /// Rules with wildcard queries (Any) that apply to all nodes. + wildcard: Vec<&'a Rule>, +} + +impl<'a> RuleIndex<'a> { + fn new(rules: &'a [Rule]) -> Self { + let mut by_kind: BTreeMap<&'static str, Vec<&'a Rule>> = BTreeMap::new(); + let mut wildcard = Vec::new(); + for rule in rules { + match rule.query.root_kind() { + Some(kind) => by_kind.entry(kind).or_default().push(rule), + None => wildcard.push(rule), + } + } + Self { by_kind, wildcard } + } + + fn rules_for_kind(&self, kind: &str) -> impl Iterator { + self.by_kind + .get(kind) + .into_iter() + .flat_map(|v| v.iter()) + .chain(self.wildcard.iter()) + } +} + +fn apply_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) +} + +fn apply_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(result_node) = rule.try_rule(ast, id, fresh)? { + let mut results = Vec::new(); + for node in result_node { + results.extend(apply_rules_inner( + index, + ast, + node, + fresh, + rewrite_depth + 1, + )?); + } + return Ok(results); + } + } + + // Collect fields before recursing (avoids borrowing ast immutably during mutation) + let field_entries: Vec<(FieldId, Vec)> = ast.nodes[id] + .fields + .iter() + .map(|(&fid, children)| (fid, children.clone())) + .collect(); + + // recursively descend into all the fields + // Child traversal does not increment rewrite depth + let mut changed = false; + let mut new_fields = BTreeMap::new(); + for (field_id, children) in field_entries { + let mut new_children = Vec::new(); + for child_id in children { + let result = apply_rules_inner(index, ast, child_id, fresh, rewrite_depth)?; + if result.len() != 1 || result[0] != child_id { + changed = true; + } + new_children.extend(result); + } + new_fields.insert(field_id, new_children); + } + + if !changed { + return Ok(vec![id]); + } + + let mut node = ast.nodes[id].clone(); + node.fields = new_fields; + node.id = ast.nodes.len(); + ast.nodes.push(node); + Ok(vec![ast.nodes.len() - 1]) +} + +/// Configuration for a desugaring pass: a set of rules and an optional +/// output node-types schema (in YAML format). +/// +/// When attached to a `LanguageSpec` (in the shared tree-sitter extractor), +/// enables yeast-based AST rewriting before TRAP extraction. The same YAML +/// is used both to validate TRAP output (via JSON conversion) and to +/// resolve output-only node kinds and fields at runtime. +pub struct DesugaringConfig { + /// Rules to apply during desugaring. + pub rules: Vec, + /// Output node-types in YAML format. If `None`, the input grammar's + /// node types are used (i.e. the desugared AST has the same node types + /// as the tree-sitter grammar). + pub output_node_types_yaml: Option<&'static str>, +} + +impl DesugaringConfig { + pub fn new(rules: Vec) -> Self { + Self { + rules, + output_node_types_yaml: None, + } + } + + pub fn with_output_node_types_yaml(mut self, yaml: &'static str) -> Self { + self.output_node_types_yaml = Some(yaml); + self + } + + /// Build the yeast `Schema` for this config, given the input language. + /// If `output_node_types_yaml` is `None`, returns the schema derived from + /// the input grammar. + pub fn build_schema(&self, language: &tree_sitter::Language) -> Result { + match self.output_node_types_yaml { + Some(yaml) => node_types_yaml::schema_from_yaml_with_language(yaml, language), + None => Ok(schema::Schema::from_language(language)), + } + } +} + +pub struct Runner<'a> { + language: tree_sitter::Language, + schema: schema::Schema, + rules: &'a [Rule], +} + +impl<'a> Runner<'a> { + /// Create a runner using the input grammar's schema for output. + pub fn new(language: tree_sitter::Language, rules: &'a [Rule]) -> Self { + let schema = schema::Schema::from_language(&language); + Self { + language, + schema, + rules, + } + } + + /// Create a runner with separate input language and output schema. + pub fn with_schema( + language: tree_sitter::Language, + schema: &schema::Schema, + rules: &'a [Rule], + ) -> Self { + Self { + language, + schema: schema.clone(), + rules, + } + } + + /// Create a runner from a [`DesugaringConfig`]. + pub fn from_config( + language: tree_sitter::Language, + config: &'a DesugaringConfig, + ) -> Result { + let schema = config.build_schema(&language)?; + Ok(Self { + language, + schema, + rules: &config.rules, + }) + } + + pub fn run_from_tree(&self, tree: &tree_sitter::Tree) -> Result { + let fresh = tree_builder::FreshScope::new(); + let mut ast = Ast::from_tree_with_schema(self.schema.clone(), tree, &self.language); + let root = ast.get_root(); + let res = apply_rules(self.rules, &mut ast, root, &fresh)?; + if res.len() != 1 { + return Err(format!( + "Expected exactly one result node, got {}", + res.len() + )); + } + ast.set_root(res[0]); + Ok(ast) + } + + pub fn run(&self, input: &str) -> Result { + let fresh = tree_builder::FreshScope::new(); + let mut parser = tree_sitter::Parser::new(); + parser + .set_language(&self.language) + .map_err(|e| format!("Failed to set language: {e}"))?; + 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 root = ast.get_root(); + let res = apply_rules(self.rules, &mut ast, root, &fresh)?; + if res.len() != 1 { + return Err(format!( + "Expected exactly one result node, got {}", + res.len() + )); + } + ast.set_root(res[0]); + Ok(ast) + } +} diff --git a/shared/yeast/src/query.rs b/shared/yeast/src/query.rs new file mode 100644 index 00000000000..223b3456919 --- /dev/null +++ b/shared/yeast/src/query.rs @@ -0,0 +1,228 @@ +use crate::{captures::Captures, Ast, Id}; + +#[derive(Debug, Clone)] +pub enum QueryNode { + Any(), + Node { + kind: &'static str, + children: Vec<(&'static str, Vec)>, + }, + UnnamedNode { + kind: &'static str, + }, + Capture { + capture: &'static str, + node: Box, + }, +} + +impl QueryNode { + /// Returns the root node kind this query matches, if it's specific. + /// Returns None for wildcards (Any) and captures wrapping wildcards. + pub fn root_kind(&self) -> Option<&'static str> { + match self { + QueryNode::Node { kind, .. } => Some(kind), + QueryNode::UnnamedNode { kind } => Some(kind), + QueryNode::Capture { node, .. } => node.root_kind(), + QueryNode::Any() => None, + } + } +} + +#[derive(Debug, Clone)] +pub enum QueryListElem { + Repeated { + children: Vec, + rep: Rep, + }, + SingleNode(QueryNode), +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub enum Rep { + ZeroOrMore, + OneOrMore, + ZeroOrOne, +} + +impl QueryNode { + /// Returns true if this query only matches named nodes (not unnamed tokens). + /// Used to skip unnamed children in positional matching, matching tree-sitter + /// semantics where `(_)` only matches named nodes. + fn matches_named_only(&self) -> bool { + match self { + QueryNode::Any() => true, + QueryNode::Node { .. } => true, + QueryNode::UnnamedNode { .. } => false, + QueryNode::Capture { node, .. } => node.matches_named_only(), + } + } + + pub fn do_match(&self, ast: &Ast, node: Id, matches: &mut Captures) -> Result { + match self { + QueryNode::Any() => Ok(true), + QueryNode::Node { kind, children } => { + let node = ast.get_node(node).unwrap(); + let target_kind = ast + .id_for_node_kind(kind) + .ok_or_else(|| format!("Node kind {kind} not found in language"))?; + if node.kind != target_kind { + return Ok(false); + } + for (field, field_children) in children { + let field_id = ast + .field_id_for_name(field) + .ok_or_else(|| format!("Field {field} not found in language"))?; + let empty = Vec::new(); + let mut child_iter = + node.fields.get(&field_id).unwrap_or(&empty).iter().cloned(); + if !match_children(field_children.iter(), ast, &mut child_iter, matches)? { + return Ok(false); + } + } + Ok(true) + } + QueryNode::UnnamedNode { kind } => { + let node = ast.get_node(node).unwrap(); + let target_kind = ast + .id_for_unnamed_node_kind(kind) + .ok_or_else(|| format!("unnamed Node kind {kind} not found in language"))?; + Ok(node.kind == target_kind) + } + QueryNode::Capture { + capture, + node: sub_query, + } => { + let matched = sub_query.do_match(ast, node, matches)?; + if matched { + matches.insert(capture, node); + } + Ok(matched) + } + } + } +} + +fn match_children<'a>( + child_matchers: impl Iterator, + ast: &Ast, + remaining_children: &mut (impl Iterator + Clone), + matches: &mut Captures, +) -> Result { + for child in child_matchers { + if !child.do_match(ast, remaining_children, matches)? { + return Ok(false); + } + } + Ok(true) +} + +impl QueryListElem { + fn do_match( + &self, + ast: &Ast, + remaining_children: &mut (impl Iterator + Clone), + matches: &mut Captures, + ) -> Result { + match self { + QueryListElem::Repeated { children, rep } => { + if children.is_empty() { + // Empty repetition always succeeds without consuming + return Ok(*rep != Rep::OneOrMore); + } + + let mut iters = 0; + + loop { + let matches_initial = matches.clone(); + let start = remaining_children.clone(); + let start_next = start.clone().next(); + if !match_children(children.iter(), ast, remaining_children, matches)? { + *remaining_children = start; + *matches = matches_initial; + break; + } + // Guard against zero-width matches: if the iterator + // didn't advance, break to avoid infinite looping. + let current_next = remaining_children.clone().next(); + if start_next == current_next { + break; + } + iters += 1; + if *rep == Rep::ZeroOrOne { + break; + } + } + if *rep == Rep::OneOrMore && iters == 0 { + // We didn't match any children but we were supposed to + Ok(false) + } else { + Ok(true) + } + } + QueryListElem::SingleNode(sub_query) => { + if sub_query.matches_named_only() { + // Skip unnamed children, matching tree-sitter semantics + // where (_) only matches named nodes. + loop { + match remaining_children.next() { + Some(child) => { + let node = ast.get_node(child).unwrap(); + if node.is_named() { + return sub_query.do_match(ast, child, matches); + } + // Skip unnamed child, continue to next + } + None => return Ok(false), + } + } + } else if let Some(child) = remaining_children.next() { + sub_query.do_match(ast, child, matches) + } else { + Ok(false) + } + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::query::*; + #[test] + fn it_works() { + let query1: QueryNode = yeast::query!((_)); + println!("{query1:?}"); + let query2 = yeast::query!((foo)); + println!("{query2:?}"); + let query3 = yeast::query!((foo child: (_))); + println!("{query3:?}"); + let query4 = yeast::query!((foo (_)*)); + println!("{query4:?}"); + let query5: QueryNode = yeast::query!((foo (_)*)); + println!("{query5:?}"); + let query6: QueryNode = yeast::query!((_) @bar); + println!("{query6:?}"); + let query7: QueryNode = yeast::query!((foo child: (_) @bar)); + println!("{query7:?}"); + let query8: QueryNode = yeast::query!( + (assignment + left: (element_reference + object: (_) @obj + (_) @index + ) + right: (_) @rhs + ) + ); + println!("{query8:?}"); + let query9 = yeast::query!( + (program + child: (assignment + left: (_) @left + right: (_) @right + ) + ) + ); + println!("{query9:?}"); + } +} diff --git a/shared/yeast/src/range.rs b/shared/yeast/src/range.rs new file mode 100644 index 00000000000..ec670b438d5 --- /dev/null +++ b/shared/yeast/src/range.rs @@ -0,0 +1,21 @@ +//! (de)-serialize helpers for tree_sitter::Range + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +#[serde(remote = "tree_sitter::Point")] +pub struct Point { + pub row: usize, + pub column: usize, +} + +#[derive(Serialize, Deserialize)] +#[serde(remote = "tree_sitter::Range")] +pub struct Range { + pub start_byte: usize, + pub end_byte: usize, + #[serde(with = "Point")] + pub start_point: tree_sitter::Point, + #[serde(with = "Point")] + pub end_point: tree_sitter::Point, +} diff --git a/shared/yeast/src/schema.rs b/shared/yeast/src/schema.rs new file mode 100644 index 00000000000..0a33fd6e0ed --- /dev/null +++ b/shared/yeast/src/schema.rs @@ -0,0 +1,167 @@ +use std::collections::BTreeMap; + +use crate::{FieldId, KindId, CHILD_FIELD}; + +/// 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. +/// +/// # Memory management +/// +/// `register_field`/`register_kind`/`register_unnamed_kind` use `Box::leak` +/// to obtain `&'static str` names. This is intentional: the `&'static str` +/// names appear pervasively in `Node`, `AstCursor`, query patterns, and the +/// extractor's TRAP output, where adding a lifetime would propagate widely. +/// +/// The leak is bounded by the number of distinct kind/field names registered. +/// Schemas are expected to be constructed once per process (e.g. at extractor +/// startup) and reused. Repeated construction in long-running processes will +/// leak memory unboundedly and should be avoided. +#[derive(Clone)] +pub struct Schema { + field_ids: BTreeMap, + field_names: BTreeMap, + next_field_id: FieldId, + kind_ids: BTreeMap, + unnamed_kind_ids: BTreeMap, + kind_names: BTreeMap, + next_kind_id: KindId, +} + +impl Default for Schema { + fn default() -> Self { + Self::new() + } +} + +impl Schema { + pub fn new() -> Self { + Self { + field_ids: BTreeMap::new(), + field_names: BTreeMap::new(), + next_field_id: 1, // 0 is reserved + kind_ids: BTreeMap::new(), + unnamed_kind_ids: BTreeMap::new(), + kind_names: BTreeMap::new(), + next_kind_id: 1, // 0 is reserved + } + } + + /// Create a schema from a tree-sitter language, importing all its + /// known field and kind names. + pub fn from_language(language: &tree_sitter::Language) -> Self { + let mut schema = Self::new(); + // Import all field names, preserving tree-sitter's IDs + for id in 1..=language.field_count() as u16 { + if let Some(name) = language.field_name_for_id(id) { + schema.field_ids.insert(name.to_string(), id); + schema.field_names.insert(id, name); + if id >= schema.next_field_id { + schema.next_field_id = id + 1; + } + } + } + // Import all node kind names, preserving tree-sitter's IDs. + // Track named and unnamed variants separately. + // For named kinds, use the canonical ID from id_for_node_kind(name, true) + // since some languages have multiple IDs for the same named kind. + for id in 0..language.node_kind_count() as u16 { + if let Some(name) = language.node_kind_for_id(id) { + if !name.is_empty() { + let is_named = language.node_kind_is_named(id); + if is_named { + let canonical_id = language.id_for_node_kind(name, true); + if canonical_id != 0 && !schema.kind_ids.contains_key(name) { + schema.kind_ids.insert(name.to_string(), canonical_id); + schema.kind_names.insert(canonical_id, name); + } + } else { + // For unnamed kinds, only insert if we don't already have one + // (some languages have multiple unnamed IDs for the same text) + schema + .unnamed_kind_ids + .entry(name.to_string()) + .or_insert(id); + } + // Always track the name for any ID we encounter + schema.kind_names.entry(id).or_insert(name); + if id >= schema.next_kind_id { + schema.next_kind_id = id + 1; + } + } + } + } + schema + } + + /// Register a field name, returning its ID. + /// If already registered, returns the existing ID. + pub fn register_field(&mut self, name: &str) -> FieldId { + if name == "child" { + return CHILD_FIELD; + } + if let Some(&id) = self.field_ids.get(name) { + return id; + } + let id = self.next_field_id; + assert!(id < CHILD_FIELD, "too many fields"); + self.next_field_id += 1; + let leaked: &'static str = Box::leak(name.to_string().into_boxed_str()); + self.field_ids.insert(name.to_string(), id); + self.field_names.insert(id, leaked); + id + } + + /// Register a named node kind name, returning its ID. + /// If already registered, returns the existing ID. + pub fn register_kind(&mut self, name: &str) -> KindId { + if let Some(&id) = self.kind_ids.get(name) { + return id; + } + let id = self.next_kind_id; + self.next_kind_id += 1; + let leaked: &'static str = Box::leak(name.to_string().into_boxed_str()); + self.kind_ids.insert(name.to_string(), id); + self.kind_names.insert(id, leaked); + id + } + + /// Register an unnamed token kind (e.g. `"="`, `"end"`), returning its ID. + /// If already registered, returns the existing ID. + pub fn register_unnamed_kind(&mut self, name: &str) -> KindId { + if let Some(&id) = self.unnamed_kind_ids.get(name) { + return id; + } + let id = self.next_kind_id; + self.next_kind_id += 1; + let leaked: &'static str = Box::leak(name.to_string().into_boxed_str()); + self.unnamed_kind_ids.insert(name.to_string(), id); + self.kind_names.insert(id, leaked); + id + } + + pub fn field_id_for_name(&self, name: &str) -> Option { + if name == "child" { + return Some(CHILD_FIELD); + } + self.field_ids.get(name).copied() + } + + pub fn field_name_for_id(&self, id: FieldId) -> Option<&'static str> { + if id == CHILD_FIELD { + return Some("child"); + } + self.field_names.get(&id).copied() + } + + pub fn id_for_node_kind(&self, kind: &str) -> Option { + self.kind_ids.get(kind).copied() + } + + pub fn id_for_unnamed_node_kind(&self, kind: &str) -> Option { + self.unnamed_kind_ids.get(kind).copied() + } + + pub fn node_kind_for_id(&self, id: KindId) -> Option<&'static str> { + self.kind_names.get(&id).copied() + } +} diff --git a/shared/yeast/src/tree_builder.rs b/shared/yeast/src/tree_builder.rs new file mode 100644 index 00000000000..c735c272d28 --- /dev/null +++ b/shared/yeast/src/tree_builder.rs @@ -0,0 +1,43 @@ +use std::cell::Cell; +use std::collections::BTreeMap; + +/// Tracks fresh identifier generation during a single tree-building operation. +/// All occurrences of the same `$name` within one build share the same generated value. +pub struct FreshScope { + counter: Cell, + resolved: std::cell::RefCell>, +} + +impl Default for FreshScope { + fn default() -> Self { + Self::new() + } +} + +impl FreshScope { + pub fn new() -> Self { + Self { + counter: Cell::new(0), + resolved: std::cell::RefCell::new(BTreeMap::new()), + } + } + + pub fn resolve(&self, name: &str) -> String { + self.resolved + .borrow_mut() + .entry(name.to_string()) + .or_insert_with(|| { + let id = self.counter.get(); + self.counter.set(id + 1); + format!("${name}-{id}") + }) + .clone() + } + + /// Clear resolved names but keep the counter. Called between rule + /// applications so that `$tmp` in different rules gets different values + /// while the counter increases monotonically. + pub fn next_scope(&self) { + self.resolved.borrow_mut().clear(); + } +} diff --git a/shared/yeast/src/visitor.rs b/shared/yeast/src/visitor.rs new file mode 100644 index 00000000000..655aa01e6b3 --- /dev/null +++ b/shared/yeast/src/visitor.rs @@ -0,0 +1,111 @@ +use std::collections::BTreeMap; +use tree_sitter::{Language, Tree}; + +use crate::{Ast, Id, Node, NodeContent, CHILD_FIELD}; + +#[derive(Debug)] +struct VisitorNode { + inner: Node, + parent: Option, +} + +/// A type that can walk a TS tree and produce an `Ast`. +#[derive(Debug)] +pub(crate) struct Visitor { + nodes: Vec, + current: Option, + language: Language, +} + +impl Visitor { + pub fn new(language: Language) -> Self { + Self { + nodes: Vec::new(), + current: None, + language, + } + } + + pub fn visit(&mut self, tree: &Tree) { + let cursor = &mut tree.walk(); + self.enter_node(cursor.node()); + let mut recurse = true; + loop { + if recurse && cursor.goto_first_child() { + recurse = self.enter_node(cursor.node()); + } else { + self.leave_node(cursor.field_name(), cursor.node()); + + if cursor.goto_next_sibling() { + recurse = self.enter_node(cursor.node()); + } else if cursor.goto_parent() { + recurse = false; + } else { + break; + } + } + } + } + + pub fn build_with_schema(self, schema: crate::schema::Schema) -> Ast { + Ast { + root: self.nodes[0].inner.id, + schema, + nodes: self.nodes.into_iter().map(|n| n.inner).collect(), + } + } + + fn add_node(&mut self, n: tree_sitter::Node<'_>, content: NodeContent, is_named: bool) -> Id { + let id = self.nodes.len(); + self.nodes.push(VisitorNode { + inner: Node { + id, + kind: self.language.id_for_node_kind(n.kind(), is_named), + kind_name: n.kind(), + content, + fields: BTreeMap::new(), + is_missing: n.is_missing(), + is_named: n.is_named(), + is_extra: n.is_extra(), + is_error: n.is_error(), + source_range: None, + }, + parent: self.current, + }); + id + } + + fn enter_node(&mut self, node: tree_sitter::Node<'_>) -> bool { + let id = self.add_node(node, node.range().into(), node.is_named()); + self.current = Some(id); + true + } + + fn leave_node(&mut self, field_name: Option<&'static str>, _node: tree_sitter::Node<'_>) { + let node = self.current.map(|i| &self.nodes[i]).unwrap(); + let node_id = node.inner.id; + let node_parent = node.parent; + + if let Some(parent_id) = node.parent { + let parent = self.nodes.get_mut(parent_id).unwrap(); + if let Some(field) = field_name { + let field_id = self.language.field_id_for_name(field).unwrap().get(); + parent + .inner + .fields + .entry(field_id) + .or_default() + .push(node_id); + } else { + parent + .inner + .fields + .entry(CHILD_FIELD) + .or_default() + .push(node_id); + } + } + + self.current = node_parent; + } +} From 8a9e53cc58041e34f844c00391421bc962de405e Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 4 May 2026 13:13:27 +0000 Subject: [PATCH 16/43] yeast: Add YAML node-types format and converter Human-friendly YAML alternative to tree-sitter node-types.json with three sections: supertypes, named, unnamed. Supports bidirectional conversion and building Schema objects from YAML. Includes CLI binary (node_types_yaml) and documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shared/yeast/doc/node-types-yaml.md | 241 ++++++++ shared/yeast/src/bin/node_types_yaml.rs | 51 ++ shared/yeast/src/node_types_yaml.rs | 722 ++++++++++++++++++++++++ 3 files changed, 1014 insertions(+) create mode 100644 shared/yeast/doc/node-types-yaml.md create mode 100644 shared/yeast/src/bin/node_types_yaml.rs create mode 100644 shared/yeast/src/node_types_yaml.rs diff --git a/shared/yeast/doc/node-types-yaml.md b/shared/yeast/doc/node-types-yaml.md new file mode 100644 index 00000000000..b887f5a82bb --- /dev/null +++ b/shared/yeast/doc/node-types-yaml.md @@ -0,0 +1,241 @@ +# YAML Node Types Format + +The YAML node-types format is a human-friendly alternative to tree-sitter's +`node-types.json`. It can be converted to and from JSON using the +`node_types_yaml` tool. + +## Overview + +A YAML node-types file has three top-level sections: + +```yaml +supertypes: + # Abstract union types + +named: + # Concrete AST nodes and leaf tokens + +unnamed: + # Punctuation and keyword tokens +``` + +All three sections are optional. If omitted, they default to empty. + +## Supertypes + +Supertypes are abstract groupings of node types (unions). Each supertype maps +to a list of its members: + +```yaml +supertypes: + _expression: + - assignment + - binary + - identifier + - call +``` + +This corresponds to the following JSON: + +```json +{ + "type": "_expression", + "named": true, + "subtypes": [ + { "type": "assignment", "named": true }, + { "type": "binary", "named": true }, + { "type": "identifier", "named": true }, + { "type": "call", "named": true } + ] +} +``` + +Members are resolved as named or unnamed using the +[type reference rules](#type-references) described below. + +## Named nodes + +Named nodes are concrete AST node types. Each entry is a node kind mapping to +its fields. A node with no fields (a leaf token like `identifier`) uses an +empty value: + +```yaml +named: + identifier: + constant: +``` + +```json +{"type": "identifier", "named": true, "fields": {}}, +{"type": "constant", "named": true, "fields": {}} +``` + +### Fields + +Each field has a name, a multiplicity suffix, and a list of allowed types. + +| Suffix | Meaning | JSON `multiple` | JSON `required` | +| ------ | ------------ | --------------- | --------------- | +| (none) | exactly one | `false` | `true` | +| `?` | zero or one | `false` | `false` | +| `+` | one or more | `true` | `true` | +| `*` | zero or more | `true` | `false` | + +Example: + +```yaml +named: + assignment: + left: _lhs + right: _expression +``` + +```json +{ + "type": "assignment", + "named": true, + "fields": { + "left": { + "multiple": false, + "required": true, + "types": [{ "type": "_lhs", "named": true }] + }, + "right": { + "multiple": false, + "required": true, + "types": [{ "type": "_expression", "named": true }] + } + } +} +``` + +A field with multiple allowed types uses a list: + +```yaml +named: + binary: + left: [_expression, _simple_numeric] + operator: ["!=", "+", "&&"] + right: _expression +``` + +A singleton list can be written as a bare value (as shown with `right` above). + +### Unnamed children + +Unnamed children (nodes that appear as children without a field name) are +specified using the special `$children` field name, with the same suffixes: + +```yaml +named: + argument_list: + $children*: [_expression, block_argument, splat_argument] +``` + +```json +{ + "type": "argument_list", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": false, + "types": [ + { "type": "_expression", "named": true }, + { "type": "block_argument", "named": true }, + { "type": "splat_argument", "named": true } + ] + } +} +``` + +## Unnamed tokens + +Unnamed tokens are punctuation, operators, and keywords that appear in the +parse tree but don't have their own AST node type. They are listed as simple +strings: + +```yaml +unnamed: + - "=" + - "end" + - "+" + - "&&" +``` + +```json +{"type": "=", "named": false}, +{"type": "end", "named": false}, +{"type": "+", "named": false}, +{"type": "&&", "named": false} +``` + +When converting to YAML, unnamed tokens are always wrapped in quotes for +visual clarity. This is purely cosmetic — YAML treats `end` and `"end"` as +the same string. + +## Type references + +When a type name appears in a field's type list or a supertype's member list, +it needs to be resolved as either named or unnamed. The rules are: + +1. If the name only appears in `named` or `supertypes`, it is **named**. +2. If the name only appears in `unnamed`, it is **unnamed**. +3. If the name appears in both, it defaults to **named**. +4. To explicitly reference an unnamed type in the ambiguous case, use the + map form: + +```yaml +named: + example: + field: { unnamed: foo } +``` + +In practice, ambiguity is rare — names like `end`, `+`, `if` are almost +always only unnamed, while names like `identifier`, `assignment` are only +named. + +## Complete example + +```yaml +supertypes: + _expression: + - assignment + - binary + - identifier + +named: + assignment: + left: _expression + right?: _expression + binary: + left: [_expression, _simple_numeric] + operator: ["!=", "+"] + right: _expression + argument_list: + $children*: [_expression, block_argument] + identifier: + constant: + +unnamed: + - "!=" + - "+" + - "=" + - "end" +``` + +## CLI usage + +Convert YAML to JSON: + +``` +node_types_yaml input.yaml > node-types.json +``` + +Convert JSON to YAML: + +``` +node_types_yaml --from-json node-types.json > node-types.yaml +``` + +Both commands also accept input from stdin if no file argument is given. diff --git a/shared/yeast/src/bin/node_types_yaml.rs b/shared/yeast/src/bin/node_types_yaml.rs new file mode 100644 index 00000000000..bc392ecb1f6 --- /dev/null +++ b/shared/yeast/src/bin/node_types_yaml.rs @@ -0,0 +1,51 @@ +use clap::Parser; +use std::io::Read; + +#[derive(Parser)] +#[clap( + name = "node-types-yaml", + about = "Convert between YAML and JSON node-types formats" +)] +struct Cli { + /// Input file (reads from stdin if not provided) + input: Option, + + /// Convert from JSON to YAML (default is YAML to JSON) + #[arg(long)] + from_json: bool, +} + +fn main() { + let args = Cli::parse(); + + let input = match &args.input { + Some(path) => std::fs::read_to_string(path).unwrap_or_else(|e| { + eprintln!("Error reading {path}: {e}"); + std::process::exit(1); + }), + None => { + let mut buf = String::new(); + std::io::stdin() + .read_to_string(&mut buf) + .unwrap_or_else(|e| { + eprintln!("Error reading stdin: {e}"); + std::process::exit(1); + }); + buf + } + }; + + let result = if args.from_json { + yeast::node_types_yaml::convert_from_json(&input) + } else { + yeast::node_types_yaml::convert(&input) + }; + + match result { + Ok(output) => print!("{output}"), + Err(e) => { + eprintln!("Error: {e}"); + std::process::exit(1); + } + } +} diff --git a/shared/yeast/src/node_types_yaml.rs b/shared/yeast/src/node_types_yaml.rs new file mode 100644 index 00000000000..d321ba8a2cf --- /dev/null +++ b/shared/yeast/src/node_types_yaml.rs @@ -0,0 +1,722 @@ +/// Converts a YAML node-types file to the tree-sitter `node-types.json` format. +/// +/// # YAML format +/// +/// ```yaml +/// supertypes: +/// _expression: +/// - assignment +/// - binary +/// +/// named: +/// assignment: +/// left: _lhs +/// right: _expression +/// identifier: +/// +/// unnamed: +/// - "+" +/// - "end" +/// ``` +/// +/// See the crate-level docs for the full format specification. +use std::collections::{BTreeMap, BTreeSet}; +use std::fmt::Write; + +use serde::Deserialize; +use serde_json::json; + +/// Top-level YAML structure. +#[derive(Deserialize, Default)] +struct YamlNodeTypes { + #[serde(default)] + supertypes: BTreeMap>, + #[serde(default)] + named: BTreeMap>>, + #[serde(default)] + unnamed: Vec, +} + +/// A reference to a node type. Can be: +/// - a plain string (resolved by looking up named vs unnamed) +/// - a map `{unnamed: "name"}` to force unnamed interpretation +#[derive(Deserialize, Debug, Clone)] +#[serde(untagged)] +enum TypeRef { + Name(String), + Explicit { unnamed: String }, +} + +/// A field value: either a single type ref or a list of them. +#[derive(Deserialize, Debug, Clone)] +#[serde(untagged)] +enum TypeRefOrList { + Single(TypeRef), + List(Vec), +} + +impl TypeRefOrList { + fn into_vec(self) -> Vec { + match self { + TypeRefOrList::Single(t) => vec![t], + TypeRefOrList::List(v) => v, + } + } +} + +/// Parsed field name: base name + multiplicity markers. +struct FieldSpec { + name: Option, // None for $children + multiple: bool, + required: bool, +} + +fn parse_field_name(raw: &str) -> FieldSpec { + let is_children = + raw == "$children" || raw == "$children?" || raw == "$children*" || raw == "$children+"; + + let suffix = raw.chars().last().filter(|c| matches!(c, '?' | '*' | '+')); + + let (multiple, required) = match suffix { + Some('?') => (false, false), + Some('*') => (true, false), + Some('+') => (true, true), + _ => (false, true), // bare field name = required, single + }; + + let name = if is_children { + None + } else { + let base = raw.trim_end_matches(['?', '*', '+']); + Some(base.to_string()) + }; + + FieldSpec { + name, + multiple, + required, + } +} + +/// Resolve a TypeRef to a (type, named) pair, 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}) + } + } + } +} + +/// Convert YAML string to node-types JSON string. +pub fn convert(yaml_input: &str) -> Result { + let yaml: YamlNodeTypes = + serde_yaml::from_str(yaml_input).map_err(|e| format!("Failed to parse YAML: {e}"))?; + + // Build the sets of known named and unnamed types for resolution. + let mut named_types = BTreeSet::new(); + for name in yaml.supertypes.keys() { + named_types.insert(name.clone()); + } + for name in yaml.named.keys() { + named_types.insert(name.clone()); + } + let unnamed_types: BTreeSet = yaml.unnamed.iter().cloned().collect(); + + let mut output = Vec::new(); + + // 1. Supertypes + for (name, members) in &yaml.supertypes { + let subtypes: Vec<_> = members + .iter() + .map(|m| resolve_type_ref(m, &named_types, &unnamed_types)) + .collect(); + output.push(json!({ + "type": name, + "named": true, + "subtypes": subtypes, + })); + } + + // 2. Named nodes + for (name, fields_opt) in &yaml.named { + let fields_map = match fields_opt { + None => { + // Leaf token: no fields, no children, no subtypes + output.push(json!({ + "type": name, + "named": true, + "fields": {}, + })); + continue; + } + Some(m) if m.is_empty() => { + output.push(json!({ + "type": name, + "named": true, + "fields": {}, + })); + continue; + } + Some(m) => m, + }; + + let mut json_fields = serde_json::Map::new(); + let mut json_children: Option = None; + + for (raw_field_name, type_refs) in fields_map { + let spec = parse_field_name(raw_field_name); + let types: Vec<_> = type_refs + .clone() + .into_vec() + .iter() + .map(|t| resolve_type_ref(t, &named_types, &unnamed_types)) + .collect(); + + // Cloning to make the borrow checker happy + let field_info = json!({ + "multiple": spec.multiple, + "required": spec.required, + "types": types, + }); + + if spec.name.is_none() { + // $children + json_children = Some(field_info); + } else { + json_fields.insert(spec.name.unwrap(), field_info); + } + } + + let mut entry = json!({ + "type": name, + "named": true, + "fields": json_fields, + }); + + if let Some(children) = json_children { + entry + .as_object_mut() + .unwrap() + .insert("children".to_string(), children); + } + + output.push(entry); + } + + // 3. Unnamed tokens + for name in &yaml.unnamed { + output.push(json!({ + "type": name, + "named": false, + })); + } + + 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(); + + // Register all supertypes as node kinds + 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 as node kinds + for name in &yaml.unnamed { + schema.register_unnamed_kind(name); + } + + Ok(schema) +} + +/// Build a Schema from a YAML string, extending a tree-sitter Language. +/// The Schema inherits all field/kind names from the Language, plus any +/// additional ones defined in the YAML. +pub fn schema_from_yaml_with_language( + yaml_input: &str, + language: &tree_sitter::Language, +) -> 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::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); + } + + Ok(schema) +} + +// --------------------------------------------------------------------------- +// JSON → YAML conversion +// --------------------------------------------------------------------------- + +/// JSON node-types structures (mirrors tree-sitter's format). +#[derive(Deserialize)] +struct JsonNodeInfo { + #[serde(rename = "type")] + kind: String, + named: bool, + #[serde(default)] + fields: BTreeMap, + children: Option, + #[serde(default)] + subtypes: Vec, +} + +#[derive(Deserialize)] +struct JsonNodeType { + #[serde(rename = "type")] + kind: String, + named: bool, +} + +#[derive(Deserialize)] +struct JsonFieldInfo { + multiple: bool, + required: bool, + types: Vec, +} + +/// Convert a tree-sitter node-types.json string to the YAML format. +pub fn convert_from_json(json_input: &str) -> Result { + let nodes: Vec = + serde_json::from_str(json_input).map_err(|e| format!("Failed to parse JSON: {e}"))?; + + // Collect all named and unnamed types for disambiguation decisions. + let mut all_named: BTreeSet = BTreeSet::new(); + let mut all_unnamed: BTreeSet = BTreeSet::new(); + for node in &nodes { + if node.named { + all_named.insert(node.kind.clone()); + } else { + all_unnamed.insert(node.kind.clone()); + } + } + + let mut supertypes: BTreeMap> = BTreeMap::new(); + let mut named: BTreeMap>> = BTreeMap::new(); + let mut unnamed: Vec = Vec::new(); + + for node in nodes { + if !node.named { + unnamed.push(node.kind); + continue; + } + + if !node.subtypes.is_empty() { + supertypes.insert(node.kind, node.subtypes); + continue; + } + + if node.fields.is_empty() && node.children.is_none() { + // Leaf token + named.insert(node.kind, None); + } else { + let mut fields = BTreeMap::new(); + for (name, info) in node.fields { + fields.insert(name, info); + } + if let Some(children) = node.children { + fields.insert("$children".to_string(), children); + } + named.insert(node.kind, Some(fields)); + } + } + + // Now emit YAML + let mut out = String::new(); + + // Supertypes + if !supertypes.is_empty() { + writeln!(out, "supertypes:").unwrap(); + for (name, members) in &supertypes { + writeln!(out, " {name}:").unwrap(); + for member in members { + let ref_str = format_type_ref(&member.kind, member.named, &all_named, &all_unnamed); + writeln!(out, " - {ref_str}").unwrap(); + } + } + writeln!(out).unwrap(); + } + + // Named + if !named.is_empty() { + writeln!(out, "named:").unwrap(); + for (name, fields_opt) in &named { + match fields_opt { + None => { + writeln!(out, " {name}:").unwrap(); + } + Some(fields) => { + writeln!(out, " {name}:").unwrap(); + for (field_name, info) in fields { + let suffix = field_suffix(info.multiple, info.required); + let yaml_name = if field_name == "$children" { + format!("$children{suffix}") + } else { + format!("{field_name}{suffix}") + }; + + let type_refs: Vec = info + .types + .iter() + .map(|t| format_type_ref(&t.kind, t.named, &all_named, &all_unnamed)) + .collect(); + + if type_refs.len() == 1 { + writeln!(out, " {yaml_name}: {}", type_refs[0]).unwrap(); + } else { + let list = type_refs + .iter() + .map(|s| s.as_str()) + .collect::>() + .join(", "); + writeln!(out, " {yaml_name}: [{list}]").unwrap(); + } + } + } + } + } + writeln!(out).unwrap(); + } + + // Unnamed + if !unnamed.is_empty() { + writeln!(out, "unnamed:").unwrap(); + for name in &unnamed { + writeln!(out, " - {}", force_quote(name)).unwrap(); + } + } + + Ok(out) +} + +fn field_suffix(multiple: bool, required: bool) -> &'static str { + match (multiple, required) { + (false, true) => "", + (false, false) => "?", + (true, true) => "+", + (true, false) => "*", + } +} + +/// Format a type reference for YAML output. Uses the disambiguation rule: +/// plain string if unambiguous, `{unnamed: name}` if the name exists as both +/// named and unnamed and we need the unnamed interpretation. +fn format_type_ref( + kind: &str, + named: bool, + all_named: &BTreeSet, + _all_unnamed: &BTreeSet, +) -> String { + if named { + quote_yaml(kind) + } else { + let is_also_named = all_named.contains(kind); + if is_also_named { + format!("{{unnamed: {}}}", force_quote(kind)) + } else { + force_quote(kind) + } + } +} + +/// Always wrap in double quotes. Used for unnamed node references so they're +/// visually distinct from named ones — YAML treats both forms as equivalent strings. +fn force_quote(s: &str) -> String { + format!("\"{}\"", s.replace('\\', "\\\\").replace('"', "\\\"")) +} + +/// Quote a YAML string value if it contains special characters or could be +/// misinterpreted. +fn quote_yaml(s: &str) -> String { + let needs_quoting = s.is_empty() + || s.contains(|c: char| { + matches!( + c, + ':' | '{' + | '}' + | '[' + | ']' + | ',' + | '&' + | '*' + | '#' + | '?' + | '|' + | '-' + | '<' + | '>' + | '=' + | '!' + | '%' + | '@' + | '`' + | '"' + | '\'' + ) + }) + || s.starts_with(' ') + || s.ends_with(' ') + || s == "true" + || s == "false" + || s == "null" + || s == "yes" + || s == "no" + || s.parse::().is_ok(); + + if needs_quoting { + format!("\"{}\"", s.replace('\\', "\\\\").replace('"', "\\\"")) + } else { + s.to_string() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_basic_conversion() { + let yaml = r#" +supertypes: + _expression: + - assignment + - binary + +named: + assignment: + left: _lhs + right: _expression + binary: + left: [_expression, _simple_numeric] + operator: ["!=", "+"] + right: _expression + argument_list: + $children*: [_expression, block_argument] + identifier: + +unnamed: + - "!=" + - "+" + - "end" +"#; + + let json_str = convert(yaml).unwrap(); + let result: Vec = serde_json::from_str(&json_str).unwrap(); + + // Check supertype + let expr = &result[0]; + assert_eq!(expr["type"], "_expression"); + assert_eq!(expr["named"], true); + assert_eq!(expr["subtypes"].as_array().unwrap().len(), 2); + + // Check assignment + let assign = result.iter().find(|n| n["type"] == "assignment").unwrap(); + assert_eq!(assign["fields"]["left"]["required"], true); + assert_eq!(assign["fields"]["left"]["multiple"], false); + assert_eq!(assign["fields"]["left"]["types"][0]["type"], "_lhs"); + assert_eq!(assign["fields"]["left"]["types"][0]["named"], true); + + // Check binary.operator — "!=" and "+" should resolve to unnamed + let binary = result.iter().find(|n| n["type"] == "binary").unwrap(); + let op_types = binary["fields"]["operator"]["types"].as_array().unwrap(); + assert_eq!(op_types[0]["type"], "!="); + assert_eq!(op_types[0]["named"], false); + assert_eq!(op_types[1]["type"], "+"); + assert_eq!(op_types[1]["named"], false); + + // Check argument_list has children, not a field + let arg_list = result + .iter() + .find(|n| n["type"] == "argument_list") + .unwrap(); + assert!(arg_list.get("children").is_some()); + assert_eq!(arg_list["children"]["multiple"], true); + assert_eq!(arg_list["children"]["required"], false); + + // Check identifier is a leaf + let ident = result.iter().find(|n| n["type"] == "identifier").unwrap(); + assert_eq!(ident["fields"].as_object().unwrap().len(), 0); + + // Check unnamed tokens + let end = result.iter().find(|n| n["type"] == "end").unwrap(); + assert_eq!(end["named"], false); + } + + #[test] + fn test_explicit_unnamed_disambiguation() { + let yaml = r#" +named: + foo: + field: [{unnamed: bar}] + +unnamed: + - bar +"#; + + let json_str = convert(yaml).unwrap(); + let result: Vec = serde_json::from_str(&json_str).unwrap(); + let foo = result.iter().find(|n| n["type"] == "foo").unwrap(); + assert_eq!(foo["fields"]["field"]["types"][0]["named"], false); + } + + #[test] + fn test_field_suffixes() { + let yaml = r#" +named: + test_node: + required_single: foo + optional_single?: foo + required_multiple+: foo + optional_multiple*: foo +"#; + + let json_str = convert(yaml).unwrap(); + let result: Vec = serde_json::from_str(&json_str).unwrap(); + let node = result.iter().find(|n| n["type"] == "test_node").unwrap(); + let fields = node["fields"].as_object().unwrap(); + + assert_eq!(fields["required_single"]["required"], true); + assert_eq!(fields["required_single"]["multiple"], false); + + assert_eq!(fields["optional_single"]["required"], false); + assert_eq!(fields["optional_single"]["multiple"], false); + + assert_eq!(fields["required_multiple"]["required"], true); + assert_eq!(fields["required_multiple"]["multiple"], true); + + assert_eq!(fields["optional_multiple"]["required"], false); + assert_eq!(fields["optional_multiple"]["multiple"], true); + } + + #[test] + fn test_json_to_yaml() { + let json = r#"[ + {"type": "_expression", "named": true, "subtypes": [ + {"type": "assignment", "named": true}, + {"type": "identifier", "named": true} + ]}, + {"type": "assignment", "named": true, "fields": { + "left": {"multiple": false, "required": true, "types": [ + {"type": "_expression", "named": true} + ]}, + "right": {"multiple": false, "required": false, "types": [ + {"type": "_expression", "named": true} + ]} + }, "children": { + "multiple": true, "required": false, "types": [ + {"type": "identifier", "named": true} + ] + }}, + {"type": "identifier", "named": true, "fields": {}}, + {"type": "=", "named": false}, + {"type": "end", "named": false} + ]"#; + + let yaml = convert_from_json(json).unwrap(); + + // Verify key structures are present + assert!(yaml.contains("supertypes:")); + assert!(yaml.contains("_expression:")); + assert!(yaml.contains("named:")); + assert!(yaml.contains("assignment:")); + assert!(yaml.contains("left:")); + assert!(yaml.contains("right?:")); + assert!(yaml.contains("$children*:")); + assert!(yaml.contains("identifier:")); + assert!(yaml.contains("unnamed:")); + assert!(yaml.contains("\"=\"")); + assert!(yaml.contains("end")); + } + + #[test] + fn test_round_trip() { + let yaml_input = r#" +supertypes: + _expression: + - assignment + - identifier + +named: + assignment: + left: _expression + right?: _expression + $children*: identifier + identifier: + +unnamed: + - "=" + - end +"#; + + // YAML → JSON → YAML + let json = convert(yaml_input).unwrap(); + let yaml_output = convert_from_json(&json).unwrap(); + // YAML → JSON again (should be identical) + let json2 = convert(&yaml_output).unwrap(); + + let v1: serde_json::Value = serde_json::from_str(&json).unwrap(); + let v2: serde_json::Value = serde_json::from_str(&json2).unwrap(); + assert_eq!(v1, v2); + } +} From 4c5548363cd8ce7295c5872d94a6a4f6f261264e Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 4 May 2026 13:13:37 +0000 Subject: [PATCH 17/43] yeast: Add AST dumper for human-readable tree output Produces indented text showing node kinds, named fields, and leaf content. Unnamed tokens are hidden unless inside a named field. Used by tests for readable assertions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shared/yeast/src/dump.rs | 181 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 shared/yeast/src/dump.rs diff --git a/shared/yeast/src/dump.rs b/shared/yeast/src/dump.rs new file mode 100644 index 00000000000..99ba019cc3e --- /dev/null +++ b/shared/yeast/src/dump.rs @@ -0,0 +1,181 @@ +use std::fmt::Write; + +use crate::{Ast, Node, NodeContent, CHILD_FIELD}; + +/// Options for controlling AST dump output. +pub struct DumpOptions { + /// Whether to include source locations in the output. + pub show_locations: bool, + /// Whether to include source text for leaf nodes. + pub show_content: bool, +} + +impl Default for DumpOptions { + fn default() -> Self { + Self { + show_locations: false, + show_content: true, + } + } +} + +/// Dump a yeast AST as a human-readable indented text format. +/// +/// Output format: +/// ```text +/// program +/// assignment +/// left: +/// left_assignment_list +/// identifier "x" +/// identifier "y" +/// right: +/// call +/// method: +/// identifier "foo" +/// ``` +pub fn dump_ast(ast: &Ast, root: usize, source: &str) -> String { + dump_ast_with_options(ast, root, source, &DumpOptions::default()) +} + +pub fn dump_ast_with_options( + ast: &Ast, + root: usize, + source: &str, + options: &DumpOptions, +) -> String { + let mut out = String::new(); + dump_node(ast, root, source, options, 0, &mut out); + out +} + +fn dump_node( + ast: &Ast, + id: usize, + source: &str, + options: &DumpOptions, + indent: usize, + out: &mut String, +) { + let node = match ast.get_node(id) { + Some(n) => n, + None => return, + }; + + let prefix = " ".repeat(indent); + + // Node kind + write!(out, "{}{}", prefix, node.kind_name()).unwrap(); + + // Location + if options.show_locations { + let start = node.start_position(); + let end = node.end_position(); + write!( + out, + " [{},{}]-[{},{}]", + start.row + 1, + start.column + 1, + end.row + 1, + end.column + 1 + ) + .unwrap(); + } + + // Content for leaf nodes + if options.show_content && node.is_named() && is_leaf(node) { + let content = node_content(node, source); + if !content.is_empty() { + write!(out, " {content:?}").unwrap(); + } + } + + writeln!(out).unwrap(); + + // Named fields first + for (&field_id, children) in &node.fields { + if field_id == CHILD_FIELD { + continue; // Handle unnamed children last + } + let field_name = ast.field_name_for_id(field_id).unwrap_or("?"); + 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); + } else { + writeln!(out).unwrap(); + dump_node(ast, children[0], source, options, indent + 2, out); + } + } else { + writeln!(out, "{prefix} {field_name}:").unwrap(); + for &child_id in children { + dump_node(ast, child_id, source, options, indent + 2, out); + } + } + } + + // Unnamed children — skip unnamed tokens (keywords, punctuation) + if let Some(children) = node.fields.get(&CHILD_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 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) { + let node = match ast.get_node(id) { + Some(n) => n, + None => return, + }; + + write!(out, "{}", node.kind_name()).unwrap(); + + if options.show_locations { + let start = node.start_position(); + let end = node.end_position(); + write!( + out, + " [{},{}]-[{},{}]", + start.row + 1, + start.column + 1, + end.row + 1, + end.column + 1 + ) + .unwrap(); + } + + if options.show_content && node.is_named() { + let content = node_content(node, source); + if !content.is_empty() { + write!(out, " {content:?}").unwrap(); + } + } + + writeln!(out).unwrap(); +} + +fn is_leaf(node: &Node) -> bool { + node.fields.is_empty() +} + +fn node_content(node: &Node, source: &str) -> String { + match &node.content { + NodeContent::DynamicString(s) if !s.is_empty() => s.clone(), + _ => { + let range = node.byte_range(); + if range.start < source.len() && range.end <= source.len() { + source[range.start..range.end].to_string() + } else { + String::new() + } + } + } +} From 6e580446fd01bd8f0c2a0e921dde69153ca6abe6 Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 4 May 2026 13:13:18 +0000 Subject: [PATCH 18/43] yeast: Add yeast test suite 12 tests covering parsing, queries, tree building, desugaring rules, cursor navigation, and the shorthand rule! syntax. Tests use a custom output node-types.yml with named fields for all children (parameter, stmt, index), loaded via schema_from_yaml_with_language. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shared/yeast/tests/node-types.yml | 63 +++++ shared/yeast/tests/test.rs | 419 ++++++++++++++++++++++++++++++ 2 files changed, 482 insertions(+) create mode 100644 shared/yeast/tests/node-types.yml create mode 100644 shared/yeast/tests/test.rs diff --git a/shared/yeast/tests/node-types.yml b/shared/yeast/tests/node-types.yml new file mode 100644 index 00000000000..978ef147543 --- /dev/null +++ b/shared/yeast/tests/node-types.yml @@ -0,0 +1,63 @@ +# Output node types for yeast test rules. +# Inspired by tree-sitter-ruby, but with all children in named fields +# (no unnamed children). This represents the desugared output schema. + +named: + program: + stmt*: [assignment, call, identifier, for] + + assignment: + left: [identifier, left_assignment_list] + right: [identifier, integer, call, element_reference] + + left_assignment_list: + item*: identifier + + element_reference: + object: identifier + index: [integer, identifier] + + for: + pattern: [identifier, left_assignment_list] + value: in + body: do + + in: + value: [identifier, call] + + do: + stmt*: [assignment, identifier, call] + + call: + receiver: [identifier, call] + method: identifier + arguments?: argument_list + block?: block + + argument_list: + argument*: [identifier, integer, call] + + block: + parameters: block_parameters + body: block_body + + block_parameters: + parameter*: identifier + + block_body: + stmt*: [assignment, identifier, call] + + identifier: + integer: + +unnamed: + - "=" + - "," + - "(" + - ")" + - "for" + - "in" + - "do" + - "end" + - "|" + - "." diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs new file mode 100644 index 00000000000..406c990a8bd --- /dev/null +++ b/shared/yeast/tests/test.rs @@ -0,0 +1,419 @@ +#![cfg(test)] + +use yeast::dump::dump_ast; +use yeast::*; + +const OUTPUT_SCHEMA_YAML: &str = include_str!("node-types.yml"); + +/// Helper: parse Ruby source with no rules, return dump. +fn parse_and_dump(input: &str) -> String { + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run(input).unwrap(); + dump_ast(&ast, ast.get_root(), input) +} + +/// Helper: parse Ruby source with a custom output schema and rules, return dump. +fn run_and_dump(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 runner = Runner::with_schema(lang, &schema, &rules); + let ast = runner.run(input).unwrap(); + dump_ast(&ast, ast.get_root(), input) +} + +/// 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 +/// line. This lets test assertions place the first line at the same +/// indentation as the rest of the body. +#[track_caller] +fn assert_dump_eq(actual: &str, expected: &str) { + let min_indent = expected + .lines() + .filter(|l| !l.trim().is_empty()) + .map(|l| l.len() - l.trim_start().len()) + .min() + .unwrap_or(0); + let dedented: String = expected + .lines() + .map(|l| { + if l.len() >= min_indent { + &l[min_indent..] + } else { + l + } + }) + .collect::>() + .join("\n"); + assert_eq!(actual.trim(), dedented.trim()); +} + +// ---- Parsing tests ---- + +#[test] +fn test_parse_assignment() { + let dump = parse_and_dump("x = 1"); + assert_dump_eq( + &dump, + r#" + program + assignment + left: identifier "x" + right: integer "1" + "#, + ); +} + +#[test] +fn test_parse_multiple_assignment() { + let dump = parse_and_dump("x, y = foo()"); + assert_dump_eq( + &dump, + r#" + program + assignment + left: + left_assignment_list + identifier "x" + identifier "y" + right: + call + arguments: + argument_list + method: identifier "foo" + "#, + ); +} + +#[test] +fn test_parse_for_loop() { + let dump = parse_and_dump("for x in list do\n y\nend"); + assert_dump_eq( + &dump, + r#" + program + for + body: + do + identifier "y" + pattern: identifier "x" + value: + in + identifier "list" + "#, + ); +} + +// ---- Query tests ---- + +#[test] +fn test_query_match() { + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("x = 1").unwrap(); + + let query = yeast::query!( + (program + child: (assignment + left: (_) @left + right: (_) @right + ) + ) + ); + + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, ast.get_root(), &mut captures).unwrap(); + assert!(matched); + assert!(captures.get_var("left").is_ok()); + assert!(captures.get_var("right").is_ok()); +} + +#[test] +fn test_query_no_match() { + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("x = 1").unwrap(); + + let query = yeast::query!( + (program + child: (call + method: (_) @m + ) + ) + ); + + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, ast.get_root(), &mut captures).unwrap(); + assert!(!matched); +} + +#[test] +fn test_query_repeated_capture() { + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("x, y, z = 1").unwrap(); + + let query = yeast::query!( + (assignment + left: (left_assignment_list + (identifier)* @names + ) + ) + ); + + // Match against the assignment node (first named child of program) + let mut cursor = AstCursor::new(&ast); + cursor.goto_first_child(); + let assignment_id = cursor.node().id(); + + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, assignment_id, &mut captures).unwrap(); + assert!(matched); + assert_eq!(captures.get_all("names").len(), 3); +} + +// ---- Tree builder tests ---- + +#[test] +fn test_tree_builder() { + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let mut ast = runner.run("x = 1").unwrap(); + let input = "x = 1"; + + let query = yeast::query!( + (program + child: (assignment + left: (_) @left + right: (_) @right + ) + ) + ); + + let mut captures = yeast::captures::Captures::new(); + query.do_match(&ast, ast.get_root(), &mut captures).unwrap(); + + // Swap left and right + let fresh = yeast::tree_builder::FreshScope::new(); + let mut ctx = yeast::build::BuildCtx::new(&mut ast, &captures, &fresh); + let new_id = yeast::tree!(ctx, + (program + child: (assignment + left: {ctx.capture("right")} + right: {ctx.capture("left")} + ) + ) + ); + + let dump = dump_ast(ctx.ast, new_id, input); + assert_dump_eq( + &dump, + r#" + program + assignment + left: integer "1" + right: identifier "x" + "#, + ); +} + +// ---- Rule tests ---- + +// These rules use field names from node-types.yml, which extends the +// tree-sitter-ruby grammar with named fields for nodes that only have +// unnamed children in tree-sitter (e.g. block_body.stmt, block_parameters.parameter). +fn ruby_rules() -> Vec { + let assign_rule = yeast::rule!( + (assignment + left: (left_assignment_list + (identifier)* @left + ) + right: (_) @right + ) + => + (assignment + left: (identifier $tmp) + right: {right} + ) + {..left.iter().enumerate().map(|(i, &lhs)| + yeast::tree!( + (assignment + left: {lhs} + right: (element_reference + object: (identifier $tmp) + index: (integer #{i}) + ) + ) + ) + )} + ); + + let for_rule = yeast::rule!( + (for + pattern: (_) @pat + value: (in (_) @val) + body: (do (_)* @body) + ) + => + (call + receiver: {val} + method: (identifier "each") + block: (block + parameters: (block_parameters + parameter: (identifier $tmp) + ) + body: (block_body + stmt: (assignment + left: {pat} + right: (identifier $tmp) + ) + stmt: {..body} + ) + ) + ) + ); + + vec![assign_rule, for_rule] +} + +#[test] +fn test_desugar_multiple_assignment() { + let dump = run_and_dump("x, y = e", ruby_rules()); + assert_dump_eq( + &dump, + r#" + program + assignment + left: identifier "$tmp-0" + right: identifier "e" + assignment + left: identifier "x" + right: + element_reference + object: identifier "$tmp-0" + index: integer "0" + assignment + left: identifier "y" + right: + element_reference + object: identifier "$tmp-0" + index: integer "1" + "#, + ); +} + +#[test] +fn test_desugar_for_loop() { + let dump = run_and_dump("for x in list do\n y\nend", ruby_rules()); + assert_dump_eq( + &dump, + r#" + program + call + block: + block + body: + block_body + stmt: + assignment + left: identifier "x" + right: identifier "$tmp-0" + identifier "y" + parameters: + block_parameters + parameter: identifier "$tmp-0" + method: identifier "each" + receiver: identifier "list" + "#, + ); +} + +#[test] +fn test_shorthand_rule() { + let rule = yeast::rule!( + (assignment + left: (_) @method + right: (_) @receiver + ) + => call + ); + + let dump = run_and_dump("x = 1", vec![rule]); + assert_dump_eq( + &dump, + r#" + program + call + method: identifier "x" + receiver: integer "1" + "#, + ); +} + +// ---- Cursor tests ---- + +#[test] +fn test_cursor_navigation() { + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("x = 1").unwrap(); + let mut cursor = AstCursor::new(&ast); + + // Start at root + assert_eq!(cursor.node().kind(), "program"); + + // Go to first child (assignment) + assert!(cursor.goto_first_child()); + assert_eq!(cursor.node().kind(), "assignment"); + + // No sibling + assert!(!cursor.goto_next_sibling()); + + // Go to first child of assignment + assert!(cursor.goto_first_child()); + assert!(cursor.node().is_named()); + + // Go back up + assert!(cursor.goto_parent()); + assert_eq!(cursor.node().kind(), "assignment"); + + assert!(cursor.goto_parent()); + assert_eq!(cursor.node().kind(), "program"); + + // Can't go further up + assert!(!cursor.goto_parent()); +} + +#[test] +fn test_desugar_for_with_multiple_assignment() { + let dump = run_and_dump("for a, b in list do\n x\nend", ruby_rules()); + assert_dump_eq( + &dump, + r#" + program + call + block: + block + body: + block_body + stmt: + assignment + left: identifier "$tmp-1" + right: identifier "$tmp-0" + assignment + left: identifier "a" + right: + element_reference + object: identifier "$tmp-1" + index: integer "0" + assignment + left: identifier "b" + right: + element_reference + object: identifier "$tmp-1" + index: integer "1" + identifier "x" + parameters: + block_parameters + parameter: identifier "$tmp-0" + method: identifier "each" + receiver: identifier "list" + "#, + ); +} From cc28ff9a4866eb8323c799dc627f07d6e8a5d628 Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 4 May 2026 13:13:46 +0000 Subject: [PATCH 19/43] yeast: Add yeast documentation Covers architecture, query language, template language (tree!/trees!/rule!), capture semantics, fresh identifiers, and extractor integration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shared/yeast/doc/yeast.md | 329 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 shared/yeast/doc/yeast.md diff --git a/shared/yeast/doc/yeast.md b/shared/yeast/doc/yeast.md new file mode 100644 index 00000000000..d49ff96f11d --- /dev/null +++ b/shared/yeast/doc/yeast.md @@ -0,0 +1,329 @@ +# YEAST — YEAST Elaborates Abstract Syntax Trees + +YEAST is a framework for transforming tree-sitter parse trees before they are +extracted into a CodeQL database. It sits between the tree-sitter parser and +the TRAP extractor, rewriting parts of the AST according to declarative rules. + +## Motivation + +Tree-sitter grammars describe the **concrete syntax** of a language — every +keyword, operator, and punctuation token appears in the parse tree. CodeQL +analyses often prefer a **simplified abstract syntax** where syntactic sugar +has been removed. YEAST bridges this gap by desugaring the tree-sitter output +into a cleaner form before extraction. + +For example, Ruby's `for x in list do ... end` is syntactic sugar for +`list.each { |x| ... }`. A YEAST rule can rewrite the former into the latter +so that CodeQL queries only need to reason about the `.each` form. + +## Architecture + +``` +Source code + │ + ▼ +┌──────────────┐ +│ tree-sitter │ Parse source into a concrete syntax tree +│ parser │ +└──────┬───────┘ + │ tree_sitter::Tree + ▼ +┌──────────────┐ +│ YEAST │ Apply desugaring rules, producing a new AST +│ Runner │ +└──────┬───────┘ + │ yeast::Ast + ▼ +┌──────────────┐ +│ TRAP │ Walk the (possibly rewritten) AST and emit TRAP tuples +│ extractor │ +└──────────────┘ +``` + +The entry point is `extract()` in the shared tree-sitter extractor. When +called with a non-empty `rules` vector, the parsed tree is run through the +YEAST `Runner` before TRAP extraction; with an empty `rules` vector the +tree is extracted unchanged. + +## How desugaring works + +A YEAST `Rule` has two parts: + +1. A **query** that matches nodes in the AST using a tree-sitter-inspired + pattern language. +2. A **transform** that produces replacement nodes from the match captures. + +The `Runner` applies rules by walking the tree top-down. At each node, it +tries each rule in order. If a rule's query matches, the node is replaced by +the transform's output, and the rules are re-applied to the result. If no +rule matches, the node is kept and its children are processed recursively. + +A rule can replace one node with zero nodes (deletion), one node (rewriting), +or multiple nodes (expansion). + +## Query language + +Queries use a syntax inspired by +[tree-sitter queries](https://tree-sitter.github.io/tree-sitter/using-parsers/queries/index.html), +written inside the `yeast::query!()` proc macro. + +### Node patterns + +```rust +// Match any named node +(_) + +// Match a node of a specific kind +(assignment) + +// Match an unnamed token by its text +("end") +``` + +### Fields + +```rust +// Match a node with specific fields +(assignment + left: (identifier) @lhs + right: (_) @rhs +) +``` + +Fields are matched by name. Unmentioned fields are ignored — the pattern +`(assignment left: (_) @x)` matches any `assignment` node regardless of +what's in `right`. + +### Captures + +Captures bind matched nodes to names for use in the transform. A capture +`@name` always follows the pattern it captures: + +```rust +(identifier) @name // capture an identifier node +(_) @value // capture any named node +(identifier)* @items // capture each repeated match +``` + +### Unnamed children + +Patterns that appear after all named fields match unnamed (positional) +children. Named node patterns like `(_)` automatically skip unnamed tokens +(keywords, operators, punctuation), matching tree-sitter semantics: + +```rust +(for + pattern: (_) @pat // named field + value: (in (_) @val) // "in" token is skipped automatically + body: (do (_)* @body) // "do" and "end" tokens skipped +) +``` + +### Repetitions + +```rust +(_)* // zero or more +(_)+ // one or more +(_)? // zero or one +(identifier)* @names // capture each repeated match +``` + +## Template language + +Templates construct new AST nodes using the `tree!` and `trees!` macros. +All children in a template must be in named fields — output AST nodes are +always fully fielded. + +When used inside a `rule!` macro, the context is implicit — no explicit +`BuildCtx` argument is needed. When used standalone, they take a `BuildCtx` +as the first argument: + +```rust +// Inside rule! — implicit context, captures are Rust variables +yeast::rule!( + (assignment left: (_) @left right: (_) @right) + => + (assignment left: {right} right: {left}) +); + +// Standalone — explicit context +let fresh = yeast::tree_builder::FreshScope::new(); +let mut ctx = BuildCtx::new(ast, &captures, &fresh); +let id = yeast::tree!(ctx, + (assignment + left: {ctx.capture("lhs")} + right: {ctx.capture("rhs")} + ) +); +``` + +### `tree!` — build a single node + +`tree!(...)` returns a single node `Id`: + +```rust +yeast::tree!(ctx, + (assignment + left: {ctx.capture("lhs")} + right: {ctx.capture("rhs")} + ) +) +``` + +### `trees!` — build multiple nodes + +`trees!(...)` returns `Vec`: + +```rust +yeast::trees!(ctx, + (assignment left: {tmp} right: {right}) + {..body} +) +``` + +### Literal nodes + +`(kind "text")` creates a leaf node with fixed text content: + +```rust +(identifier "each") // an identifier node whose text is "each" +``` + +### Computed literals + +`(kind #{expr})` creates a leaf node whose content is `expr.to_string()`: + +```rust +(integer #{i}) // an integer node with the value of i +(identifier #{name}) // an identifier from a Rust variable +``` + +### Fresh identifiers + +`(kind $name)` creates a leaf node with an auto-generated unique name. All +occurrences of the same `$name` within one `BuildCtx` share the same value: + +```rust +(block + parameters: (block_parameters + (identifier $tmp) // generates e.g. "$tmp-0" + ) + body: (block_body + (assignment + left: {pat} + right: (identifier $tmp) // same "$tmp-0" value + ) + ) +) +``` + +### Embedded Rust expressions + +`{expr}` embeds a Rust expression that returns a single node `Id`: + +```rust +(assignment + left: {some_node_id} // insert a pre-built node + right: {rhs} // insert a captured value (inside rule!) +) +``` + +`{..expr}` splices a `Vec` (or any iterable of `Id`): + +```rust +yeast::trees!(ctx, + (assignment left: {tmp} right: {right}) + {..extra_nodes} // splice a Vec +) +``` + +Inside `rule!`, captures are Rust variables, so `{name}` inserts a +single capture (`Id`) and `{..name}` splices a repeated capture +(`Vec`). + +## Complete example: for-loop desugaring + +This rule rewrites Ruby's `for pat in val do body end` into +`val.each { |tmp| pat = tmp; body }`: + +```rust +let for_rule = yeast::rule!( + (for + pattern: (_) @pat + value: (in (_) @val) + body: (do (_)* @body) + ) + => + (call + receiver: {val} + method: (identifier "each") + block: (block + parameters: (block_parameters + (identifier $tmp) + ) + body: (block_body + (assignment + left: {pat} + right: (identifier $tmp) + ) + {..body} + ) + ) + ) +); +``` + +Captures from the query (`@pat`, `@val`, `@body`) become Rust variables +automatically: single captures bind as `Id`, repeated captures (after +`*` or `+`) as `Vec`, and optional captures (after `?`) as +`Option`. + +## The `rule!` macro + +`rule!` combines a query and a transform into a single declaration: + +```rust +// Full template form +yeast::rule!( + (query_pattern field: (_) @capture) + => + (output_template field: {capture}) +) + +// Shorthand form — captures become fields on the output node +yeast::rule!( + (query_pattern field: (_) @capture) + => output_kind +) +``` + +The shorthand `=> kind` form auto-generates the template, mapping each +capture name to a field of the same name on the output node. + +## Integration with the extractor + +A YEAST desugaring pass is configured with a [`DesugaringConfig`], which +carries the rules and an optional output node-types schema (in YAML +format). Attach it to a language spec to enable rewriting: + +```rust +let desugar = yeast::DesugaringConfig::new(my_rules) + .with_output_node_types_yaml(include_str!("output-node-types.yml")); + +let lang = simple::LanguageSpec { + prefix: "ruby", + ts_language: tree_sitter_ruby::LANGUAGE.into(), + node_types: tree_sitter_ruby::NODE_TYPES, + desugar: Some(desugar), + file_globs: vec!["*.rb".into()], +}; +``` + +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). + +For the dbscheme/QL code generator, set `Language::desugar` to a +`DesugaringConfig` carrying the same YAML; the generator converts it to +JSON for downstream code generation. The `rules` field of the config is +unused at code-generation time. From 9ad431dea1fd87f956868565e61afbc621af3ee7 Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 4 May 2026 13:13:58 +0000 Subject: [PATCH 20/43] yeast: Integrate yeast with shared tree-sitter extractor extract() gains a rules parameter. When empty, uses tree-sitter native traversal (no behavior change). When non-empty, runs yeast desugaring and extracts via traverse_yeast. Adds AstNode trait abstracting over tree_sitter::Node and yeast::Node, with minimal changes to existing Visitor methods (Node -> &N in 6 signatures). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ql/extractor/src/extractor.rs | 4 + ruby/extractor/src/extractor.rs | 2 + shared/tree-sitter-extractor/Cargo.toml | 1 + .../src/extractor/mod.rs | 151 ++++++++++++++++-- .../src/extractor/simple.rs | 35 +++- .../tests/integration_test.rs | 1 + .../tests/multiple_languages.rs | 2 + 7 files changed, 178 insertions(+), 18 deletions(-) diff --git a/ql/extractor/src/extractor.rs b/ql/extractor/src/extractor.rs index 8383d8424ee..66096442e85 100644 --- a/ql/extractor/src/extractor.rs +++ b/ql/extractor/src/extractor.rs @@ -29,24 +29,28 @@ pub fn run(options: Options) -> std::io::Result<()> { prefix: "ql", ts_language: tree_sitter_ql::LANGUAGE.into(), node_types: tree_sitter_ql::NODE_TYPES, + desugar: None, file_globs: vec!["*.ql".into(), "*.qll".into()], }, simple::LanguageSpec { prefix: "dbscheme", ts_language: tree_sitter_ql_dbscheme::LANGUAGE.into(), node_types: tree_sitter_ql_dbscheme::NODE_TYPES, + desugar: None, file_globs: vec!["*.dbscheme".into()], }, simple::LanguageSpec { prefix: "json", ts_language: tree_sitter_json::LANGUAGE.into(), node_types: tree_sitter_json::NODE_TYPES, + desugar: None, file_globs: vec!["*.json".into(), "*.jsonl".into(), "*.jsonc".into()], }, simple::LanguageSpec { prefix: "blame", ts_language: tree_sitter_blame::LANGUAGE.into(), node_types: tree_sitter_blame::NODE_TYPES, + desugar: None, file_globs: vec!["*.blame".into()], }, ], diff --git a/ruby/extractor/src/extractor.rs b/ruby/extractor/src/extractor.rs index 6807d09e9be..4849f473ccb 100644 --- a/ruby/extractor/src/extractor.rs +++ b/ruby/extractor/src/extractor.rs @@ -123,6 +123,7 @@ pub fn run(options: Options) -> std::io::Result<()> { &path, &source, &[], + None, ); let (ranges, line_breaks) = scan_erb( @@ -211,6 +212,7 @@ pub fn run(options: Options) -> std::io::Result<()> { &path, &source, &code_ranges, + None, ); std::fs::create_dir_all(src_archive_file.parent().unwrap())?; if needs_conversion { diff --git a/shared/tree-sitter-extractor/Cargo.toml b/shared/tree-sitter-extractor/Cargo.toml index d02f02fd588..1ad18a6df5a 100644 --- a/shared/tree-sitter-extractor/Cargo.toml +++ b/shared/tree-sitter-extractor/Cargo.toml @@ -20,6 +20,7 @@ serde_json = "1.0" chrono = { version = "0.4.42", features = ["serde"] } num_cpus = "1.17.0" zstd = "0.13.3" +yeast = { path = "../yeast" } [dev-dependencies] tree-sitter-ql = "0.23.1" diff --git a/shared/tree-sitter-extractor/src/extractor/mod.rs b/shared/tree-sitter-extractor/src/extractor/mod.rs index 0ace3831881..0c3e1366081 100644 --- a/shared/tree-sitter-extractor/src/extractor/mod.rs +++ b/shared/tree-sitter-extractor/src/extractor/mod.rs @@ -18,6 +18,82 @@ use tree_sitter::{Language, Node, Parser, Range, Tree}; pub mod simple; +/// Trait abstracting over tree-sitter and yeast node types for extraction. +trait AstNode { + fn kind(&self) -> &str; + fn is_named(&self) -> bool; + fn is_missing(&self) -> bool; + fn is_error(&self) -> bool; + fn is_extra(&self) -> bool; + fn start_position(&self) -> tree_sitter::Point; + fn end_position(&self) -> tree_sitter::Point; + fn byte_range(&self) -> std::ops::Range; + fn end_byte(&self) -> usize { + self.byte_range().end + } + /// For yeast nodes with synthetic content, return it. Otherwise None. + fn opt_string_content(&self) -> Option { + None + } +} + +impl<'a> AstNode for Node<'a> { + fn kind(&self) -> &str { + Node::kind(self) + } + fn is_named(&self) -> bool { + Node::is_named(self) + } + fn is_missing(&self) -> bool { + Node::is_missing(self) + } + fn is_error(&self) -> bool { + Node::is_error(self) + } + fn is_extra(&self) -> bool { + Node::is_extra(self) + } + fn start_position(&self) -> tree_sitter::Point { + Node::start_position(self) + } + fn end_position(&self) -> tree_sitter::Point { + Node::end_position(self) + } + fn byte_range(&self) -> std::ops::Range { + Node::byte_range(self) + } +} + +impl AstNode for yeast::Node { + fn kind(&self) -> &str { + yeast::Node::kind(self) + } + fn is_named(&self) -> bool { + yeast::Node::is_named(self) + } + fn is_missing(&self) -> bool { + yeast::Node::is_missing(self) + } + fn is_error(&self) -> bool { + yeast::Node::is_error(self) + } + fn is_extra(&self) -> bool { + yeast::Node::is_extra(self) + } + fn start_position(&self) -> tree_sitter::Point { + yeast::Node::start_position(self) + } + fn end_position(&self) -> tree_sitter::Point { + yeast::Node::end_position(self) + } + fn byte_range(&self) -> std::ops::Range { + yeast::Node::byte_range(self) + } + fn opt_string_content(&self) -> Option { + yeast::Node::opt_string_content(self) + } +} + /// Sets the tracing level based on the environment variables /// `RUST_LOG` and `CODEQL_VERBOSITY` (prioritized in that order), /// falling back to `warn` if neither is set. @@ -204,6 +280,11 @@ pub fn location_label(writer: &mut trap::Writer, location: trap::Location) -> tr } /// Extracts the source file at `path`, which is assumed to be canonicalized. +/// When `yeast_runner` is `Some`, the parsed tree is first transformed +/// through the supplied yeast `Runner` before TRAP extraction. Building the +/// `Runner` (which parses YAML and constructs the schema) is the caller's +/// responsibility, allowing it to be done once and shared across files. +#[allow(clippy::too_many_arguments)] pub fn extract( language: &Language, language_prefix: &str, @@ -214,6 +295,7 @@ pub fn extract( path: &Path, source: &[u8], ranges: &[Range], + yeast_runner: Option<&yeast::Runner<'_>>, ) { let path_str = file_paths::normalize_and_transform_path(path, transformer); let span = tracing::span!( @@ -236,13 +318,20 @@ pub fn extract( source, diagnostics_writer, trap_writer, - // TODO: should we handle path strings that are not valid UTF8 better? &path_str, file_label, language_prefix, schema, ); - traverse(&tree, &mut visitor); + + if let Some(yeast_runner) = yeast_runner { + let ast = yeast_runner + .run_from_tree(&tree) + .unwrap_or_else(|e| panic!("Desugaring failed for {path_str}: {e}")); + traverse_yeast(&ast, &mut visitor); + } else { + traverse(&tree, &mut visitor); + } parser.reset(); } @@ -329,11 +418,11 @@ impl<'a> Visitor<'a> { ); } - fn record_parse_error_for_node( + fn record_parse_error_for_node( &mut self, message: &str, args: &[diagnostics::MessageArg], - node: Node, + node: &N, status_page: bool, ) { let loc = location_for(self, self.file_label, node); @@ -357,7 +446,7 @@ impl<'a> Visitor<'a> { self.record_parse_error(loc_label, &mesg); } - fn enter_node(&mut self, node: Node) -> bool { + fn enter_node(&mut self, node: &N) -> bool { if node.is_missing() { self.record_parse_error_for_node( "A parse error occurred (expected {} symbol). Check the syntax of the file. If the file is invalid, correct the error or {} the file from analysis.", @@ -383,7 +472,7 @@ impl<'a> Visitor<'a> { true } - fn leave_node(&mut self, field_name: Option<&'static str>, node: Node) { + fn leave_node(&mut self, field_name: Option<&'static str>, node: &N) { if node.is_error() || node.is_missing() { return; } @@ -434,7 +523,7 @@ impl<'a> Visitor<'a> { fields, name: table_name, } => { - if let Some(args) = self.complex_node(&node, fields, &child_nodes, id) { + if let Some(args) = self.complex_node(node, fields, &child_nodes, id) { self.trap_writer.add_tuple( &self.ast_node_location_table_name, vec![trap::Arg::Label(id), trap::Arg::Label(loc_label)], @@ -495,9 +584,9 @@ impl<'a> Visitor<'a> { } } - fn complex_node( + fn complex_node( &mut self, - node: &Node, + node: &N, fields: &[Field], child_nodes: &[ChildNode], parent_id: trap::Label, @@ -529,7 +618,7 @@ impl<'a> Visitor<'a> { diagnostics::MessageArg::Code(&format!("{:?}", child_node.type_name)), diagnostics::MessageArg::Code(&format!("{:?}", field.type_info)), ], - *node, + node, false, ); } @@ -541,7 +630,7 @@ impl<'a> Visitor<'a> { diagnostics::MessageArg::Code(child_node.field_name.unwrap_or("child")), diagnostics::MessageArg::Code(&format!("{:?}", child_node.type_name)), ], - *node, + node, false, ); } @@ -566,7 +655,7 @@ impl<'a> Visitor<'a> { node.kind(), column_name ); - self.record_parse_error_for_node(&error_message, &[], *node, false); + self.record_parse_error_for_node(&error_message, &[], node, false); } } Storage::Table { @@ -582,7 +671,7 @@ impl<'a> Visitor<'a> { diagnostics::MessageArg::Code(node.kind()), diagnostics::MessageArg::Code(table_name), ], - *node, + node, false, ); break; @@ -639,15 +728,21 @@ impl<'a> Visitor<'a> { } // Emit a slice of a source file as an Arg. -fn sliced_source_arg(source: &[u8], n: Node) -> trap::Arg { - let range = n.byte_range(); - trap::Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) +fn sliced_source_arg(source: &[u8], n: &N) -> trap::Arg { + trap::Arg::String(n.opt_string_content().unwrap_or_else(|| { + let range = n.byte_range(); + String::from_utf8_lossy(&source[range.start..range.end]).into_owned() + })) } // Emit a pair of `TrapEntry`s for the provided node, appropriately calibrated. // The first is the location and label definition, and the second is the // 'Located' entry. -fn location_for(visitor: &mut Visitor, file_label: trap::Label, n: Node) -> trap::Location { +fn location_for( + visitor: &mut Visitor, + file_label: trap::Label, + n: &N, +) -> trap::Location { // Tree-sitter row, column values are 0-based while CodeQL starts // counting at 1. In addition Tree-sitter's row and column for the // end position are exclusive while CodeQL's end positions are inclusive. @@ -715,6 +810,28 @@ fn location_for(visitor: &mut Visitor, file_label: trap::Label, n: Node) -> trap fn traverse(tree: &Tree, visitor: &mut Visitor) { let cursor = &mut tree.walk(); + visitor.enter_node(&cursor.node()); + let mut recurse = true; + loop { + if recurse && cursor.goto_first_child() { + recurse = visitor.enter_node(&cursor.node()); + } else { + visitor.leave_node(cursor.field_name(), &cursor.node()); + + if cursor.goto_next_sibling() { + recurse = visitor.enter_node(&cursor.node()); + } else if cursor.goto_parent() { + recurse = false; + } else { + break; + } + } + } +} + +fn traverse_yeast(tree: &yeast::Ast, visitor: &mut Visitor) { + use yeast::Cursor; + let mut cursor = tree.walk(); visitor.enter_node(cursor.node()); let mut recurse = true; loop { diff --git a/shared/tree-sitter-extractor/src/extractor/simple.rs b/shared/tree-sitter-extractor/src/extractor/simple.rs index b8446d02f89..6fcd29b0344 100644 --- a/shared/tree-sitter-extractor/src/extractor/simple.rs +++ b/shared/tree-sitter-extractor/src/extractor/simple.rs @@ -7,11 +7,17 @@ use std::path::{Path, PathBuf}; use crate::diagnostics; use crate::node_types; +use yeast; pub struct LanguageSpec { pub prefix: &'static str, pub ts_language: tree_sitter::Language, pub node_types: &'static str, + /// Optional yeast desugaring configuration. When set, the parsed + /// tree is rewritten through yeast before TRAP extraction. The + /// config's `output_node_types_yaml` (if set) provides the schema + /// used both at runtime (for the rewriter) and for TRAP validation. + pub desugar: Option, pub file_globs: Vec, } @@ -85,9 +91,35 @@ impl Extractor { .collect(); let mut schemas = vec![]; + let mut yeast_runners = Vec::new(); for lang in &self.languages { - let schema = node_types::read_node_types_str(lang.prefix, lang.node_types)?; + let effective_node_types: String = + match lang.desugar.as_ref().and_then(|c| c.output_node_types_yaml) { + Some(yaml) => yeast::node_types_yaml::convert(yaml).map_err(|e| { + std::io::Error::other(format!( + "Failed to convert YAML node-types to JSON for {}: {e}", + lang.prefix + )) + })?, + None => lang.node_types.to_string(), + }; + let schema = node_types::read_node_types_str(lang.prefix, &effective_node_types)?; schemas.push(schema); + + // Build the yeast runner once per language so the YAML schema + // isn't re-parsed for every file. + let yeast_runner = lang + .desugar + .as_ref() + .map(|config| yeast::Runner::from_config(lang.ts_language.clone(), config)) + .transpose() + .map_err(|e| { + std::io::Error::other(format!( + "Failed to build desugaring runner for {}: {e}", + lang.prefix + )) + })?; + yeast_runners.push(yeast_runner); } // Construct a single globset containing all language globs, @@ -162,6 +194,7 @@ impl Extractor { &path, &source, &[], + yeast_runners[i].as_ref(), ); std::fs::create_dir_all(src_archive_file.parent().unwrap())?; std::fs::copy(&path, &src_archive_file)?; diff --git a/shared/tree-sitter-extractor/tests/integration_test.rs b/shared/tree-sitter-extractor/tests/integration_test.rs index 2b243ff7945..694eb526f39 100644 --- a/shared/tree-sitter-extractor/tests/integration_test.rs +++ b/shared/tree-sitter-extractor/tests/integration_test.rs @@ -13,6 +13,7 @@ fn simple_extractor() { prefix: "ql", ts_language: tree_sitter_ql::LANGUAGE.into(), node_types: tree_sitter_ql::NODE_TYPES, + desugar: None, file_globs: vec!["*.qll".into()], }; diff --git a/shared/tree-sitter-extractor/tests/multiple_languages.rs b/shared/tree-sitter-extractor/tests/multiple_languages.rs index 2e45e56754a..e345eec5828 100644 --- a/shared/tree-sitter-extractor/tests/multiple_languages.rs +++ b/shared/tree-sitter-extractor/tests/multiple_languages.rs @@ -13,12 +13,14 @@ fn multiple_language_extractor() { prefix: "ql", ts_language: tree_sitter_ql::LANGUAGE.into(), node_types: tree_sitter_ql::NODE_TYPES, + desugar: None, file_globs: vec!["*.qll".into()], }; let lang_json = simple::LanguageSpec { prefix: "json", ts_language: tree_sitter_json::LANGUAGE.into(), node_types: tree_sitter_json::NODE_TYPES, + desugar: None, file_globs: vec!["*.json".into(), "*Jsonfile".into()], }; From 82bbdee83234d082d1fd181b131f282e2b2794ba Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 4 May 2026 13:27:00 +0000 Subject: [PATCH 21/43] yeast: Support separate output node types in extractor generator Language and LanguageSpec gain optional output_node_types field. When set, the generator produces dbscheme/QL from the output types and the extractor validates TRAP against them. All existing extractors pass None (no behavior change). Ruby extract() calls gain vec![] for the new rules parameter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ql/extractor/src/generator.rs | 4 ++++ ruby/extractor/src/generator.rs | 2 ++ .../src/generator/language.rs | 5 +++++ .../tree-sitter-extractor/src/generator/mod.rs | 16 +++++++++++++++- 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ql/extractor/src/generator.rs b/ql/extractor/src/generator.rs index 650e11c138b..96ce5319dd1 100644 --- a/ql/extractor/src/generator.rs +++ b/ql/extractor/src/generator.rs @@ -21,18 +21,22 @@ pub fn run(options: Options) -> std::io::Result<()> { Language { name: "QL".to_owned(), node_types: tree_sitter_ql::NODE_TYPES, + desugar: None, }, Language { name: "Dbscheme".to_owned(), node_types: tree_sitter_ql_dbscheme::NODE_TYPES, + desugar: None, }, Language { name: "Blame".to_owned(), node_types: tree_sitter_blame::NODE_TYPES, + desugar: None, }, Language { name: "JSON".to_owned(), node_types: tree_sitter_json::NODE_TYPES, + desugar: None, }, ]; diff --git a/ruby/extractor/src/generator.rs b/ruby/extractor/src/generator.rs index de1d0dbfd7e..0430afd103e 100644 --- a/ruby/extractor/src/generator.rs +++ b/ruby/extractor/src/generator.rs @@ -21,10 +21,12 @@ pub fn run(options: Options) -> std::io::Result<()> { Language { name: "Ruby".to_owned(), node_types: tree_sitter_ruby::NODE_TYPES, + desugar: None, }, Language { name: "Erb".to_owned(), node_types: tree_sitter_embedded_template::NODE_TYPES, + desugar: None, }, ]; diff --git a/shared/tree-sitter-extractor/src/generator/language.rs b/shared/tree-sitter-extractor/src/generator/language.rs index f0b0ed1790f..a95f750b572 100644 --- a/shared/tree-sitter-extractor/src/generator/language.rs +++ b/shared/tree-sitter-extractor/src/generator/language.rs @@ -1,4 +1,9 @@ pub struct Language { pub name: String, pub node_types: &'static str, + /// Optional yeast desugaring configuration. When set with an + /// `output_node_types_yaml`, the generator uses that YAML for the + /// dbscheme/QL library instead of `node_types`. The `rules` field is + /// unused at code-generation time; only the schema matters. + pub desugar: Option, } diff --git a/shared/tree-sitter-extractor/src/generator/mod.rs b/shared/tree-sitter-extractor/src/generator/mod.rs index 78e9e4a0b69..d2521c51b3e 100644 --- a/shared/tree-sitter-extractor/src/generator/mod.rs +++ b/shared/tree-sitter-extractor/src/generator/mod.rs @@ -6,6 +6,7 @@ use std::io::Write; use std::path::PathBuf; use crate::node_types; +use yeast; pub mod dbscheme; pub mod language; @@ -68,7 +69,20 @@ pub fn generate( let token_name = format!("{}_token", &prefix); let tokeninfo_name = format!("{}_tokeninfo", &prefix); let reserved_word_name = format!("{}_reserved_word", &prefix); - let nodes = node_types::read_node_types_str(&prefix, language.node_types)?; + let effective_node_types: String = match language + .desugar + .as_ref() + .and_then(|c| c.output_node_types_yaml) + { + Some(yaml) => yeast::node_types_yaml::convert(yaml).map_err(|e| { + std::io::Error::other(format!( + "Failed to convert YAML node-types to JSON for {}: {e}", + language.name + )) + })?, + None => language.node_types.to_string(), + }; + let nodes = node_types::read_node_types_str(&prefix, &effective_node_types)?; let (dbscheme_entries, mut ast_node_members, token_kinds) = convert_nodes(&nodes); ast_node_members.insert(&token_name); writeln!(&mut dbscheme_writer, "/*- {} dbscheme -*/", language.name)?; From 60dcf88b50305b8e4afc4f00bde1ec7caeb03fce Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 5 May 2026 12:26:57 +0000 Subject: [PATCH 22/43] yeast: Add Bazel build rules for yeast crates Add BUILD.bazel files for the yeast and yeast-macros crates, register them as dependencies of the shared tree-sitter extractor, and refresh the vendored crate dependencies via update_tree_sitter_extractors_deps.sh. --- Cargo.lock | 14 +- MODULE.bazel | 4 +- .../tree_sitter_extractors_deps/BUILD.bazel | 30 +++- ....cc-1.2.37.bazel => BUILD.cc-1.2.61.bazel} | 4 +- ...azel => BUILD.find-msvc-tools-0.1.9.bazel} | 2 +- .../BUILD.iana-time-zone-haiku-0.1.2.bazel | 2 +- ...9.bazel => BUILD.tree-sitter-0.26.8.bazel} | 8 +- ...tree-sitter-embedded-template-0.25.0.bazel | 2 +- .../BUILD.tree-sitter-json-0.24.8.bazel | 2 +- .../BUILD.tree-sitter-python-0.23.6.bazel | 166 ++++++++++++++++++ .../BUILD.tree-sitter-ql-0.23.1.bazel | 2 +- .../BUILD.tree-sitter-ruby-0.23.1.bazel | 2 +- .../BUILD.zstd-sys-2.0.16+zstd.1.5.7.bazel | 2 +- .../tree_sitter_extractors_deps/defs.bzl | 114 ++++++++++-- shared/tree-sitter-extractor/BUILD.bazel | 4 +- shared/yeast-macros/BUILD.bazel | 12 ++ shared/yeast/BUILD.bazel | 18 ++ 17 files changed, 346 insertions(+), 42 deletions(-) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.cc-1.2.37.bazel => BUILD.cc-1.2.61.bazel} (98%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.find-msvc-tools-0.1.1.bazel => BUILD.find-msvc-tools-0.1.9.bazel} (99%) rename misc/bazel/3rdparty/tree_sitter_extractors_deps/{BUILD.tree-sitter-0.25.9.bazel => BUILD.tree-sitter-0.26.8.bazel} (97%) create mode 100644 misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-python-0.23.6.bazel create mode 100644 shared/yeast-macros/BUILD.bazel create mode 100644 shared/yeast/BUILD.bazel diff --git a/Cargo.lock b/Cargo.lock index 38a3c806fb2..12be6b1cc43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -240,9 +240,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.37" +version = "1.2.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44" +checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" dependencies = [ "find-msvc-tools", "jobserver", @@ -755,9 +755,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.1" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixedbitset" @@ -2471,6 +2471,7 @@ version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ + "indexmap 2.11.4", "itoa", "memchr", "ryu", @@ -2853,13 +2854,14 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.24.7" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5387dffa7ffc7d2dae12b50c6f7aab8ff79d6210147c6613561fc3d474c6f75" +checksum = "887bd495d0582c5e3e0d8ece2233666169fa56a9644d172fc22ad179ab2d0538" dependencies = [ "cc", "regex", "regex-syntax", + "serde_json", "streaming-iterator", "tree-sitter-language", ] diff --git a/MODULE.bazel b/MODULE.bazel index 16b4a4691f8..e7474e9a393 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -141,14 +141,16 @@ use_repo( "vendor_ts__serde-1.0.228", "vendor_ts__serde_json-1.0.145", "vendor_ts__serde_with-3.14.1", + "vendor_ts__serde_yaml-0.9.34-deprecated", "vendor_ts__syn-2.0.106", "vendor_ts__toml-0.9.7", "vendor_ts__tracing-0.1.41", "vendor_ts__tracing-flame-0.2.0", "vendor_ts__tracing-subscriber-0.3.20", - "vendor_ts__tree-sitter-0.25.9", + "vendor_ts__tree-sitter-0.26.8", "vendor_ts__tree-sitter-embedded-template-0.25.0", "vendor_ts__tree-sitter-json-0.24.8", + "vendor_ts__tree-sitter-python-0.23.6", "vendor_ts__tree-sitter-ql-0.23.1", "vendor_ts__tree-sitter-ruby-0.23.1", "vendor_ts__triomphe-0.1.14", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel index a5cfeccdcea..27d36c221ea 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel @@ -529,6 +529,18 @@ alias( tags = ["manual"], ) +alias( + name = "serde_yaml-0.9.34+deprecated", + actual = "@vendor_ts__serde_yaml-0.9.34-deprecated//:serde_yaml", + tags = ["manual"], +) + +alias( + name = "serde_yaml", + actual = "@vendor_ts__serde_yaml-0.9.34-deprecated//:serde_yaml", + tags = ["manual"], +) + alias( name = "syn-2.0.106", actual = "@vendor_ts__syn-2.0.106//:syn", @@ -590,14 +602,14 @@ alias( ) alias( - name = "tree-sitter-0.25.9", - actual = "@vendor_ts__tree-sitter-0.25.9//:tree_sitter", + name = "tree-sitter-0.26.8", + actual = "@vendor_ts__tree-sitter-0.26.8//:tree_sitter", tags = ["manual"], ) alias( name = "tree-sitter", - actual = "@vendor_ts__tree-sitter-0.25.9//:tree_sitter", + actual = "@vendor_ts__tree-sitter-0.26.8//:tree_sitter", tags = ["manual"], ) @@ -625,6 +637,18 @@ alias( tags = ["manual"], ) +alias( + name = "tree-sitter-python-0.23.6", + actual = "@vendor_ts__tree-sitter-python-0.23.6//:tree_sitter_python", + tags = ["manual"], +) + +alias( + name = "tree-sitter-python", + actual = "@vendor_ts__tree-sitter-python-0.23.6//:tree_sitter_python", + tags = ["manual"], +) + alias( name = "tree-sitter-ql-0.23.1", actual = "@vendor_ts__tree-sitter-ql-0.23.1//:tree_sitter_ql", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.37.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.61.bazel similarity index 98% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.37.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.61.bazel index c747c1c3c4f..4071cd59243 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.37.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.cc-1.2.61.bazel @@ -96,9 +96,9 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "1.2.37", + version = "1.2.61", deps = [ - "@vendor_ts__find-msvc-tools-0.1.1//:find_msvc_tools", + "@vendor_ts__find-msvc-tools-0.1.9//:find_msvc_tools", "@vendor_ts__jobserver-0.1.34//:jobserver", "@vendor_ts__shlex-1.3.0//:shlex", ] + select({ diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.find-msvc-tools-0.1.1.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.find-msvc-tools-0.1.9.bazel similarity index 99% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.find-msvc-tools-0.1.1.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.find-msvc-tools-0.1.9.bazel index 8fc8c9a81e2..12cd2ecbe0c 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.find-msvc-tools-0.1.1.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.find-msvc-tools-0.1.9.bazel @@ -93,5 +93,5 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "0.1.1", + version = "0.1.9", ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.iana-time-zone-haiku-0.1.2.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.iana-time-zone-haiku-0.1.2.bazel index fe120c04689..582c31e06fb 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.iana-time-zone-haiku-0.1.2.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.iana-time-zone-haiku-0.1.2.bazel @@ -154,7 +154,7 @@ cargo_build_script( version = "0.1.2", visibility = ["//visibility:private"], deps = [ - "@vendor_ts__cc-1.2.37//:cc", + "@vendor_ts__cc-1.2.61//:cc", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.25.9.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.26.8.bazel similarity index 97% rename from misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.25.9.bazel rename to misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.26.8.bazel index fd97779c54c..98cdfaa4d2f 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.25.9.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-0.26.8.bazel @@ -101,12 +101,12 @@ rust_library( "@rules_rust//rust/platform:x86_64-unknown-uefi": [], "//conditions:default": ["@platforms//:incompatible"], }), - version = "0.25.9", + version = "0.26.8", deps = [ "@vendor_ts__regex-1.11.3//:regex", "@vendor_ts__regex-syntax-0.8.6//:regex_syntax", "@vendor_ts__streaming-iterator-0.1.9//:streaming_iterator", - "@vendor_ts__tree-sitter-0.25.9//:build_script_build", + "@vendor_ts__tree-sitter-0.26.8//:build_script_build", "@vendor_ts__tree-sitter-language-0.1.5//:tree_sitter_language", ], ) @@ -164,10 +164,10 @@ cargo_build_script( "noclippy", "norustfmt", ], - version = "0.25.9", + version = "0.26.8", visibility = ["//visibility:private"], deps = [ - "@vendor_ts__cc-1.2.37//:cc", + "@vendor_ts__cc-1.2.61//:cc", "@vendor_ts__serde_json-1.0.145//:serde_json", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.25.0.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.25.0.bazel index c9dd60b03c0..57cf6cd860b 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.25.0.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-embedded-template-0.25.0.bazel @@ -155,7 +155,7 @@ cargo_build_script( version = "0.25.0", visibility = ["//visibility:private"], deps = [ - "@vendor_ts__cc-1.2.37//:cc", + "@vendor_ts__cc-1.2.61//:cc", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-json-0.24.8.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-json-0.24.8.bazel index 6b9a7bf0582..245539d02e7 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-json-0.24.8.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-json-0.24.8.bazel @@ -155,7 +155,7 @@ cargo_build_script( version = "0.24.8", visibility = ["//visibility:private"], deps = [ - "@vendor_ts__cc-1.2.37//:cc", + "@vendor_ts__cc-1.2.61//:cc", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-python-0.23.6.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-python-0.23.6.bazel new file mode 100644 index 00000000000..fc7a098193a --- /dev/null +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-python-0.23.6.bazel @@ -0,0 +1,166 @@ +############################################################################### +# @generated +# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To +# regenerate this file, run the following: +# +# bazel run @@//misc/bazel/3rdparty:vendor_tree_sitter_extractors +############################################################################### + +load( + "@rules_rust//cargo:defs.bzl", + "cargo_build_script", + "cargo_toml_env_vars", +) +load("@rules_rust//rust:defs.bzl", "rust_library") + +package(default_visibility = ["//visibility:public"]) + +cargo_toml_env_vars( + name = "cargo_toml_env_vars", + src = "Cargo.toml", +) + +rust_library( + name = "tree_sitter_python", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_root = "bindings/rust/lib.rs", + edition = "2021", + rustc_env_files = [ + ":cargo_toml_env_vars", + ], + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=tree-sitter-python", + "manual", + "noclippy", + "norustfmt", + ], + target_compatible_with = select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [], + "@rules_rust//rust/platform:aarch64-apple-ios": [], + "@rules_rust//rust/platform:aarch64-apple-ios-sim": [], + "@rules_rust//rust/platform:aarch64-linux-android": [], + "@rules_rust//rust/platform:aarch64-pc-windows-msvc": [], + "@rules_rust//rust/platform:aarch64-unknown-fuchsia": [], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [], + "@rules_rust//rust/platform:aarch64-unknown-uefi": [], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:arm-unknown-linux-musleabi": [], + "@rules_rust//rust/platform:armv7-linux-androideabi": [], + "@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:i686-apple-darwin": [], + "@rules_rust//rust/platform:i686-linux-android": [], + "@rules_rust//rust/platform:i686-pc-windows-msvc": [], + "@rules_rust//rust/platform:i686-unknown-freebsd": [], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [], + "@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [], + "@rules_rust//rust/platform:thumbv7em-none-eabi": [], + "@rules_rust//rust/platform:thumbv8m.main-none-eabi": [], + "@rules_rust//rust/platform:wasm32-unknown-emscripten": [], + "@rules_rust//rust/platform:wasm32-unknown-unknown": [], + "@rules_rust//rust/platform:wasm32-wasip1": [], + "@rules_rust//rust/platform:wasm32-wasip1-threads": [], + "@rules_rust//rust/platform:wasm32-wasip2": [], + "@rules_rust//rust/platform:x86_64-apple-darwin": [], + "@rules_rust//rust/platform:x86_64-apple-ios": [], + "@rules_rust//rust/platform:x86_64-linux-android": [], + "@rules_rust//rust/platform:x86_64-pc-windows-msvc": [], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [], + "@rules_rust//rust/platform:x86_64-unknown-fuchsia": [], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-none": [], + "@rules_rust//rust/platform:x86_64-unknown-uefi": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + version = "0.23.6", + deps = [ + "@vendor_ts__tree-sitter-language-0.1.5//:tree_sitter_language", + "@vendor_ts__tree-sitter-python-0.23.6//:build_script_build", + ], +) + +cargo_build_script( + name = "_bs", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + "**/*.rs", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_name = "build_script_build", + crate_root = "bindings/rust/build.rs", + data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + edition = "2021", + pkg_name = "tree-sitter-python", + rustc_env_files = [ + ":cargo_toml_env_vars", + ], + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=tree-sitter-python", + "manual", + "noclippy", + "norustfmt", + ], + version = "0.23.6", + visibility = ["//visibility:private"], + deps = [ + "@vendor_ts__cc-1.2.61//:cc", + ], +) + +alias( + name = "build_script_build", + actual = ":_bs", + tags = ["manual"], +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-ql-0.23.1.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-ql-0.23.1.bazel index 0b7ce3a9a29..6d68d04cf00 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-ql-0.23.1.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-ql-0.23.1.bazel @@ -155,7 +155,7 @@ cargo_build_script( version = "0.23.1", visibility = ["//visibility:private"], deps = [ - "@vendor_ts__cc-1.2.37//:cc", + "@vendor_ts__cc-1.2.61//:cc", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-ruby-0.23.1.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-ruby-0.23.1.bazel index f939b4b9493..855b7513311 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-ruby-0.23.1.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-ruby-0.23.1.bazel @@ -155,7 +155,7 @@ cargo_build_script( version = "0.23.1", visibility = ["//visibility:private"], deps = [ - "@vendor_ts__cc-1.2.37//:cc", + "@vendor_ts__cc-1.2.61//:cc", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-sys-2.0.16+zstd.1.5.7.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-sys-2.0.16+zstd.1.5.7.bazel index 32a06f94788..f2a70faf464 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-sys-2.0.16+zstd.1.5.7.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.zstd-sys-2.0.16+zstd.1.5.7.bazel @@ -165,7 +165,7 @@ cargo_build_script( version = "2.0.16+zstd.1.5.7", visibility = ["//visibility:private"], deps = [ - "@vendor_ts__cc-1.2.37//:cc", + "@vendor_ts__cc-1.2.61//:cc", "@vendor_ts__pkg-config-0.3.32//:pkg_config", ], ) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl index bf11bc6c82f..d1da77819f3 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl @@ -303,7 +303,7 @@ _NORMAL_DEPENDENCIES = { "serde_json": Label("@vendor_ts__serde_json-1.0.145//:serde_json"), "tracing": Label("@vendor_ts__tracing-0.1.41//:tracing"), "tracing-subscriber": Label("@vendor_ts__tracing-subscriber-0.3.20//:tracing_subscriber"), - "tree-sitter": Label("@vendor_ts__tree-sitter-0.25.9//:tree_sitter"), + "tree-sitter": Label("@vendor_ts__tree-sitter-0.26.8//:tree_sitter"), "tree-sitter-embedded-template": Label("@vendor_ts__tree-sitter-embedded-template-0.25.0//:tree_sitter_embedded_template"), "tree-sitter-ruby": Label("@vendor_ts__tree-sitter-ruby-0.23.1//:tree_sitter_ruby"), }, @@ -381,10 +381,28 @@ _NORMAL_DEPENDENCIES = { "serde_json": Label("@vendor_ts__serde_json-1.0.145//:serde_json"), "tracing": Label("@vendor_ts__tracing-0.1.41//:tracing"), "tracing-subscriber": Label("@vendor_ts__tracing-subscriber-0.3.20//:tracing_subscriber"), - "tree-sitter": Label("@vendor_ts__tree-sitter-0.25.9//:tree_sitter"), + "tree-sitter": Label("@vendor_ts__tree-sitter-0.26.8//:tree_sitter"), "zstd": Label("@vendor_ts__zstd-0.13.3//:zstd"), }, }, + "shared/yeast": { + _COMMON_CONDITION: { + "clap": Label("@vendor_ts__clap-4.5.48//:clap"), + "serde": Label("@vendor_ts__serde-1.0.228//:serde"), + "serde_json": Label("@vendor_ts__serde_json-1.0.145//:serde_json"), + "serde_yaml": Label("@vendor_ts__serde_yaml-0.9.34-deprecated//:serde_yaml"), + "tree-sitter": Label("@vendor_ts__tree-sitter-0.26.8//:tree_sitter"), + "tree-sitter-python": Label("@vendor_ts__tree-sitter-python-0.23.6//:tree_sitter_python"), + "tree-sitter-ruby": Label("@vendor_ts__tree-sitter-ruby-0.23.1//:tree_sitter_ruby"), + }, + }, + "shared/yeast-macros": { + _COMMON_CONDITION: { + "proc-macro2": Label("@vendor_ts__proc-macro2-1.0.101//:proc_macro2"), + "quote": Label("@vendor_ts__quote-1.0.41//:quote"), + "syn": Label("@vendor_ts__syn-2.0.106//:syn"), + }, + }, } _NORMAL_ALIASES = { @@ -411,6 +429,14 @@ _NORMAL_ALIASES = { _COMMON_CONDITION: { }, }, + "shared/yeast": { + _COMMON_CONDITION: { + }, + }, + "shared/yeast-macros": { + _COMMON_CONDITION: { + }, + }, } _NORMAL_DEV_DEPENDENCIES = { @@ -431,6 +457,10 @@ _NORMAL_DEV_DEPENDENCIES = { "tree-sitter-ql": Label("@vendor_ts__tree-sitter-ql-0.23.1//:tree_sitter_ql"), }, }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _NORMAL_DEV_ALIASES = { @@ -448,6 +478,10 @@ _NORMAL_DEV_ALIASES = { _COMMON_CONDITION: { }, }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _PROC_MACRO_DEPENDENCIES = { @@ -463,6 +497,10 @@ _PROC_MACRO_DEPENDENCIES = { }, "shared/tree-sitter-extractor": { }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _PROC_MACRO_ALIASES = { @@ -478,6 +516,10 @@ _PROC_MACRO_ALIASES = { }, "shared/tree-sitter-extractor": { }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _PROC_MACRO_DEV_DEPENDENCIES = { @@ -493,6 +535,10 @@ _PROC_MACRO_DEV_DEPENDENCIES = { }, "shared/tree-sitter-extractor": { }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _PROC_MACRO_DEV_ALIASES = { @@ -510,6 +556,10 @@ _PROC_MACRO_DEV_ALIASES = { _COMMON_CONDITION: { }, }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _BUILD_DEPENDENCIES = { @@ -525,6 +575,10 @@ _BUILD_DEPENDENCIES = { }, "shared/tree-sitter-extractor": { }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _BUILD_ALIASES = { @@ -540,6 +594,10 @@ _BUILD_ALIASES = { }, "shared/tree-sitter-extractor": { }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _BUILD_PROC_MACRO_DEPENDENCIES = { @@ -555,6 +613,10 @@ _BUILD_PROC_MACRO_DEPENDENCIES = { }, "shared/tree-sitter-extractor": { }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _BUILD_PROC_MACRO_ALIASES = { @@ -570,6 +632,10 @@ _BUILD_PROC_MACRO_ALIASES = { }, "shared/tree-sitter-extractor": { }, + "shared/yeast": { + }, + "shared/yeast-macros": { + }, } _CONDITIONS = { @@ -923,12 +989,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__cc-1.2.37", - sha256 = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44", + name = "vendor_ts__cc-1.2.61", + sha256 = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d", type = "tar.gz", - urls = ["https://static.crates.io/crates/cc/1.2.37/download"], - strip_prefix = "cc-1.2.37", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.cc-1.2.37.bazel"), + urls = ["https://static.crates.io/crates/cc/1.2.61/download"], + strip_prefix = "cc-1.2.61", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.cc-1.2.61.bazel"), ) maybe( @@ -1373,12 +1439,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__find-msvc-tools-0.1.1", - sha256 = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d", + name = "vendor_ts__find-msvc-tools-0.1.9", + sha256 = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582", type = "tar.gz", - urls = ["https://static.crates.io/crates/find-msvc-tools/0.1.1/download"], - strip_prefix = "find-msvc-tools-0.1.1", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.find-msvc-tools-0.1.1.bazel"), + urls = ["https://static.crates.io/crates/find-msvc-tools/0.1.9/download"], + strip_prefix = "find-msvc-tools-0.1.9", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.find-msvc-tools-0.1.9.bazel"), ) maybe( @@ -3363,12 +3429,12 @@ def crate_repositories(): maybe( http_archive, - name = "vendor_ts__tree-sitter-0.25.9", - sha256 = "ccd2a058a86cfece0bf96f7cce1021efef9c8ed0e892ab74639173e5ed7a34fa", + name = "vendor_ts__tree-sitter-0.26.8", + sha256 = "887bd495d0582c5e3e0d8ece2233666169fa56a9644d172fc22ad179ab2d0538", type = "tar.gz", - urls = ["https://static.crates.io/crates/tree-sitter/0.25.9/download"], - strip_prefix = "tree-sitter-0.25.9", - build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.tree-sitter-0.25.9.bazel"), + urls = ["https://static.crates.io/crates/tree-sitter/0.26.8/download"], + strip_prefix = "tree-sitter-0.26.8", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.tree-sitter-0.26.8.bazel"), ) maybe( @@ -3401,6 +3467,16 @@ def crate_repositories(): build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.tree-sitter-language-0.1.5.bazel"), ) + maybe( + http_archive, + name = "vendor_ts__tree-sitter-python-0.23.6", + sha256 = "3d065aaa27f3aaceaf60c1f0e0ac09e1cb9eb8ed28e7bcdaa52129cffc7f4b04", + type = "tar.gz", + urls = ["https://static.crates.io/crates/tree-sitter-python/0.23.6/download"], + strip_prefix = "tree-sitter-python-0.23.6", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.tree-sitter-python-0.23.6.bazel"), + ) + maybe( http_archive, name = "vendor_ts__tree-sitter-ql-0.23.1", @@ -4152,13 +4228,15 @@ def crate_repositories(): struct(repo = "vendor_ts__serde-1.0.228", is_dev_dep = False), struct(repo = "vendor_ts__serde_json-1.0.145", is_dev_dep = False), struct(repo = "vendor_ts__serde_with-3.14.1", is_dev_dep = False), + struct(repo = "vendor_ts__serde_yaml-0.9.34-deprecated", is_dev_dep = False), struct(repo = "vendor_ts__syn-2.0.106", is_dev_dep = False), struct(repo = "vendor_ts__toml-0.9.7", is_dev_dep = False), struct(repo = "vendor_ts__tracing-0.1.41", is_dev_dep = False), struct(repo = "vendor_ts__tracing-flame-0.2.0", is_dev_dep = False), struct(repo = "vendor_ts__tracing-subscriber-0.3.20", is_dev_dep = False), - struct(repo = "vendor_ts__tree-sitter-0.25.9", is_dev_dep = False), + struct(repo = "vendor_ts__tree-sitter-0.26.8", is_dev_dep = False), struct(repo = "vendor_ts__tree-sitter-embedded-template-0.25.0", is_dev_dep = False), + struct(repo = "vendor_ts__tree-sitter-python-0.23.6", is_dev_dep = False), struct(repo = "vendor_ts__tree-sitter-ruby-0.23.1", is_dev_dep = False), struct(repo = "vendor_ts__triomphe-0.1.14", is_dev_dep = False), struct(repo = "vendor_ts__ungrammar-1.16.1", is_dev_dep = False), diff --git a/shared/tree-sitter-extractor/BUILD.bazel b/shared/tree-sitter-extractor/BUILD.bazel index ee19d8e5c77..5539641e90e 100644 --- a/shared/tree-sitter-extractor/BUILD.bazel +++ b/shared/tree-sitter-extractor/BUILD.bazel @@ -12,7 +12,9 @@ rust_library( compile_data = [ "src/generator/prefix.dbscheme", ], - deps = all_crate_deps(), + deps = all_crate_deps() + [ + "//shared/yeast", + ], ) alias( diff --git a/shared/yeast-macros/BUILD.bazel b/shared/yeast-macros/BUILD.bazel new file mode 100644 index 00000000000..71bc6eb288a --- /dev/null +++ b/shared/yeast-macros/BUILD.bazel @@ -0,0 +1,12 @@ +load("@rules_rust//rust:defs.bzl", "rust_proc_macro") +load("//misc/bazel/3rdparty/tree_sitter_extractors_deps:defs.bzl", "aliases", "all_crate_deps") + +exports_files(["Cargo.toml"]) + +rust_proc_macro( + name = "yeast-macros", + srcs = glob(["src/**/*.rs"]), + aliases = aliases(), + visibility = ["//visibility:public"], + deps = all_crate_deps(), +) diff --git a/shared/yeast/BUILD.bazel b/shared/yeast/BUILD.bazel new file mode 100644 index 00000000000..fe0b01bb87b --- /dev/null +++ b/shared/yeast/BUILD.bazel @@ -0,0 +1,18 @@ +load("@rules_rust//rust:defs.bzl", "rust_library") +load("//misc/bazel/3rdparty/tree_sitter_extractors_deps:defs.bzl", "aliases", "all_crate_deps") + +exports_files(["Cargo.toml"]) + +rust_library( + name = "yeast", + srcs = glob( + ["src/**/*.rs"], + exclude = ["src/bin/**"], + ), + aliases = aliases(), + proc_macro_deps = [ + "//shared/yeast-macros", + ], + visibility = ["//visibility:public"], + deps = all_crate_deps(), +) From a0a0e9e9a75b3290dbd662b2366fed8c03f15168 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 6 May 2026 11:45:53 +0000 Subject: [PATCH 23/43] yeast: Add test for chained rules with output-only kinds Adds a regression test verifying that desugaring rules can chain across output-only node kinds: a first rule rewrites an input kind to an output-only kind, and a second rule then rewrites that output-only kind into another output-only kind. This exercises the schema lookup for query patterns whose root kind is not present in the input tree-sitter grammar. --- shared/yeast/tests/node-types.yml | 12 ++++++++++- shared/yeast/tests/test.rs | 35 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/shared/yeast/tests/node-types.yml b/shared/yeast/tests/node-types.yml index 978ef147543..8416d377ee8 100644 --- a/shared/yeast/tests/node-types.yml +++ b/shared/yeast/tests/node-types.yml @@ -4,7 +4,7 @@ named: program: - stmt*: [assignment, call, identifier, for] + stmt*: [assignment, call, identifier, for, first_node, second_node] assignment: left: [identifier, left_assignment_list] @@ -50,6 +50,16 @@ named: identifier: integer: + # Output-only kinds, used by tests of chained desugaring rules. + # Neither exists in the input tree-sitter-ruby grammar. + first_node: + left: [identifier, integer] + right: [identifier, integer] + + second_node: + left: [identifier, integer] + right: [identifier, integer] + unnamed: - "=" - "," diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index 406c990a8bd..e4485857bff 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -347,6 +347,41 @@ fn test_shorthand_rule() { ); } +#[test] +fn test_chained_rules_output_only_kind() { + // Exercise rule chaining where an intermediate kind exists only in the + // output schema (not in the input tree-sitter grammar): + // assignment → first_node (input → output-only) + // first_node → second_node (output-only → output-only) + // The matcher must look up `first_node` against the schema, which only + // knows about it via the YAML node-types file. + let assignment_to_first = yeast::rule!( + (assignment + left: (_) @left + right: (_) @right + ) + => first_node + ); + let first_to_second = yeast::rule!( + (first_node + left: (_) @left + right: (_) @right + ) + => second_node + ); + + let dump = run_and_dump("x = 1", vec![assignment_to_first, first_to_second]); + assert_dump_eq( + &dump, + r#" + program + second_node + left: identifier "x" + right: integer "1" + "#, + ); +} + // ---- Cursor tests ---- #[test] From 9a9483697445b4ab52203a7d280500131466ea50 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 6 May 2026 12:33:18 +0000 Subject: [PATCH 24/43] yeast: Add per-rule .repeated() flag to opt into iterative matching Previously, after a rule fired the engine would always re-try that same rule on the result root. A rule whose output matched its own query (intentionally or by accident) would loop until the global MAX_REWRITE_DEPTH safety net kicked in. Make the default behavior fire-once-per-node: after a rule fires on node N, the engine no longer tries that same rule on the result root. Other rules and child traversal are unaffected. Rules that intentionally rewrite iteratively can opt into the old behavior via the new Rule::repeated() builder method. Add two regression tests using a self-swapping assignment rule: - with .repeated(), the swap loops and trips the depth limit - without it (default), the swap fires once and terminates --- shared/yeast/doc/yeast.md | 16 +++++++++++ shared/yeast/src/lib.rs | 38 ++++++++++++++++++++++--- shared/yeast/tests/test.rs | 57 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 4 deletions(-) diff --git a/shared/yeast/doc/yeast.md b/shared/yeast/doc/yeast.md index d49ff96f11d..45e0006f909 100644 --- a/shared/yeast/doc/yeast.md +++ b/shared/yeast/doc/yeast.md @@ -61,6 +61,22 @@ rule matches, the node is kept and its children are processed recursively. A rule can replace one node with zero nodes (deletion), one node (rewriting), or multiple nodes (expansion). +By default a rule fires **at most once on a given node**: after firing, the +engine will not re-try that same rule on the result root. Other rules may +still fire on the result, and the rule may still fire on different nodes +(including the result's children). To opt into iterative behaviour — when a +rule's output is intentionally re-matched by the same rule — call +`.repeated()` on the constructed `Rule`: + +```rust +let r = yeast::rule!((foo ...) => (foo ...)).repeated(); +``` + +Without `.repeated()`, a rule whose output happens to match its own query +simply fires once and stops. With `.repeated()`, the rule is allowed to +re-match indefinitely; the runner still enforces a global rewrite-depth +limit (currently 100) as a safety net against accidental cycles. + ## Query language Queries use a syntax inspired by diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index 46629e19840..0c66a0c8521 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -471,11 +471,29 @@ pub type Transform = Box< pub struct Rule { query: QueryNode, transform: Transform, + /// If true, after this rule fires on a node the engine will try to + /// re-apply this same rule on the result root. Defaults to false: + /// each rule fires at most once on a given node, which prevents + /// accidental loops where a rule's output matches its own query. + repeated: bool, } impl Rule { pub fn new(query: QueryNode, transform: Transform) -> Self { - Self { query, transform } + Self { + query, + transform, + repeated: false, + } + } + + /// Mark this rule as allowed to fire multiple times on the same node. + /// Use when the rule is intentionally iterative (its output may match + /// its own query). Without this, a rule fires at most once per node; + /// other rules can still fire on the result. + pub fn repeated(mut self) -> Self { + self.repeated = true; + self } fn try_rule( @@ -537,7 +555,7 @@ fn apply_rules( fresh: &tree_builder::FreshScope, ) -> Result, String> { let index = RuleIndex::new(rules); - apply_rules_inner(&index, ast, id, fresh, 0) + apply_rules_inner(&index, ast, id, fresh, 0, None) } fn apply_rules_inner( @@ -546,6 +564,7 @@ fn apply_rules_inner( id: Id, fresh: &tree_builder::FreshScope, rewrite_depth: usize, + skip_rule: Option<*const Rule>, ) -> Result, String> { if rewrite_depth > MAX_REWRITE_DEPTH { return Err(format!( @@ -556,7 +575,16 @@ fn apply_rules_inner( let node_kind = ast.get_node(id).map(|n| n.kind()).unwrap_or(""); for rule in index.rules_for_kind(node_kind) { + let rule_ptr = *rule as *const Rule; + if Some(rule_ptr) == skip_rule { + continue; + } if let Some(result_node) = rule.try_rule(ast, id, fresh)? { + // For non-repeated rules, suppress further application of *this* + // rule on the result root, so a rule whose output matches its own + // query doesn't loop. Other rules and child traversal are + // unaffected. + 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( @@ -565,6 +593,7 @@ fn apply_rules_inner( node, fresh, rewrite_depth + 1, + next_skip, )?); } return Ok(results); @@ -579,13 +608,14 @@ fn apply_rules_inner( .collect(); // recursively descend into all the fields - // Child traversal does not increment rewrite depth + // Child traversal does not increment rewrite depth and starts fresh + // (no rule is skipped on child subtrees). let mut changed = false; let mut new_fields = BTreeMap::new(); for (field_id, children) in field_entries { let mut new_children = Vec::new(); for child_id in children { - let result = apply_rules_inner(index, ast, child_id, fresh, rewrite_depth)?; + let result = apply_rules_inner(index, ast, child_id, fresh, rewrite_depth, None)?; if result.len() != 1 || result[0] != child_id { changed = true; } diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index e4485857bff..aebda65eae4 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -22,6 +22,18 @@ fn run_and_dump(input: &str, rules: Vec) -> String { dump_ast(&ast, ast.get_root(), input) } +/// Helper: like `run_and_dump`, but returns the runner error (if any) +/// instead of unwrapping. +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 runner = Runner::with_schema(lang, &schema, &rules); + runner + .run(input) + .expect_err("expected runner to return an error") +} + /// 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 @@ -382,6 +394,51 @@ fn test_chained_rules_output_only_kind() { ); } +// A rule that swaps `assignment.left` and `assignment.right`. Each +// application produces another `assignment` whose query the rule +// matches again, so without the once-per-node default it would loop. +fn swap_assignment_rule() -> Rule { + yeast::rule!( + (assignment + left: (_) @left + right: (_) @right + ) + => + (assignment + left: {right} + right: {left} + ) + ) +} + +#[test] +fn test_repeated_rule_hits_depth_limit() { + // With `.repeated()` the rule is allowed to fire on its own output, + // which cycles forever and trips the rewrite-depth safety net. + let err = run_and_get_error("x = 1", vec![swap_assignment_rule().repeated()]); + assert!( + err.contains("exceeded maximum rewrite depth"), + "expected depth-limit error, got: {err}" + ); +} + +#[test] +fn test_default_rule_fires_at_most_once_per_node() { + // Without `.repeated()` (the default), a rule fires at most once on a + // given node. The swap therefore happens exactly once and the desugaring + // terminates cleanly. + let dump = run_and_dump("x = 1", vec![swap_assignment_rule()]); + assert_dump_eq( + &dump, + r#" + program + assignment + left: integer "1" + right: identifier "x" + "#, + ); +} + // ---- Cursor tests ---- #[test] From 957c89b478ded5d3d753e7dff861b6b1584c582f Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 6 May 2026 15:30:54 +0000 Subject: [PATCH 25/43] yeast: Support multi-phase desugaring via DesugaringConfig::add_phase Extend the desugaring config from a single flat list of rules to an ordered sequence of named Phases. Each phase runs to completion (a full traversal applying its rules) before the next phase starts. Rules in different phases never compete for matches. The config is built via the new chainable API: DesugaringConfig::new() .add_phase("cleanup", cleanup_rules) .add_phase("desugar", desugar_rules) .with_output_node_types_yaml(yaml); Single-phase configs are just .add_phase(...) called once. A single FreshScope is shared across phases so generated identifier names (e.g. $tmp-N) are unique throughout the run. Phase names appear in error messages, e.g. "Phase `desugar`: exceeded maximum rewrite depth". Add two regression tests: one verifying basic two-phase chained desugaring, and one verifying that errors include the failing phase name. --- shared/yeast/doc/yeast.md | 14 ++++- shared/yeast/src/lib.rs | 109 +++++++++++++++++++++++++------------ shared/yeast/tests/test.rs | 76 +++++++++++++++++++++++++- 3 files changed, 158 insertions(+), 41 deletions(-) diff --git a/shared/yeast/doc/yeast.md b/shared/yeast/doc/yeast.md index 45e0006f909..bc243a4b274 100644 --- a/shared/yeast/doc/yeast.md +++ b/shared/yeast/doc/yeast.md @@ -319,11 +319,16 @@ capture name to a field of the same name on the output node. ## Integration with the extractor A YEAST desugaring pass is configured with a [`DesugaringConfig`], which -carries the rules and an optional output node-types schema (in YAML -format). Attach it to a language spec to enable rewriting: +carries one or more named [`Phase`]s of rules and an optional output +node-types schema (in YAML format). Each phase is a complete traversal +that runs to completion before the next phase starts; rules in different +phases never compete for matches. Attach the config to a language spec +to enable rewriting: ```rust -let desugar = yeast::DesugaringConfig::new(my_rules) +let desugar = yeast::DesugaringConfig::new() + .add_phase("cleanup", cleanup_rules()) + .add_phase("desugar", desugar_rules()) .with_output_node_types_yaml(include_str!("output-node-types.yml")); let lang = simple::LanguageSpec { @@ -335,6 +340,9 @@ 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. + 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/lib.rs b/shared/yeast/src/lib.rs index 0c66a0c8521..8c0aa6545b5 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -635,16 +635,46 @@ fn apply_rules_inner( Ok(vec![ast.nodes.len() - 1]) } -/// Configuration for a desugaring pass: a set of rules and an optional -/// output node-types schema (in YAML format). +/// 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 +/// different phases never compete because they don't see each other's input. +pub struct Phase { + /// Name used in error messages. + pub name: String, + pub rules: Vec, +} + +impl Phase { + pub fn new(name: impl Into, rules: Vec) -> Self { + Self { + name: name.into(), + rules, + } + } +} + +/// Configuration for a desugaring pass: an ordered list of [`Phase`]s and +/// an optional output node-types schema (in YAML format). /// /// When attached to a `LanguageSpec` (in the shared tree-sitter extractor), /// enables yeast-based AST rewriting before TRAP extraction. The same YAML /// is used both to validate TRAP output (via JSON conversion) and to /// resolve output-only node kinds and fields at runtime. +/// +/// Construct with `DesugaringConfig::new()` and add phases via +/// `add_phase`: +/// +/// ```ignore +/// let config = yeast::DesugaringConfig::new() +/// .add_phase("cleanup", cleanup_rules) +/// .add_phase("desugar", desugar_rules) +/// .with_output_node_types_yaml(yaml); +/// ``` +#[derive(Default)] pub struct DesugaringConfig { - /// Rules to apply during desugaring. - pub rules: Vec, + /// Phases of rule application, applied in order. + pub phases: Vec, /// Output node-types in YAML format. If `None`, the input grammar's /// node types are used (i.e. the desugared AST has the same node types /// as the tree-sitter grammar). @@ -652,11 +682,16 @@ pub struct DesugaringConfig { } impl DesugaringConfig { - pub fn new(rules: Vec) -> Self { - Self { - rules, - output_node_types_yaml: None, - } + /// Create an empty configuration. Add phases via [`add_phase`] and an + /// optional output schema via [`with_output_node_types_yaml`]. + pub fn new() -> Self { + 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)); + self } pub fn with_output_node_types_yaml(mut self, yaml: &'static str) -> Self { @@ -678,17 +713,17 @@ impl DesugaringConfig { pub struct Runner<'a> { language: tree_sitter::Language, schema: schema::Schema, - rules: &'a [Rule], + phases: &'a [Phase], } impl<'a> Runner<'a> { /// Create a runner using the input grammar's schema for output. - pub fn new(language: tree_sitter::Language, rules: &'a [Rule]) -> Self { + pub fn new(language: tree_sitter::Language, phases: &'a [Phase]) -> Self { let schema = schema::Schema::from_language(&language); Self { language, schema, - rules, + phases, } } @@ -696,12 +731,12 @@ impl<'a> Runner<'a> { pub fn with_schema( language: tree_sitter::Language, schema: &schema::Schema, - rules: &'a [Rule], + phases: &'a [Phase], ) -> Self { Self { language, schema: schema.clone(), - rules, + phases, } } @@ -714,27 +749,17 @@ impl<'a> Runner<'a> { Ok(Self { language, schema, - rules: &config.rules, + phases: &config.phases, }) } pub fn run_from_tree(&self, tree: &tree_sitter::Tree) -> Result { - let fresh = tree_builder::FreshScope::new(); let mut ast = Ast::from_tree_with_schema(self.schema.clone(), tree, &self.language); - let root = ast.get_root(); - let res = apply_rules(self.rules, &mut ast, root, &fresh)?; - if res.len() != 1 { - return Err(format!( - "Expected exactly one result node, got {}", - res.len() - )); - } - ast.set_root(res[0]); + self.run_phases(&mut ast)?; Ok(ast) } pub fn run(&self, input: &str) -> Result { - let fresh = tree_builder::FreshScope::new(); let mut parser = tree_sitter::Parser::new(); parser .set_language(&self.language) @@ -743,15 +768,29 @@ impl<'a> Runner<'a> { .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 root = ast.get_root(); - let res = apply_rules(self.rules, &mut ast, root, &fresh)?; - if res.len() != 1 { - return Err(format!( - "Expected exactly one result node, got {}", - res.len() - )); - } - ast.set_root(res[0]); + self.run_phases(&mut ast)?; Ok(ast) } + + /// Apply each phase in turn to the AST, threading the root through. + /// A single `FreshScope` is shared across phases so that fresh + /// identifiers generated in different phases don't collide. + fn run_phases(&self, ast: &mut Ast) -> Result<(), String> { + 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))?; + if res.len() != 1 { + return Err(format!( + "Phase `{}`: expected exactly one result node, got {}", + phase.name, + res.len() + )); + } + root = res[0]; + } + ast.set_root(root); + Ok(()) + } } diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index aebda65eae4..badfe9ba5cb 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -12,12 +12,19 @@ fn parse_and_dump(input: &str) -> String { dump_ast(&ast, ast.get_root(), input) } -/// Helper: parse Ruby source with a custom output schema and rules, return dump. +/// 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)]) +} + +/// Helper: parse Ruby source with a custom output schema and multiple +/// rule phases, return dump. +fn run_phased_and_dump(input: &str, phases: 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 runner = Runner::with_schema(lang, &schema, &rules); + let runner = Runner::with_schema(lang, &schema, &phases); let ast = runner.run(input).unwrap(); dump_ast(&ast, ast.get_root(), input) } @@ -28,7 +35,8 @@ 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 runner = Runner::with_schema(lang, &schema, &rules); + let phases = vec![Phase::new("test", rules)]; + let runner = Runner::with_schema(lang, &schema, &phases); runner .run(input) .expect_err("expected runner to return an error") @@ -439,6 +447,68 @@ fn test_default_rule_fires_at_most_once_per_node() { ); } +// ---- Phase tests ---- + +#[test] +fn test_phased_desugaring() { + // Two phases that could equally have been a single one with chained + // rules. Splitting them makes the intent (cleanup, then desugar) + // explicit and provides per-phase error messages. + let cleanup = vec![yeast::rule!( + (assignment + left: (_) @left + right: (_) @right + ) + => first_node + )]; + let desugar = vec![yeast::rule!( + (first_node + left: (_) @left + right: (_) @right + ) + => second_node + )]; + + let dump = run_phased_and_dump( + "x = 1", + vec![ + Phase::new("cleanup", cleanup), + Phase::new("desugar", desugar), + ], + ); + assert_dump_eq( + &dump, + r#" + program + second_node + left: identifier "x" + right: integer "1" + "#, + ); +} + +#[test] +fn test_phase_error_includes_phase_name() { + // A repeated rule that loops; the error message should identify the + // phase that tripped the depth limit. + 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 runner = Runner::with_schema(lang, &schema, &phases); + let err = runner + .run("x = 1") + .expect_err("expected runner to return an error"); + assert!( + err.contains("Phase `buggy`"), + "error should mention the failing phase, got: {err}" + ); + assert!( + err.contains("exceeded maximum rewrite depth"), + "error should mention the depth limit, got: {err}" + ); +} + // ---- Cursor tests ---- #[test] From 33035dbfc8be4d6b2732b61f7c52cefeb5875b84 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Thu, 7 May 2026 11:06:43 +0100 Subject: [PATCH 26/43] Fix yaml formatting --- java/ql/lib/ext/org.apache.commons.io.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/org.apache.commons.io.model.yml b/java/ql/lib/ext/org.apache.commons.io.model.yml index f6ced2d2b85..7ef2f1f60e6 100644 --- a/java/ql/lib/ext/org.apache.commons.io.model.yml +++ b/java/ql/lib/ext/org.apache.commons.io.model.yml @@ -29,7 +29,7 @@ extensions: - ["org.apache.commons.io", "FileUtils", False, "forceMkdir", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "moveDirectory", "(File,File)", "", "Argument[0]", "path-injection", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "readFileToByteArray", "(File)", "", "Argument[0]", "path-injection", "ai-manual"] -- ["org.apache.commons.io", "FileUtils", False, "readFileToByteArray", "", "", "Argument[0]", "path-injection[read]", "ai-manual"] + - ["org.apache.commons.io", "FileUtils", False, "readFileToByteArray", "", "", "Argument[0]", "path-injection[read]", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "writeLines", "(File,String,Collection,String)", "", "Argument[3]", "file-content-store", "ai-manual"] - ["org.apache.commons.io", "FileUtils", False, "writeStringToFile", "(File,String,Charset,boolean)", "", "Argument[1]", "file-content-store", "ai-manual"] - ["org.apache.commons.io", "FileUtils", True, "copyInputStreamToFile", "(InputStream,File)", "", "Argument[0]", "file-content-store", "ai-manual"] From 48785a0a767f69265b82b350c0cbfde51c1ae260 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 7 May 2026 13:07:07 +0200 Subject: [PATCH 27/43] Cfg: Rework CFG for switch case patterns. --- .../controlflow/internal/ControlFlowGraph.qll | 2 +- .../lib/semmle/code/java/ControlFlowGraph.qll | 8 +- .../codeql/controlflow/ControlFlowGraph.qll | 89 ++++++++++--------- 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraph.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraph.qll index c44a3ef4a55..ca71e213e32 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraph.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraph.qll @@ -229,7 +229,7 @@ module Ast implements AstSig { final private class FinalCase = CS::Case; class Case extends FinalCase { - AstNode getAPattern() { result = this.getPattern() } + AstNode getPattern(int index) { result = this.getPattern() and index = 0 } Expr getGuard() { result = this.getCondition() } diff --git a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll index a1e071df10c..27f0102b3cf 100644 --- a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll @@ -153,10 +153,10 @@ private module Ast implements AstSig { } class Case extends AstNode instanceof J::SwitchCase { - /** Gets a pattern being matched by this case. */ - AstNode getAPattern() { - result = this.(PatternCase).getAPattern() or - result = this.(ConstCase).getValue(_) + /** Gets the pattern being matched by this case at the specified (zero-based) `index`. */ + AstNode getPattern(int index) { + result = this.(PatternCase).getPattern(index) or + result = this.(ConstCase).getValue(index) } /** Gets the guard expression of this case, if any. */ diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index 514a68cba47..17a01b7e371 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -255,8 +255,8 @@ signature module AstSig { /** A case in a switch. */ class Case extends AstNode { - /** Gets a pattern being matched by this case. */ - AstNode getAPattern(); + /** Gets the pattern being matched by this case at the specified (zero-based) `index`. */ + AstNode getPattern(int index); /** Gets the guard expression of this case, if any. */ Expr getGuard(); @@ -489,6 +489,18 @@ module Make0 Ast> { * need to be consecutive nor start from a specific index. */ default Parameter callableGetParameter(Callable c, CallableContext ctx, int index) { none() } + + /** Holds if this catch clause catches all exceptions. */ + default predicate catchAll(CatchClause catch) { none() } + + /** + * Holds if this case matches all possible values, for example, if it is a + * `default` case or a match-all pattern like `Object o` or if it is the + * final case in a switch that is known to be exhaustive. + * + * A match-all case can still ultimately fail to match if it has a guard. + */ + default predicate matchAll(Case c) { c instanceof DefaultCase } } /** @@ -612,6 +624,8 @@ module Make0 Ast> { or n instanceof Case or + n = any(Case case).getPattern(_) + or exists(n.(Parameter).getDefaultValue()) ) } @@ -772,12 +786,25 @@ module Make0 Ast> { result = DenseRank2::denseRank(c, ctx.asSome(), rnk) } + private predicate constantCondition(AstNode n, ConditionalSuccessor t) { + n.(BooleanLiteral).getValue() = t.(BooleanSuccessor).getValue() + or + exists(Case c, int i | + Input1::matchAll(c) and + c.getPattern(i) = n and + not exists(c.getPattern(i + 1)) and + t.(MatchingSuccessor).getValue() = true + ) + } + cached private newtype TNode = TBeforeNode(AstNode n) { Input1::cfgCachedStageRef() and exists(getEnclosingCallable(n)) } or TAstNode(AstNode n) { postOrInOrder(n) and exists(getEnclosingCallable(n)) } or TAfterValueNode(AstNode n, ConditionalSuccessor t) { - inConditionalContext(n, t.getKind()) and exists(getEnclosingCallable(n)) + inConditionalContext(n, t.getKind()) and + exists(getEnclosingCallable(n)) and + not constantCondition(n, t.getDual()) } or TAfterNode(AstNode n) { exists(getEnclosingCallable(n)) and @@ -1105,18 +1132,6 @@ module Make0 Ast> { } signature module InputSig2 { - /** Holds if this catch clause catches all exceptions. */ - default predicate catchAll(CatchClause catch) { none() } - - /** - * Holds if this case matches all possible values, for example, if it is a - * `default` case or a match-all pattern like `Object o` or if it is the - * final case in a switch that is known to be exhaustive. - * - * A match-all case can still ultimately fail to match if it has a guard. - */ - default predicate matchAll(Case c) { c instanceof DefaultCase } - /** * Holds if `ast` may result in an abrupt completion `c` originating at * `n`. The boolean `always` indicates whether the abrupt completion @@ -1471,12 +1486,6 @@ module Make0 Ast> { n2.isBefore(condexpr.getElse()) ) or - exists(BooleanLiteral boollit | - inConditionalContext(boollit, _) and - n1.isBefore(boollit) and - n2.isAfterValue(boollit, any(BooleanSuccessor t | t.getValue() = boollit.getValue())) - ) - or exists(PatternMatchExpr pme | n1.isBefore(pme) and n2.isBefore(pme.getExpr()) @@ -1662,7 +1671,7 @@ module Make0 Ast> { exists(MatchingSuccessor t | n1.isBefore(catchclause) and n2.isAfterValue(catchclause, t) and - if Input2::catchAll(catchclause) then t.getValue() = true else any() + if Input1::catchAll(catchclause) then t.getValue() = true else any() ) or exists(PreControlFlowNode beforeVar, PreControlFlowNode beforeCond | @@ -1720,21 +1729,22 @@ module Make0 Ast> { ) or exists(Case case | - exists(MatchingSuccessor t | - n1.isBefore(case) and - n2.isAfterValue(case, t) and - if Input2::matchAll(case) then t.getValue() = true else any() + n1.isBefore(case) and + ( + if exists(case.getPattern(_)) + then n2.isBefore(case.getPattern(0)) + else n2.isAfterValue(case, any(MatchingSuccessor t | t.getValue() = true)) ) or - exists( - PreControlFlowNode beforePattern, PreControlFlowNode beforeGuard, - PreControlFlowNode beforeBody - | - ( - beforePattern.isBefore(case.getAPattern()) - or - not exists(case.getAPattern()) and beforePattern = beforeGuard - ) and + exists(int i, MatchingSuccessor ms | n1.isAfterValue(case.getPattern(i), ms) | + ms.getValue() = false and + n2.isBefore(case.getPattern(i + 1)) + or + (ms.getValue() = true or not exists(case.getPattern(i + 1))) and + n2.isAfterValue(case, ms) + ) + or + exists(PreControlFlowNode beforeGuard, PreControlFlowNode beforeBody | ( beforeGuard.isBefore(case.getGuard()) or @@ -1748,9 +1758,6 @@ module Make0 Ast> { ) | n1.isAfterValue(case, any(MatchingSuccessor t | t.getValue() = true)) and - n2 = beforePattern - or - n1.isAfter(case.getAPattern()) and n2 = beforeGuard or n1.isAfterTrue(case.getGuard()) and @@ -2225,12 +2232,6 @@ module Make0 Ast> { t instanceof DirectSuccessor and node.isAdditional(any(ForeachStmt foreach), loopHeaderTag()) ) and - // allow for disjunctive patterns (e.g. `case "foo", "bar":`) - not ( - t instanceof DirectSuccessor and - node.isAfterValue(any(Case c | 2 <= strictcount(c.getAPattern())), - any(MatchingSuccessor m | m.getValue() = true)) - ) and // allow for functions with multiple bodies not exists(Callable c | successor.getAstNode() = getBodyEntry(c, _) and From 072166ba8880e561e4368575a18ed5bdfcb7b63d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 7 May 2026 13:46:52 +0200 Subject: [PATCH 28/43] C#/Java: Adjust Guards instantiations. --- .../ql/lib/semmle/code/csharp/controlflow/Guards.qll | 4 ++-- java/ql/lib/semmle/code/java/controlflow/Guards.qll | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll index 168ce6a1e5c..3353866e334 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll @@ -85,12 +85,12 @@ private module GuardsInput implements SharedGuards::InputSig Date: Thu, 7 May 2026 12:35:46 +0000 Subject: [PATCH 29/43] yeast: address review wording in phase docs Agent-Logs-Url: https://github.com/github/codeql/sessions/6d23db05-a6e9-4de4-8951-b465980fd0ef Co-authored-by: tausbn <1104778+tausbn@users.noreply.github.com> --- shared/yeast/doc/yeast.md | 7 ++++--- shared/yeast/src/lib.rs | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/shared/yeast/doc/yeast.md b/shared/yeast/doc/yeast.md index bc243a4b274..130d722b96e 100644 --- a/shared/yeast/doc/yeast.md +++ b/shared/yeast/doc/yeast.md @@ -321,8 +321,9 @@ capture name to a field of the same name on the output node. A YEAST desugaring pass is configured with a [`DesugaringConfig`], which carries one or more named [`Phase`]s of rules and an optional output node-types schema (in YAML format). Each phase is a complete traversal -that runs to completion before the next phase starts; rules in different -phases never compete for matches. Attach the config to a language spec +that runs to completion before the next phase starts; only the current +phase's rules are considered during that traversal. Attach the config to +a language spec to enable rewriting: ```rust @@ -349,5 +350,5 @@ is converted to JSON internally). For the dbscheme/QL code generator, set `Language::desugar` to a `DesugaringConfig` carrying the same YAML; the generator converts it to -JSON for downstream code generation. The `rules` field of the config is +JSON for downstream code generation. The `phases` field of the config is unused at code-generation time. diff --git a/shared/yeast/src/lib.rs b/shared/yeast/src/lib.rs index 8c0aa6545b5..0f0ea45a985 100644 --- a/shared/yeast/src/lib.rs +++ b/shared/yeast/src/lib.rs @@ -638,7 +638,8 @@ fn apply_rules_inner( /// 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 -/// different phases never compete because they don't see each other's input. +/// different phases never compete because each traversal only considers the +/// current phase's rules. pub struct Phase { /// Name used in error messages. pub name: String, From 6b6df374fa381b3f9afe02dc640bad57da38e237 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 7 May 2026 15:07:31 +0200 Subject: [PATCH 30/43] C#/Java: Accept test changes. --- .../controlflow/graph/BasicBlock.expected | 249 +- .../controlflow/graph/Condition.expected | 507 ++-- .../controlflow/graph/Dominance.expected | 2116 +++++++++-------- .../graph/EnclosingCallable.expected | 299 ++- .../controlflow/graph/NodeGraph.expected | 522 ++-- .../guards/BooleanGuardedExpr.expected | 1 - .../guards/GuardedControlFlowNode.expected | 1 - .../controlflow/guards/GuardedExpr.expected | 1 - .../library-tests/csharp7/IsFlow.expected | 80 +- .../csharp8/switchexprcontrolflow.expected | 167 +- .../csharp8/switchstmtctrlflow.expected | 163 +- .../ql/test/library-tests/goto/Goto1.expected | 50 +- .../library-tests/guards/guardslogic.expected | 8 +- .../library-tests/guards12/guard.expected | 80 +- .../pattern-switch/cfg/test.expected | 84 +- .../successors/TestBreak/TestSucc.expected | 16 +- .../TestLoopBranch/TestSucc.expected | 16 +- 17 files changed, 2413 insertions(+), 1947 deletions(-) diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected index 50fb2c69531..819674d2746 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected @@ -912,7 +912,7 @@ | PartialImplementationB.cs:4:12:4:18 | Entry | PartialImplementationB.cs:4:12:4:18 | Exit | 11 | | Patterns.cs:3:7:3:14 | Entry | Patterns.cs:3:7:3:14 | Exit | 11 | | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:8:13:8:23 | ... is ... | 13 | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:13:22:23 | case ...: | 4 | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:18:22:22 | "xyz" | 5 | | Patterns.cs:8:13:8:23 | After ... is ... [false] | Patterns.cs:12:18:12:31 | ... is ... | 5 | | Patterns.cs:8:13:8:23 | [MatchTrue] ... is ... | Patterns.cs:9:9:11:9 | After {...} | 18 | | Patterns.cs:12:14:18:9 | After if (...) ... | Patterns.cs:12:14:18:9 | After if (...) ... | 1 | @@ -922,19 +922,19 @@ | Patterns.cs:16:18:16:28 | After ... is ... [false] | Patterns.cs:16:18:16:28 | After ... is ... [false] | 1 | | Patterns.cs:16:18:16:28 | [MatchTrue] ... is ... | Patterns.cs:17:9:18:9 | {...} | 4 | | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:5:10:5:11 | Exit | 7 | -| Patterns.cs:22:13:22:23 | After case ...: [match] | Patterns.cs:23:17:23:22 | break; | 4 | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | case ...: | 2 | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:30:24:35 | ... > ... | 6 | -| Patterns.cs:24:13:24:36 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | After case ...: [no-match] | 1 | +| Patterns.cs:22:18:22:22 | After "xyz" [match] | Patterns.cs:23:17:23:22 | break; | 4 | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:24:18:24:23 | Int32 i2 | 4 | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:24:30:24:35 | ... > ... | 6 | +| Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | Patterns.cs:24:13:24:36 | After case ...: [no-match] | 2 | | Patterns.cs:24:30:24:35 | After ... > ... [false] | Patterns.cs:24:30:24:35 | After ... > ... [false] | 1 | | Patterns.cs:24:30:24:35 | After ... > ... [true] | Patterns.cs:26:17:26:22 | break; | 16 | -| Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:29:17:29:22 | break; | 17 | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | case ...: | 2 | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | case ...: | 1 | -| Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:32:17:32:22 | break; | 17 | -| Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | case ...: | 2 | -| Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:34:17:34:22 | break; | 4 | -| Patterns.cs:33:13:33:24 | After case ...: [no-match] | Patterns.cs:37:17:37:22 | break; | 11 | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:18:27:23 | Int32 i3 | 2 | +| Patterns.cs:27:18:27:23 | After Int32 i3 [match] | Patterns.cs:29:17:29:22 | break; | 17 | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:30:18:30:26 | String s2 | 4 | +| Patterns.cs:30:18:30:26 | After String s2 [match] | Patterns.cs:32:17:32:22 | break; | 17 | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:33:18:33:23 | Object v2 | 4 | +| Patterns.cs:33:18:33:23 | After Object v2 [match] | Patterns.cs:34:17:34:22 | break; | 4 | +| Patterns.cs:33:18:33:23 | After Object v2 [no-match] | Patterns.cs:37:17:37:22 | break; | 12 | | Patterns.cs:47:24:47:25 | Entry | Patterns.cs:48:9:48:20 | ... is ... | 5 | | Patterns.cs:48:9:48:20 | After ... is ... | Patterns.cs:47:24:47:25 | Exit | 3 | | Patterns.cs:48:9:48:20 | [MatchTrue] ... is ... | Patterns.cs:48:14:48:20 | After not ... | 5 | @@ -949,24 +949,24 @@ | Patterns.cs:53:24:53:25 | Entry | Patterns.cs:54:9:54:37 | ... is ... | 5 | | Patterns.cs:54:9:54:37 | After ... is ... | Patterns.cs:53:24:53:25 | Exit | 3 | | Patterns.cs:54:9:54:37 | [MatchTrue] ... is ... | Patterns.cs:54:14:54:37 | After not ... | 13 | -| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:28 | ... => ... | 7 | +| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:17 | not ... | 10 | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:56:26:56:27 | Exit | 4 | -| Patterns.cs:60:13:60:28 | After ... => ... [match] | Patterns.cs:60:22:60:28 | "not 1" | 6 | -| Patterns.cs:60:13:60:28 | After ... => ... [no-match] | Patterns.cs:61:18:61:24 | "other" | 5 | -| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:33 | ... => ... | 6 | +| Patterns.cs:60:13:60:17 | After not ... [match] | Patterns.cs:60:22:60:28 | "not 1" | 3 | +| Patterns.cs:60:13:60:17 | After not ... [no-match] | Patterns.cs:61:18:61:24 | "other" | 7 | +| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:17 | not ... | 9 | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:65:26:65:27 | Exit | 4 | -| Patterns.cs:69:13:69:33 | After ... => ... [match] | Patterns.cs:69:22:69:33 | "impossible" | 6 | -| Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | ... => ... | 2 | -| Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:70:18:70:27 | "possible" | 3 | -| Patterns.cs:70:13:70:27 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | 1 | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:24 | ... => ... | 7 | +| Patterns.cs:69:13:69:17 | After not ... [match] | Patterns.cs:69:22:69:33 | "impossible" | 3 | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:70:13:70:13 | 2 | 4 | +| Patterns.cs:70:13:70:13 | After 2 [match] | Patterns.cs:70:18:70:27 | "possible" | 3 | +| Patterns.cs:70:13:70:13 | After 2 [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | 2 | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:15 | > ... | 10 | | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:74:26:74:27 | Exit | 4 | -| Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:78:20:78:24 | "> 1" | 6 | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:24 | ... => ... | 2 | -| Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:79:20:79:24 | "< 0" | 6 | -| Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | ... => ... | 2 | -| Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:80:18:80:20 | "1" | 3 | -| Patterns.cs:80:13:80:20 | After ... => ... [no-match] | Patterns.cs:81:18:81:20 | "0" | 5 | +| Patterns.cs:78:13:78:15 | After > ... [match] | Patterns.cs:78:20:78:24 | "> 1" | 3 | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:79:13:79:15 | < ... | 6 | +| Patterns.cs:79:13:79:15 | After < ... [match] | Patterns.cs:79:20:79:24 | "< 0" | 3 | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:80:13:80:13 | 1 | 4 | +| Patterns.cs:80:13:80:13 | After 1 [match] | Patterns.cs:80:18:80:20 | "1" | 3 | +| Patterns.cs:80:13:80:13 | After 1 [no-match] | Patterns.cs:81:18:81:20 | "0" | 7 | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:39:85:53 | ... is ... | 6 | | Patterns.cs:85:39:85:53 | After ... is ... [false] | Patterns.cs:85:67:85:69 | "2" | 2 | | Patterns.cs:85:39:85:53 | [MatchTrue] ... is ... | Patterns.cs:85:57:85:63 | "not 2" | 11 | @@ -995,129 +995,130 @@ | Qualifiers.cs:10:10:10:10 | Entry | Qualifiers.cs:10:10:10:10 | Exit | 149 | | Switch.cs:3:7:3:12 | Entry | Switch.cs:3:7:3:12 | Exit | 11 | | Switch.cs:5:10:5:11 | Entry | Switch.cs:5:10:5:11 | Exit | 9 | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:13:14:21 | case ...: | 6 | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:18:14:20 | "a" | 7 | | Switch.cs:10:10:10:11 | Exceptional Exit | Switch.cs:10:10:10:11 | Exceptional Exit | 1 | | Switch.cs:10:10:10:11 | Exit | Switch.cs:10:10:10:11 | Exit | 1 | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:10:10:10:11 | Normal Exit | 1 | -| Switch.cs:14:13:14:21 | After case ...: [match] | Switch.cs:15:17:15:23 | return ...; | 4 | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:16:13:16:19 | case ...: | 2 | -| Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:17:17:17:38 | throw ...; | 7 | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:18:13:18:22 | case ...: | 2 | -| Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:19:17:19:29 | goto default; | 4 | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:20:13:20:23 | case ...: | 2 | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:21:21:21:29 | ... == ... | 7 | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:13:24:56 | case ...: | 2 | +| Switch.cs:14:18:14:20 | After "a" [match] | Switch.cs:15:17:15:23 | return ...; | 4 | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:16:18:16:18 | 0 | 4 | +| Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:17:17:17:38 | throw ...; | 6 | +| Switch.cs:16:18:16:18 | After 0 [match] | Switch.cs:16:18:16:18 | After 0 [match] | 1 | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:18:18:18:21 | null | 4 | +| Switch.cs:18:18:18:21 | After null [match] | Switch.cs:19:17:19:29 | goto default; | 4 | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:20:18:20:22 | Int32 i | 4 | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:21:21:21:29 | ... == ... | 7 | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:18:24:25 | String s | 4 | | Switch.cs:21:21:21:29 | After ... == ... [false] | Switch.cs:23:17:23:28 | goto case ...; | 5 | | Switch.cs:21:21:21:29 | After ... == ... [true] | Switch.cs:22:21:22:27 | return ...; | 3 | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:32:24:43 | ... > ... | 10 | -| Switch.cs:24:13:24:56 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | 1 | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:32:24:43 | ... > ... | 10 | +| Switch.cs:24:18:24:25 | After String s [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | 2 | | Switch.cs:24:32:24:43 | After ... > ... [false] | Switch.cs:24:32:24:43 | After ... > ... [false] | 1 | | Switch.cs:24:32:24:43 | After ... > ... [true] | Switch.cs:24:48:24:55 | ... != ... | 5 | | Switch.cs:24:32:24:55 | After ... && ... [false] | Switch.cs:24:32:24:55 | After ... && ... [false] | 1 | | Switch.cs:24:48:24:55 | After ... != ... [false] | Switch.cs:24:48:24:55 | After ... != ... [false] | 1 | | Switch.cs:24:48:24:55 | After ... != ... [true] | Switch.cs:26:17:26:23 | return ...; | 10 | -| Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:27:32:27:38 | call to method Throw | 4 | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:30:13:30:20 | default: | 2 | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | case ...: | 1 | +| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:18:27:25 | Double d | 2 | +| Switch.cs:27:18:27:25 | After Double d [match] | Switch.cs:27:32:27:38 | call to method Throw | 4 | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:30:13:30:20 | default: | 3 | | Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:29:17:29:23 | return ...; | 6 | | Switch.cs:35:10:35:11 | Entry | Switch.cs:35:10:35:11 | Exit | 7 | -| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:13:48:23 | case ...: | 6 | +| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:18:48:20 | access to type Int32 | 7 | | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:44:10:44:11 | Exit | 4 | -| Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:49:17:49:22 | break; | 4 | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:13:50:39 | case ...: | 2 | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:30:50:38 | ... != ... | 6 | -| Switch.cs:50:13:50:39 | After case ...: [no-match] | Switch.cs:50:13:50:39 | After case ...: [no-match] | 1 | +| Switch.cs:48:18:48:20 | After access to type Int32 [match] | Switch.cs:49:17:49:22 | break; | 4 | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:50:18:50:21 | access to type Boolean | 4 | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:50:30:50:38 | ... != ... | 6 | +| Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | Switch.cs:50:13:50:39 | After case ...: [no-match] | 2 | | Switch.cs:50:30:50:38 | After ... != ... [false] | Switch.cs:50:30:50:38 | After ... != ... [false] | 1 | | Switch.cs:50:30:50:38 | After ... != ... [true] | Switch.cs:51:17:51:22 | break; | 3 | -| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:13:59:19 | case ...: | 9 | +| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:18:59:18 | 2 | 10 | | Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:55:10:55:11 | Exit | 4 | -| Switch.cs:59:13:59:19 | After case ...: [match] | Switch.cs:60:17:60:22 | break; | 4 | -| Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | case ...: | 2 | -| Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:62:17:62:22 | break; | 4 | -| Switch.cs:61:13:61:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | After case ...: [no-match] | 1 | -| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:13:70:23 | case ...: | 9 | +| Switch.cs:59:18:59:18 | After 2 [match] | Switch.cs:60:17:60:22 | break; | 4 | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:61:18:61:18 | 3 | 4 | +| Switch.cs:61:18:61:18 | After 3 [match] | Switch.cs:62:17:62:22 | break; | 4 | +| Switch.cs:61:18:61:18 | After 3 [no-match] | Switch.cs:61:13:61:19 | After case ...: [no-match] | 2 | +| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:18:70:20 | access to type Int32 | 10 | | Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:66:10:66:11 | Exit | 4 | -| Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:71:17:71:22 | break; | 4 | -| Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:72:13:72:20 | case ...: | 2 | -| Switch.cs:72:13:72:20 | After case ...: [match] | Switch.cs:73:17:73:22 | break; | 4 | -| Switch.cs:72:13:72:20 | After case ...: [no-match] | Switch.cs:72:13:72:20 | After case ...: [no-match] | 1 | -| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:13:81:19 | case ...: | 7 | +| Switch.cs:70:18:70:20 | After access to type Int32 [match] | Switch.cs:71:17:71:22 | break; | 4 | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:72:18:72:19 | "" | 4 | +| Switch.cs:72:18:72:19 | After "" [match] | Switch.cs:73:17:73:22 | break; | 4 | +| Switch.cs:72:18:72:19 | After "" [no-match] | Switch.cs:72:13:72:20 | After case ...: [no-match] | 2 | +| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:18:81:18 | 1 | 8 | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:77:10:77:11 | Exit | 2 | | Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:88:9:88:21 | return ...; | 4 | -| Switch.cs:81:13:81:19 | After case ...: [match] | Switch.cs:82:17:82:28 | return ...; | 5 | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | case ...: | 2 | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:84:21:84:25 | ... > ... | 7 | -| Switch.cs:83:13:83:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | After case ...: [no-match] | 1 | +| Switch.cs:81:18:81:18 | After 1 [match] | Switch.cs:82:17:82:28 | return ...; | 5 | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:83:18:83:18 | 2 | 4 | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:84:21:84:25 | ... > ... | 7 | +| Switch.cs:83:18:83:18 | After 2 [no-match] | Switch.cs:83:13:83:19 | After case ...: [no-match] | 2 | | Switch.cs:84:21:84:25 | After ... > ... [false] | Switch.cs:86:17:86:28 | return ...; | 5 | | Switch.cs:84:21:84:25 | After ... > ... [true] | Switch.cs:85:21:85:26 | break; | 3 | -| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:13:95:23 | case ...: | 6 | +| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:18:95:20 | access to type Int32 | 7 | | Switch.cs:91:10:91:11 | Normal Exit | Switch.cs:91:10:91:11 | Exit | 2 | -| Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:96:17:96:28 | return ...; | 5 | -| Switch.cs:95:13:95:23 | After case ...: [no-match] | Switch.cs:98:9:98:21 | return ...; | 5 | +| Switch.cs:95:18:95:20 | After access to type Int32 [match] | Switch.cs:96:17:96:28 | return ...; | 5 | +| Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | Switch.cs:98:9:98:21 | return ...; | 6 | | Switch.cs:101:9:101:10 | Entry | Switch.cs:103:17:103:17 | access to parameter s | 6 | | Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:101:9:101:10 | Exit | 2 | | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | Switch.cs:103:17:103:25 | access to property Length | 2 | | Switch.cs:103:17:103:17 | After access to parameter s [null] | Switch.cs:103:17:103:17 | After access to parameter s [null] | 1 | -| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:13:105:19 | case ...: | 2 | -| Switch.cs:105:13:105:19 | After case ...: [match] | Switch.cs:105:21:105:29 | return ...; | 5 | -| Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:106:13:106:19 | case ...: | 2 | -| Switch.cs:106:13:106:19 | After case ...: [match] | Switch.cs:106:21:106:29 | return ...; | 5 | -| Switch.cs:106:13:106:19 | After case ...: [no-match] | Switch.cs:108:9:108:18 | return ...; | 8 | +| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:18:105:18 | 0 | 3 | +| Switch.cs:105:18:105:18 | After 0 [match] | Switch.cs:105:21:105:29 | return ...; | 5 | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:106:18:106:18 | 1 | 4 | +| Switch.cs:106:18:106:18 | After 1 [match] | Switch.cs:106:21:106:29 | return ...; | 5 | +| Switch.cs:106:18:106:18 | After 1 [no-match] | Switch.cs:108:9:108:18 | return ...; | 9 | | Switch.cs:111:17:111:21 | Entry | Switch.cs:111:17:111:21 | Exit | 8 | -| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:13:117:35 | case ...: | 9 | +| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:18:117:18 | 3 | 10 | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:113:9:113:11 | Exit | 2 | | Switch.cs:115:9:119:9 | After switch (...) {...} | Switch.cs:120:9:120:18 | return ...; | 7 | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:25:117:34 | ... == ... | 6 | -| Switch.cs:117:13:117:35 | After case ...: [no-match] | Switch.cs:117:13:117:35 | After case ...: [no-match] | 1 | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:117:25:117:34 | ... == ... | 6 | +| Switch.cs:117:18:117:18 | After 3 [no-match] | Switch.cs:117:13:117:35 | After case ...: [no-match] | 2 | | Switch.cs:117:25:117:34 | After ... == ... [false] | Switch.cs:117:25:117:34 | After ... == ... [false] | 1 | | Switch.cs:117:25:117:34 | After ... == ... [true] | Switch.cs:117:37:117:45 | return ...; | 4 | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:25:118:33 | ... == ... | 6 | -| Switch.cs:118:13:118:34 | After case ...: [no-match] | Switch.cs:118:13:118:34 | After case ...: [no-match] | 1 | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | case ...: | 1 | +| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:18:118:18 | 2 | 2 | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:118:25:118:33 | ... == ... | 6 | +| Switch.cs:118:18:118:18 | After 2 [no-match] | Switch.cs:118:13:118:34 | After case ...: [no-match] | 2 | | Switch.cs:118:25:118:33 | After ... == ... [false] | Switch.cs:118:25:118:33 | After ... == ... [false] | 1 | | Switch.cs:118:25:118:33 | After ... == ... [true] | Switch.cs:118:36:118:44 | return ...; | 4 | -| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:34 | ... => ... | 7 | +| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:29 | Boolean b | 8 | | Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:123:10:123:12 | Exit | 2 | | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | Switch.cs:124:5:127:5 | After {...} | 3 | | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | Switch.cs:126:13:126:19 | return ...; | 3 | -| Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:125:34:125:34 | access to local variable b | 3 | -| Switch.cs:125:24:125:34 | After ... => ... [no-match] | Switch.cs:125:42:125:46 | false | 5 | -| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:40 | ... => ... | 8 | +| Switch.cs:125:24:125:29 | After Boolean b [match] | Switch.cs:125:34:125:34 | access to local variable b | 3 | +| Switch.cs:125:24:125:29 | After Boolean b [no-match] | Switch.cs:125:42:125:46 | false | 7 | +| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:35 | String s | 9 | | Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:129:12:129:14 | Exit | 4 | | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | Switch.cs:131:16:131:66 | call to method ToString | 2 | | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | 1 | -| Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:131:40:131:40 | access to local variable s | 3 | -| Switch.cs:131:28:131:40 | After ... => ... [no-match] | Switch.cs:131:48:131:51 | null | 5 | -| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:13:139:19 | case ...: | 6 | +| Switch.cs:131:28:131:35 | After String s [match] | Switch.cs:131:40:131:40 | access to local variable s | 3 | +| Switch.cs:131:28:131:35 | After String s [no-match] | Switch.cs:131:48:131:51 | null | 7 | +| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:18:139:18 | 1 | 7 | | Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:134:9:134:11 | Exit | 2 | -| Switch.cs:139:13:139:19 | After case ...: [match] | Switch.cs:139:21:139:29 | return ...; | 5 | -| Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:140:13:140:19 | case ...: | 2 | -| Switch.cs:140:13:140:19 | After case ...: [match] | Switch.cs:140:21:140:29 | return ...; | 5 | -| Switch.cs:140:13:140:19 | After case ...: [no-match] | Switch.cs:138:22:138:31 | return ...; | 9 | -| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:13:148:19 | case ...: | 6 | +| Switch.cs:139:18:139:18 | After 1 [match] | Switch.cs:139:21:139:29 | return ...; | 5 | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:140:18:140:18 | 2 | 4 | +| Switch.cs:140:18:140:18 | After 2 [match] | Switch.cs:140:21:140:29 | return ...; | 5 | +| Switch.cs:140:18:140:18 | After 2 [no-match] | Switch.cs:138:22:138:31 | return ...; | 10 | +| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:18:148:18 | 1 | 7 | | Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:144:9:144:11 | Exit | 2 | -| Switch.cs:148:13:148:19 | After case ...: [match] | Switch.cs:148:21:148:29 | return ...; | 5 | -| Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:150:13:150:19 | case ...: | 2 | -| Switch.cs:150:13:150:19 | After case ...: [match] | Switch.cs:150:21:150:29 | return ...; | 5 | -| Switch.cs:150:13:150:19 | After case ...: [no-match] | Switch.cs:149:22:149:31 | return ...; | 9 | -| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:38 | ... => ... | 9 | +| Switch.cs:148:18:148:18 | After 1 [match] | Switch.cs:148:21:148:29 | return ...; | 5 | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:150:18:150:18 | 2 | 4 | +| Switch.cs:150:18:150:18 | After 2 [match] | Switch.cs:150:21:150:29 | return ...; | 5 | +| Switch.cs:150:18:150:18 | After 2 [no-match] | Switch.cs:149:22:149:31 | return ...; | 10 | +| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:31 | true | 10 | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:157:13:157:13 | access to parameter b | 6 | -| Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:156:36:156:38 | "a" | 3 | -| Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | ... => ... | 2 | -| Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:156:50:156:52 | "b" | 3 | -| Switch.cs:156:41:156:52 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | After ... => ... [no-match] | 1 | +| Switch.cs:156:28:156:31 | After true [match] | Switch.cs:156:36:156:38 | "a" | 3 | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:156:41:156:45 | false | 4 | +| Switch.cs:156:41:156:45 | After false [match] | Switch.cs:156:50:156:52 | "b" | 3 | +| Switch.cs:156:41:156:45 | After false [no-match] | Switch.cs:156:41:156:52 | After ... => ... [no-match] | 2 | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:154:10:154:12 | Exit | 4 | | Switch.cs:157:13:157:13 | After access to parameter b [false] | Switch.cs:160:13:160:49 | After ...; | 14 | | Switch.cs:157:13:157:13 | After access to parameter b [true] | Switch.cs:158:13:158:49 | After ...; | 14 | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:13:167:19 | case ...: | 6 | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:18:167:18 | 1 | 7 | | Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:163:10:163:12 | Exit | 4 | -| Switch.cs:167:13:167:19 | After case ...: [match] | Switch.cs:167:18:167:18 | 1 | 2 | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:168:13:168:19 | case ...: | 2 | -| Switch.cs:168:13:168:19 | After case ...: [match] | Switch.cs:168:18:168:18 | 2 | 2 | -| Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | case ...: | 2 | +| Switch.cs:167:18:167:18 | After 1 [match] | Switch.cs:167:13:167:19 | After case ...: [match] | 2 | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:168:18:168:18 | 2 | 4 | +| Switch.cs:168:18:168:18 | After 2 [match] | Switch.cs:168:13:168:19 | After case ...: [match] | 2 | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:171:18:171:18 | 3 | 4 | | Switch.cs:169:17:169:51 | ...; | Switch.cs:170:17:170:22 | break; | 8 | -| Switch.cs:171:13:171:19 | After case ...: [match] | Switch.cs:173:17:173:22 | break; | 10 | -| Switch.cs:171:13:171:19 | After case ...: [no-match] | Switch.cs:176:17:176:22 | break; | 11 | +| Switch.cs:171:18:171:18 | After 3 [match] | Switch.cs:173:17:173:22 | break; | 10 | +| Switch.cs:171:18:171:18 | After 3 [no-match] | Switch.cs:176:17:176:22 | break; | 12 | | TypeAccesses.cs:1:7:1:18 | Entry | TypeAccesses.cs:1:7:1:18 | Exit | 11 | | TypeAccesses.cs:3:10:3:10 | Entry | TypeAccesses.cs:7:13:7:22 | ... is ... | 27 | | TypeAccesses.cs:7:9:7:25 | After if (...) ... | TypeAccesses.cs:3:10:3:10 | Exit | 11 | @@ -1157,21 +1158,23 @@ | cflow.cs:30:18:33:37 | After if (...) ... | cflow.cs:30:18:33:37 | After if (...) ... | 1 | | cflow.cs:30:22:30:31 | After ... == ... [false] | cflow.cs:33:17:33:37 | After ...; | 7 | | cflow.cs:30:22:30:31 | After ... == ... [true] | cflow.cs:31:17:31:42 | After ...; | 7 | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:41:13:41:19 | case ...: | 6 | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:41:18:41:18 | 1 | 7 | | cflow.cs:37:17:37:22 | Exit | cflow.cs:37:17:37:22 | Exit | 1 | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:13:53:20 | case ...: | 4 | -| cflow.cs:41:13:41:19 | After case ...: [match] | cflow.cs:43:17:43:28 | goto case ...; | 11 | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:44:13:44:19 | case ...: | 2 | -| cflow.cs:44:13:44:19 | After case ...: [match] | cflow.cs:46:17:46:28 | goto case ...; | 11 | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | case ...: | 2 | -| cflow.cs:47:13:47:19 | After case ...: [match] | cflow.cs:49:17:49:22 | break; | 10 | -| cflow.cs:47:13:47:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | 1 | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:13:62:19 | case ...: | 10 | -| cflow.cs:53:13:53:20 | After case ...: [match] | cflow.cs:55:17:55:22 | break; | 10 | -| cflow.cs:53:13:53:20 | After case ...: [no-match] | cflow.cs:58:17:58:22 | break; | 11 | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:18:53:19 | 42 | 5 | +| cflow.cs:41:13:41:19 | After case ...: [match] | cflow.cs:43:17:43:28 | goto case ...; | 10 | +| cflow.cs:41:18:41:18 | After 1 [match] | cflow.cs:41:18:41:18 | After 1 [match] | 1 | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:44:18:44:18 | 2 | 4 | +| cflow.cs:44:13:44:19 | After case ...: [match] | cflow.cs:46:17:46:28 | goto case ...; | 10 | +| cflow.cs:44:18:44:18 | After 2 [match] | cflow.cs:44:18:44:18 | After 2 [match] | 1 | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:47:18:47:18 | 3 | 4 | +| cflow.cs:47:18:47:18 | After 3 [match] | cflow.cs:49:17:49:22 | break; | 10 | +| cflow.cs:47:18:47:18 | After 3 [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | 2 | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:18:62:18 | 0 | 11 | +| cflow.cs:53:18:53:19 | After 42 [match] | cflow.cs:55:17:55:22 | break; | 10 | +| cflow.cs:53:18:53:19 | After 42 [no-match] | cflow.cs:58:17:58:22 | break; | 12 | | cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:37:17:37:22 | Normal Exit | 5 | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:63:23:63:33 | ... == ... | 11 | -| cflow.cs:62:13:62:19 | After case ...: [no-match] | cflow.cs:62:13:62:19 | After case ...: [no-match] | 1 | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:63:23:63:33 | ... == ... | 11 | +| cflow.cs:62:18:62:18 | After 0 [no-match] | cflow.cs:62:13:62:19 | After case ...: [no-match] | 2 | | cflow.cs:63:23:63:33 | After ... == ... [false] | cflow.cs:37:17:37:22 | Exceptional Exit | 8 | | cflow.cs:63:23:63:33 | After ... == ... [true] | cflow.cs:65:17:65:22 | break; | 5 | | cflow.cs:70:18:70:18 | Entry | cflow.cs:72:13:72:21 | ... == ... | 8 | @@ -1293,15 +1296,15 @@ | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:244:13:244:28 | ... > ... | 12 | | cflow.cs:242:19:242:35 | After ... == ... [false] | cflow.cs:242:16:242:36 | After !... [false] | 3 | | cflow.cs:242:19:242:35 | After ... == ... [true] | cflow.cs:242:39:242:41 | {...} | 4 | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:13:248:19 | case ...: | 15 | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:18:248:18 | 0 | 16 | | cflow.cs:244:13:244:28 | After ... > ... [true] | cflow.cs:244:31:244:41 | goto ...; | 3 | | cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:240:10:240:13 | Exit | 4 | -| cflow.cs:248:13:248:19 | After case ...: [match] | cflow.cs:249:17:249:29 | goto default; | 4 | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:250:13:250:19 | case ...: | 2 | -| cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:252:17:252:22 | break; | 10 | -| cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | case ...: | 2 | -| cflow.cs:253:13:253:19 | After case ...: [match] | cflow.cs:254:17:254:27 | goto ...; | 4 | -| cflow.cs:253:13:253:19 | After case ...: [no-match] | cflow.cs:255:13:255:20 | default: | 2 | +| cflow.cs:248:18:248:18 | After 0 [match] | cflow.cs:249:17:249:29 | goto default; | 4 | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:250:18:250:18 | 1 | 4 | +| cflow.cs:250:18:250:18 | After 1 [match] | cflow.cs:252:17:252:22 | break; | 10 | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:253:18:253:18 | 2 | 4 | +| cflow.cs:253:18:253:18 | After 2 [match] | cflow.cs:254:17:254:27 | goto ...; | 4 | +| cflow.cs:253:18:253:18 | After 2 [no-match] | cflow.cs:255:13:255:20 | default: | 3 | | cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:257:17:257:22 | break; | 9 | | cflow.cs:261:49:261:53 | Entry | cflow.cs:264:18:264:22 | After Int32 i = ... | 12 | | cflow.cs:261:49:261:53 | Exceptional Exit | cflow.cs:261:49:261:53 | Exceptional Exit | 1 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Condition.expected b/csharp/ql/test/library-tests/controlflow/graph/Condition.expected index 94ae5455517..4ed3508dd69 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Condition.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Condition.expected @@ -541,19 +541,19 @@ conditionBlock | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:16:14:18:9 | After if (...) ... | false | | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:16:18:16:28 | After ... is ... [false] | false | | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:16:18:16:28 | [MatchTrue] ... is ... | false | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:13:22:23 | After case ...: [match] | true | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:13:22:23 | After case ...: [no-match] | false | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:13:24:36 | After case ...: [match] | false | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:13:24:36 | After case ...: [no-match] | false | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:18:22:22 | After "xyz" [match] | true | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:18:22:22 | After "xyz" [no-match] | false | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | false | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | false | | Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:30:24:35 | After ... > ... [false] | false | | Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:30:24:35 | After ... > ... [true] | false | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:13:27:24 | After case ...: [match] | false | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:13:27:24 | After case ...: [no-match] | false | | Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:13:27:24 | case ...: | false | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:30:13:30:27 | After case ...: [match] | false | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:30:13:30:27 | After case ...: [no-match] | false | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:33:13:33:24 | After case ...: [match] | false | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:33:13:33:24 | After case ...: [no-match] | false | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | false | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | false | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:30:18:30:26 | After String s2 [match] | false | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:30:18:30:26 | After String s2 [no-match] | false | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:33:18:33:23 | After Object v2 [match] | false | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | false | | Patterns.cs:8:13:8:23 | After ... is ... [false] | Patterns.cs:12:18:12:31 | After ... is ... [false] | false | | Patterns.cs:8:13:8:23 | After ... is ... [false] | Patterns.cs:12:18:12:31 | [MatchTrue] ... is ... | true | | Patterns.cs:8:13:8:23 | After ... is ... [false] | Patterns.cs:16:14:18:9 | After if (...) ... | false | @@ -561,24 +561,24 @@ conditionBlock | Patterns.cs:8:13:8:23 | After ... is ... [false] | Patterns.cs:16:18:16:28 | [MatchTrue] ... is ... | false | | Patterns.cs:12:18:12:31 | After ... is ... [false] | Patterns.cs:16:18:16:28 | After ... is ... [false] | false | | Patterns.cs:12:18:12:31 | After ... is ... [false] | Patterns.cs:16:18:16:28 | [MatchTrue] ... is ... | true | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | After case ...: [match] | true | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | After case ...: [no-match] | false | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:30:24:35 | After ... > ... [false] | true | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:30:24:35 | After ... > ... [true] | true | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:30:24:35 | After ... > ... [false] | false | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:30:24:35 | After ... > ... [true] | true | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | After case ...: [match] | true | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | After case ...: [no-match] | false | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [match] | false | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [no-match] | false | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | After case ...: [match] | true | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | After case ...: [no-match] | false | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:30:13:30:27 | After case ...: [match] | false | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:30:13:30:27 | After case ...: [no-match] | false | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:33:13:33:24 | After case ...: [match] | false | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:33:13:33:24 | After case ...: [no-match] | false | -| Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [match] | true | -| Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [no-match] | false | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | true | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | false | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:24:30:24:35 | After ... > ... [false] | true | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:24:30:24:35 | After ... > ... [true] | true | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:24:30:24:35 | After ... > ... [false] | false | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:24:30:24:35 | After ... > ... [true] | true | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | true | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | false | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:30:18:30:26 | After String s2 [match] | false | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:30:18:30:26 | After String s2 [no-match] | false | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:33:18:33:23 | After Object v2 [match] | false | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | false | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:30:18:30:26 | After String s2 [match] | true | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:30:18:30:26 | After String s2 [no-match] | false | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [match] | false | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | false | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [match] | true | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | false | | Patterns.cs:47:24:47:25 | Entry | Patterns.cs:48:9:48:20 | [MatchTrue] ... is ... | true | | Patterns.cs:50:24:50:25 | Entry | Patterns.cs:51:9:51:21 | After ... is ... [false] | false | | Patterns.cs:50:24:50:25 | Entry | Patterns.cs:51:9:51:21 | [MatchTrue] ... is ... | true | @@ -589,26 +589,26 @@ conditionBlock | Patterns.cs:51:9:51:21 | After ... is ... [false] | Patterns.cs:51:34:51:39 | [MatchTrue] ... is ... | true | | Patterns.cs:51:9:51:21 | [MatchTrue] ... is ... | Patterns.cs:51:25:51:30 | [MatchTrue] ... is ... | true | | Patterns.cs:53:24:53:25 | Entry | Patterns.cs:54:9:54:37 | [MatchTrue] ... is ... | true | -| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:28 | After ... => ... [match] | true | -| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | false | -| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:33 | After ... => ... [match] | true | -| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | false | -| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:70:13:70:27 | After ... => ... [match] | false | -| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | false | -| Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [match] | true | -| Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | false | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:24 | After ... => ... [match] | true | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | false | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:79:13:79:24 | After ... => ... [match] | false | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | false | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:80:13:80:20 | After ... => ... [match] | false | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | false | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:24 | After ... => ... [match] | true | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | false | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [match] | false | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | false | -| Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [match] | true | -| Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | false | +| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:17 | After not ... [match] | true | +| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:17 | After not ... [no-match] | false | +| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:17 | After not ... [match] | true | +| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:17 | After not ... [no-match] | false | +| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:70:13:70:13 | After 2 [match] | false | +| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:70:13:70:13 | After 2 [no-match] | false | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:70:13:70:13 | After 2 [match] | true | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:70:13:70:13 | After 2 [no-match] | false | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:15 | After > ... [match] | true | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:15 | After > ... [no-match] | false | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:79:13:79:15 | After < ... [match] | false | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:79:13:79:15 | After < ... [no-match] | false | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:80:13:80:13 | After 1 [match] | false | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:80:13:80:13 | After 1 [no-match] | false | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:79:13:79:15 | After < ... [match] | true | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:79:13:79:15 | After < ... [no-match] | false | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:80:13:80:13 | After 1 [match] | false | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:80:13:80:13 | After 1 [no-match] | false | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:80:13:80:13 | After 1 [match] | true | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:80:13:80:13 | After 1 [no-match] | false | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:39:85:53 | After ... is ... [false] | false | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:39:85:53 | [MatchTrue] ... is ... | true | | Patterns.cs:87:26:87:27 | Entry | Patterns.cs:87:39:87:54 | After ... is ... [false] | false | @@ -620,187 +620,189 @@ conditionBlock | PostDominance.cs:17:10:17:11 | Entry | PostDominance.cs:19:13:19:21 | After ... is ... [false] | false | | PostDominance.cs:17:10:17:11 | Entry | PostDominance.cs:19:13:19:21 | [MatchTrue] ... is ... | true | | Switch.cs:10:10:10:11 | Entry | Switch.cs:10:10:10:11 | Exceptional Exit | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:13:14:21 | After case ...: [match] | true | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:13:14:21 | After case ...: [no-match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:18:14:20 | After "a" [match] | true | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:18:14:20 | After "a" [no-match] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:16:13:16:19 | After case ...: [match] | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:16:13:16:19 | After case ...: [no-match] | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:18:13:18:22 | After case ...: [match] | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:18:13:18:22 | After case ...: [no-match] | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:20:13:20:23 | After case ...: [match] | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:20:13:20:23 | After case ...: [no-match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:16:18:16:18 | After 0 [match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:16:18:16:18 | After 0 [no-match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:18:18:18:21 | After null [match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:18:18:18:21 | After null [no-match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:20:18:20:22 | After Int32 i [match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:20:18:20:22 | After Int32 i [no-match] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:21:21:21:29 | After ... == ... [false] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:21:21:21:29 | After ... == ... [true] | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:24:13:24:56 | After case ...: [match] | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:24:13:24:56 | After case ...: [no-match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:24:18:24:25 | After String s [match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:24:18:24:25 | After String s [no-match] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:32:24:43 | After ... > ... [false] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:32:24:43 | After ... > ... [true] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:32:24:55 | After ... && ... [false] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:48:24:55 | After ... != ... [false] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:48:24:55 | After ... != ... [true] | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:27:13:27:39 | After case ...: [match] | false | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:27:13:27:39 | After case ...: [no-match] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:27:13:27:39 | case ...: | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:27:18:27:25 | After Double d [match] | false | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:27:18:27:25 | After Double d [no-match] | false | | Switch.cs:10:10:10:11 | Entry | Switch.cs:30:13:30:20 | After default: [match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:16:13:16:19 | After case ...: [no-match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [no-match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | false | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:30:13:30:20 | After default: [match] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [match] | true | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [no-match] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [match] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [match] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [match] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | false | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [match] | true | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | true | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | true | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [match] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [match] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | false | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | false | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:21:21:21:29 | After ... == ... [false] | false | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:21:21:21:29 | After ... == ... [true] | true | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [match] | true | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | false | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | true | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | true | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | true | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | true | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | true | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:32:24:43 | After ... > ... [false] | false | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:32:24:43 | After ... > ... [true] | true | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:48:24:55 | After ... != ... [false] | true | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:48:24:55 | After ... != ... [true] | true | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:16:18:16:18 | After 0 [match] | true | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:16:18:16:18 | After 0 [no-match] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:18:18:18:21 | After null [match] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:18:18:18:21 | After null [no-match] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:20:18:20:22 | After Int32 i [match] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:20:18:20:22 | After Int32 i [no-match] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:18:24:25 | After String s [match] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:27:13:27:39 | case ...: | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:27:18:27:25 | After Double d [match] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | false | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:30:13:30:20 | After default: [match] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:18:18:18:21 | After null [match] | true | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:18:18:18:21 | After null [no-match] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:20:18:20:22 | After Int32 i [match] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:20:18:20:22 | After Int32 i [no-match] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:18:24:25 | After String s [match] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:27:13:27:39 | case ...: | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:27:18:27:25 | After Double d [match] | false | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:20:18:20:22 | After Int32 i [match] | true | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:20:18:20:22 | After Int32 i [no-match] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | true | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | true | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:18:24:25 | After String s [match] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:27:13:27:39 | case ...: | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:27:18:27:25 | After Double d [match] | false | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | false | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:21:21:21:29 | After ... == ... [false] | false | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:21:21:21:29 | After ... == ... [true] | true | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:18:24:25 | After String s [match] | true | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | false | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | true | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | true | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | true | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | true | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | true | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:32:24:43 | After ... > ... [false] | false | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:32:24:43 | After ... > ... [true] | true | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:48:24:55 | After ... != ... [false] | true | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:48:24:55 | After ... != ... [true] | true | | Switch.cs:24:32:24:43 | After ... > ... [true] | Switch.cs:24:48:24:55 | After ... != ... [false] | false | | Switch.cs:24:32:24:43 | After ... > ... [true] | Switch.cs:24:48:24:55 | After ... != ... [true] | true | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | After case ...: [match] | true | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | After case ...: [no-match] | false | -| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:13:48:23 | After case ...: [match] | true | -| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:13:48:23 | After case ...: [no-match] | false | -| Switch.cs:44:10:44:11 | Entry | Switch.cs:50:13:50:39 | After case ...: [match] | false | -| Switch.cs:44:10:44:11 | Entry | Switch.cs:50:13:50:39 | After case ...: [no-match] | false | +| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:18:27:25 | After Double d [match] | true | +| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:18:27:25 | After Double d [no-match] | false | +| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:18:48:20 | After access to type Int32 [match] | true | +| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | false | +| Switch.cs:44:10:44:11 | Entry | Switch.cs:50:18:50:21 | After access to type Boolean [match] | false | +| Switch.cs:44:10:44:11 | Entry | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | false | | Switch.cs:44:10:44:11 | Entry | Switch.cs:50:30:50:38 | After ... != ... [false] | false | | Switch.cs:44:10:44:11 | Entry | Switch.cs:50:30:50:38 | After ... != ... [true] | false | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:13:50:39 | After case ...: [match] | true | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:13:50:39 | After case ...: [no-match] | false | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:30:50:38 | After ... != ... [false] | true | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:30:50:38 | After ... != ... [true] | true | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:30:50:38 | After ... != ... [false] | false | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:30:50:38 | After ... != ... [true] | true | -| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:13:59:19 | After case ...: [match] | true | -| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:13:59:19 | After case ...: [no-match] | false | -| Switch.cs:55:10:55:11 | Entry | Switch.cs:61:13:61:19 | After case ...: [match] | false | -| Switch.cs:55:10:55:11 | Entry | Switch.cs:61:13:61:19 | After case ...: [no-match] | false | -| Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | After case ...: [match] | true | -| Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | After case ...: [no-match] | false | -| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:13:70:23 | After case ...: [match] | true | -| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:13:70:23 | After case ...: [no-match] | false | -| Switch.cs:66:10:66:11 | Entry | Switch.cs:72:13:72:20 | After case ...: [match] | false | -| Switch.cs:66:10:66:11 | Entry | Switch.cs:72:13:72:20 | After case ...: [no-match] | false | -| Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:72:13:72:20 | After case ...: [match] | true | -| Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:72:13:72:20 | After case ...: [no-match] | false | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:50:18:50:21 | After access to type Boolean [match] | true | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | false | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:50:30:50:38 | After ... != ... [false] | true | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:50:30:50:38 | After ... != ... [true] | true | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:50:30:50:38 | After ... != ... [false] | false | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:50:30:50:38 | After ... != ... [true] | true | +| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:18:59:18 | After 2 [match] | true | +| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:18:59:18 | After 2 [no-match] | false | +| Switch.cs:55:10:55:11 | Entry | Switch.cs:61:18:61:18 | After 3 [match] | false | +| Switch.cs:55:10:55:11 | Entry | Switch.cs:61:18:61:18 | After 3 [no-match] | false | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:61:18:61:18 | After 3 [match] | true | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:61:18:61:18 | After 3 [no-match] | false | +| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:18:70:20 | After access to type Int32 [match] | true | +| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | false | +| Switch.cs:66:10:66:11 | Entry | Switch.cs:72:18:72:19 | After "" [match] | false | +| Switch.cs:66:10:66:11 | Entry | Switch.cs:72:18:72:19 | After "" [no-match] | false | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:72:18:72:19 | After "" [match] | true | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:72:18:72:19 | After "" [no-match] | false | | Switch.cs:77:10:77:11 | Entry | Switch.cs:79:9:87:9 | After switch (...) {...} | false | -| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:13:81:19 | After case ...: [match] | true | -| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:13:81:19 | After case ...: [no-match] | false | -| Switch.cs:77:10:77:11 | Entry | Switch.cs:83:13:83:19 | After case ...: [match] | false | -| Switch.cs:77:10:77:11 | Entry | Switch.cs:83:13:83:19 | After case ...: [no-match] | false | +| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:18:81:18 | After 1 [match] | true | +| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:18:81:18 | After 1 [no-match] | false | +| Switch.cs:77:10:77:11 | Entry | Switch.cs:83:18:83:18 | After 2 [match] | false | +| Switch.cs:77:10:77:11 | Entry | Switch.cs:83:18:83:18 | After 2 [no-match] | false | | Switch.cs:77:10:77:11 | Entry | Switch.cs:84:21:84:25 | After ... > ... [false] | false | | Switch.cs:77:10:77:11 | Entry | Switch.cs:84:21:84:25 | After ... > ... [true] | false | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | After case ...: [match] | true | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | After case ...: [no-match] | false | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:84:21:84:25 | After ... > ... [false] | true | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:84:21:84:25 | After ... > ... [true] | true | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:84:21:84:25 | After ... > ... [false] | false | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:84:21:84:25 | After ... > ... [true] | true | -| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:13:95:23 | After case ...: [match] | true | -| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:13:95:23 | After case ...: [no-match] | false | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:83:18:83:18 | After 2 [match] | true | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:83:18:83:18 | After 2 [no-match] | false | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:84:21:84:25 | After ... > ... [false] | true | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:84:21:84:25 | After ... > ... [true] | true | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:84:21:84:25 | After ... > ... [false] | false | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:84:21:84:25 | After ... > ... [true] | true | +| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:18:95:20 | After access to type Int32 [match] | true | +| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | false | | Switch.cs:101:9:101:10 | Entry | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | false | | Switch.cs:101:9:101:10 | Entry | Switch.cs:103:17:103:17 | After access to parameter s [null] | true | -| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:13:105:19 | After case ...: [match] | true | -| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:13:105:19 | After case ...: [no-match] | false | -| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:106:13:106:19 | After case ...: [match] | false | -| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:106:13:106:19 | After case ...: [no-match] | false | -| Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:106:13:106:19 | After case ...: [match] | true | -| Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:106:13:106:19 | After case ...: [no-match] | false | -| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:13:117:35 | After case ...: [match] | true | -| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:13:117:35 | After case ...: [no-match] | false | +| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:18:105:18 | After 0 [match] | true | +| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:18:105:18 | After 0 [no-match] | false | +| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:106:18:106:18 | After 1 [match] | false | +| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:106:18:106:18 | After 1 [no-match] | false | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:106:18:106:18 | After 1 [match] | true | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:106:18:106:18 | After 1 [no-match] | false | +| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:18:117:18 | After 3 [match] | true | +| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:18:117:18 | After 3 [no-match] | false | | Switch.cs:113:9:113:11 | Entry | Switch.cs:117:25:117:34 | After ... == ... [false] | true | | Switch.cs:113:9:113:11 | Entry | Switch.cs:117:25:117:34 | After ... == ... [true] | true | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:25:117:34 | After ... == ... [false] | false | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:25:117:34 | After ... == ... [true] | true | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:25:118:33 | After ... == ... [false] | false | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:25:118:33 | After ... == ... [true] | true | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | After case ...: [match] | true | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | After case ...: [no-match] | false | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:117:25:117:34 | After ... == ... [false] | false | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:117:25:117:34 | After ... == ... [true] | true | +| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:18:118:18 | After 2 [match] | true | +| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:18:118:18 | After 2 [no-match] | false | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:25:118:33 | After ... == ... [false] | true | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:25:118:33 | After ... == ... [true] | true | -| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:34 | After ... => ... [match] | true | -| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:34 | After ... => ... [no-match] | false | -| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:40 | After ... => ... [match] | true | -| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:40 | After ... => ... [no-match] | false | -| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:13:139:19 | After case ...: [match] | true | -| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:13:139:19 | After case ...: [no-match] | false | -| Switch.cs:134:9:134:11 | Entry | Switch.cs:140:13:140:19 | After case ...: [match] | false | -| Switch.cs:134:9:134:11 | Entry | Switch.cs:140:13:140:19 | After case ...: [no-match] | false | -| Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:140:13:140:19 | After case ...: [match] | true | -| Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:140:13:140:19 | After case ...: [no-match] | false | -| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:13:148:19 | After case ...: [match] | true | -| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:13:148:19 | After case ...: [no-match] | false | -| Switch.cs:144:9:144:11 | Entry | Switch.cs:150:13:150:19 | After case ...: [match] | false | -| Switch.cs:144:9:144:11 | Entry | Switch.cs:150:13:150:19 | After case ...: [no-match] | false | -| Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:150:13:150:19 | After case ...: [match] | true | -| Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:150:13:150:19 | After case ...: [no-match] | false | -| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:38 | After ... => ... [match] | true | -| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:38 | After ... => ... [no-match] | false | -| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:41:156:52 | After ... => ... [match] | false | -| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:41:156:52 | After ... => ... [no-match] | false | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:118:25:118:33 | After ... == ... [false] | false | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:118:25:118:33 | After ... == ... [true] | true | +| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:29 | After Boolean b [match] | true | +| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:29 | After Boolean b [no-match] | false | +| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:35 | After String s [match] | true | +| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:35 | After String s [no-match] | false | +| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:18:139:18 | After 1 [match] | true | +| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:18:139:18 | After 1 [no-match] | false | +| Switch.cs:134:9:134:11 | Entry | Switch.cs:140:18:140:18 | After 2 [match] | false | +| Switch.cs:134:9:134:11 | Entry | Switch.cs:140:18:140:18 | After 2 [no-match] | false | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:140:18:140:18 | After 2 [match] | true | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:140:18:140:18 | After 2 [no-match] | false | +| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:18:148:18 | After 1 [match] | true | +| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:18:148:18 | After 1 [no-match] | false | +| Switch.cs:144:9:144:11 | Entry | Switch.cs:150:18:150:18 | After 2 [match] | false | +| Switch.cs:144:9:144:11 | Entry | Switch.cs:150:18:150:18 | After 2 [no-match] | false | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:150:18:150:18 | After 2 [match] | true | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:150:18:150:18 | After 2 [no-match] | false | +| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:31 | After true [match] | true | +| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:31 | After true [no-match] | false | +| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:41:156:45 | After false [match] | false | +| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:41:156:45 | After false [no-match] | false | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:157:13:157:13 | After access to parameter b [false] | false | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:157:13:157:13 | After access to parameter b [true] | true | -| Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | After ... => ... [match] | true | -| Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | After ... => ... [no-match] | false | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:13:167:19 | After case ...: [match] | true | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:13:167:19 | After case ...: [no-match] | false | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:168:13:168:19 | After case ...: [match] | false | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:168:13:168:19 | After case ...: [no-match] | false | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:171:13:171:19 | After case ...: [match] | false | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:171:13:171:19 | After case ...: [no-match] | false | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:168:13:168:19 | After case ...: [match] | true | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:168:13:168:19 | After case ...: [no-match] | false | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [match] | false | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [no-match] | false | -| Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [match] | true | -| Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [no-match] | false | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:156:41:156:45 | After false [match] | true | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:156:41:156:45 | After false [no-match] | false | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:18:167:18 | After 1 [match] | true | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:18:167:18 | After 1 [no-match] | false | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:168:18:168:18 | After 2 [match] | false | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:168:18:168:18 | After 2 [no-match] | false | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:171:18:171:18 | After 3 [match] | false | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:171:18:171:18 | After 3 [no-match] | false | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:168:18:168:18 | After 2 [match] | true | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:168:18:168:18 | After 2 [no-match] | false | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:171:18:171:18 | After 3 [match] | false | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:171:18:171:18 | After 3 [no-match] | false | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:171:18:171:18 | After 3 [match] | true | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:171:18:171:18 | After 3 [no-match] | false | | TypeAccesses.cs:3:10:3:10 | Entry | TypeAccesses.cs:7:13:7:22 | After ... is ... [false] | false | | TypeAccesses.cs:3:10:3:10 | Entry | TypeAccesses.cs:7:13:7:22 | [MatchTrue] ... is ... | true | | VarDecls.cs:19:7:19:8 | Entry | VarDecls.cs:25:20:25:20 | After access to parameter b [false] | false | @@ -873,41 +875,44 @@ conditionBlock | cflow.cs:28:22:28:31 | After ... == ... [false] | cflow.cs:30:22:30:31 | After ... == ... [true] | true | | cflow.cs:37:17:37:22 | Entry | cflow.cs:37:17:37:22 | Exit | false | | cflow.cs:37:17:37:22 | Entry | cflow.cs:39:9:50:9 | After switch (...) {...} | false | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:41:13:41:19 | After case ...: [no-match] | false | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:44:13:44:19 | After case ...: [no-match] | false | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:47:13:47:19 | After case ...: [match] | false | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:47:13:47:19 | After case ...: [no-match] | false | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:41:18:41:18 | After 1 [match] | true | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:41:18:41:18 | After 1 [no-match] | false | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:44:18:44:18 | After 2 [match] | false | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:44:18:44:18 | After 2 [no-match] | false | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:47:18:47:18 | After 3 [match] | false | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:47:18:47:18 | After 3 [no-match] | false | | cflow.cs:37:17:37:22 | Entry | cflow.cs:51:9:59:9 | After switch (...) {...} | false | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:53:13:53:20 | After case ...: [match] | false | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:53:13:53:20 | After case ...: [no-match] | false | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:53:18:53:19 | After 42 [match] | false | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:53:18:53:19 | After 42 [no-match] | false | | cflow.cs:37:17:37:22 | Entry | cflow.cs:60:9:66:9 | After switch (...) {...} | false | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:62:13:62:19 | After case ...: [match] | false | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:62:13:62:19 | After case ...: [no-match] | false | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:62:18:62:18 | After 0 [match] | false | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:62:18:62:18 | After 0 [no-match] | false | | cflow.cs:37:17:37:22 | Entry | cflow.cs:63:23:63:33 | After ... == ... [false] | false | | cflow.cs:37:17:37:22 | Entry | cflow.cs:63:23:63:33 | After ... == ... [true] | false | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:13:53:20 | After case ...: [match] | true | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:13:53:20 | After case ...: [no-match] | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Exit | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:39:9:50:9 | After switch (...) {...} | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:44:13:44:19 | After case ...: [no-match] | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [match] | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:51:9:59:9 | After switch (...) {...} | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:53:13:53:20 | After case ...: [match] | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:53:13:53:20 | After case ...: [no-match] | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:60:9:66:9 | After switch (...) {...} | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:62:13:62:19 | After case ...: [match] | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:62:13:62:19 | After case ...: [no-match] | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:63:23:63:33 | After ... == ... [false] | false | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:63:23:63:33 | After ... == ... [true] | false | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [match] | true | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | false | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:13:62:19 | After case ...: [match] | true | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:13:62:19 | After case ...: [no-match] | false | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:18:53:19 | After 42 [match] | true | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:18:53:19 | After 42 [no-match] | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:37:17:37:22 | Exit | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:39:9:50:9 | After switch (...) {...} | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:44:18:44:18 | After 2 [match] | true | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:44:18:44:18 | After 2 [no-match] | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:47:18:47:18 | After 3 [match] | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:47:18:47:18 | After 3 [no-match] | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:51:9:59:9 | After switch (...) {...} | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:53:18:53:19 | After 42 [match] | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:53:18:53:19 | After 42 [no-match] | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:60:9:66:9 | After switch (...) {...} | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:62:18:62:18 | After 0 [match] | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:62:18:62:18 | After 0 [no-match] | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:63:23:63:33 | After ... == ... [false] | false | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:63:23:63:33 | After ... == ... [true] | false | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:47:18:47:18 | After 3 [match] | true | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:47:18:47:18 | After 3 [no-match] | false | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:18:62:18 | After 0 [match] | true | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:18:62:18 | After 0 [no-match] | false | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:63:23:63:33 | After ... == ... [false] | true | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:63:23:63:33 | After ... == ... [true] | true | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:63:23:63:33 | After ... == ... [false] | false | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:63:23:63:33 | After ... == ... [true] | true | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:63:23:63:33 | After ... == ... [false] | false | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:63:23:63:33 | After ... == ... [true] | true | | cflow.cs:70:18:70:18 | Entry | cflow.cs:72:13:72:21 | After ... == ... [false] | false | | cflow.cs:70:18:70:18 | Entry | cflow.cs:72:13:72:21 | After ... == ... [true] | true | | cflow.cs:70:18:70:18 | Entry | cflow.cs:74:9:81:9 | After if (...) ... | false | @@ -1054,25 +1059,25 @@ conditionBlock | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:244:13:244:28 | After ... > ... [false] | false | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:244:13:244:28 | After ... > ... [true] | true | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:246:9:258:9 | After switch (...) {...} | false | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:248:13:248:19 | After case ...: [match] | false | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:248:13:248:19 | After case ...: [no-match] | false | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:250:13:250:19 | After case ...: [match] | false | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:250:13:250:19 | After case ...: [no-match] | false | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:13:253:19 | After case ...: [match] | false | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:13:253:19 | After case ...: [no-match] | false | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:248:18:248:18 | After 0 [match] | false | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:248:18:248:18 | After 0 [no-match] | false | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:250:18:250:18 | After 1 [match] | false | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:250:18:250:18 | After 1 [no-match] | false | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:18:253:18 | After 2 [match] | false | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:18:253:18 | After 2 [no-match] | false | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:255:13:255:20 | After default: [match] | false | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:13:248:19 | After case ...: [match] | true | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:13:248:19 | After case ...: [no-match] | false | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:250:13:250:19 | After case ...: [match] | false | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:250:13:250:19 | After case ...: [no-match] | false | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:13:253:19 | After case ...: [match] | false | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:13:253:19 | After case ...: [no-match] | false | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:250:13:250:19 | After case ...: [match] | true | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:250:13:250:19 | After case ...: [no-match] | false | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [match] | false | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [no-match] | false | -| cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [match] | true | -| cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [no-match] | false | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:18:248:18 | After 0 [match] | true | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:18:248:18 | After 0 [no-match] | false | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:250:18:250:18 | After 1 [match] | false | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:250:18:250:18 | After 1 [no-match] | false | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:18:253:18 | After 2 [match] | false | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:18:253:18 | After 2 [no-match] | false | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:250:18:250:18 | After 1 [match] | true | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:250:18:250:18 | After 1 [no-match] | false | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:253:18:253:18 | After 2 [match] | false | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:253:18:253:18 | After 2 [no-match] | false | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:253:18:253:18 | After 2 [match] | true | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:253:18:253:18 | After 2 [no-match] | false | | cflow.cs:264:25:264:30 | Before ... < ... | cflow.cs:261:49:261:53 | Exceptional Exit | false | | cflow.cs:264:25:264:30 | Before ... < ... | cflow.cs:261:49:261:53 | Exit | false | | cflow.cs:264:25:264:30 | Before ... < ... | cflow.cs:261:49:261:53 | Normal Exit | false | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected index 51d4721caea..5001f49300a 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected @@ -5212,16 +5212,20 @@ dominance | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:40:9:42:9 | switch (...) {...} | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:20:17:20:17 | access to local variable o | | Patterns.cs:20:17:20:17 | access to local variable o | Patterns.cs:22:13:22:23 | case ...: | -| Patterns.cs:22:13:22:23 | After case ...: [match] | Patterns.cs:22:18:22:22 | "xyz" | +| Patterns.cs:22:13:22:23 | After case ...: [match] | Patterns.cs:23:17:23:22 | Before break; | | Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | case ...: | -| Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:22:13:22:23 | After case ...: [match] | -| Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:22:13:22:23 | After case ...: [no-match] | -| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:23:17:23:22 | Before break; | +| Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:22:18:22:22 | "xyz" | +| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:22:18:22:22 | After "xyz" [match] | +| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:22:18:22:22 | After "xyz" [no-match] | +| Patterns.cs:22:18:22:22 | After "xyz" [match] | Patterns.cs:22:13:22:23 | After case ...: [match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:22:13:22:23 | After case ...: [no-match] | | Patterns.cs:23:17:23:22 | Before break; | Patterns.cs:23:17:23:22 | break; | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:18:24:23 | Int32 i2 | -| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:24:13:24:36 | After case ...: [match] | -| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:24:13:24:36 | After case ...: [no-match] | -| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:24:30:24:35 | Before ... > ... | +| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:30:24:35 | Before ... > ... | +| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:24:18:24:23 | Int32 i2 | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:24:13:24:36 | After case ...: [match] | +| Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | Patterns.cs:24:13:24:36 | After case ...: [no-match] | +| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | +| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | | Patterns.cs:24:30:24:31 | access to local variable i2 | Patterns.cs:24:35:24:35 | 0 | | Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:24:30:24:35 | After ... > ... [false] | | Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:24:30:24:35 | After ... > ... [true] | @@ -5242,11 +5246,13 @@ dominance | Patterns.cs:25:46:25:49 | {...} | Patterns.cs:25:46:25:49 | After {...} | | Patterns.cs:25:47:25:48 | access to local variable i2 | Patterns.cs:25:46:25:49 | {...} | | Patterns.cs:26:17:26:22 | Before break; | Patterns.cs:26:17:26:22 | break; | -| Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:27:18:27:23 | Int32 i3 | +| Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:28:17:28:47 | ...; | | Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | case ...: | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | After case ...: [match] | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | After case ...: [no-match] | -| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:28:17:28:47 | ...; | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:18:27:23 | Int32 i3 | +| Patterns.cs:27:18:27:23 | After Int32 i3 [match] | Patterns.cs:27:13:27:24 | After case ...: [match] | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:27:13:27:24 | After case ...: [no-match] | +| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | +| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | | Patterns.cs:28:17:28:46 | After call to method WriteLine | Patterns.cs:28:17:28:47 | After ...; | | Patterns.cs:28:17:28:46 | Before call to method WriteLine | Patterns.cs:28:35:28:45 | Before $"..." | | Patterns.cs:28:17:28:46 | call to method WriteLine | Patterns.cs:28:17:28:46 | After call to method WriteLine | @@ -5261,11 +5267,13 @@ dominance | Patterns.cs:28:41:28:44 | {...} | Patterns.cs:28:41:28:44 | After {...} | | Patterns.cs:28:42:28:43 | access to local variable i3 | Patterns.cs:28:41:28:44 | {...} | | Patterns.cs:29:17:29:22 | Before break; | Patterns.cs:29:17:29:22 | break; | -| Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:30:18:30:26 | String s2 | +| Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:31:17:31:50 | ...; | | Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | case ...: | -| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:30:13:30:27 | After case ...: [match] | -| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:31:17:31:50 | ...; | +| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:30:18:30:26 | String s2 | +| Patterns.cs:30:18:30:26 | After String s2 [match] | Patterns.cs:30:13:30:27 | After case ...: [match] | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:30:13:30:27 | After case ...: [no-match] | +| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:30:18:30:26 | After String s2 [no-match] | | Patterns.cs:31:17:31:49 | After call to method WriteLine | Patterns.cs:31:17:31:50 | After ...; | | Patterns.cs:31:17:31:49 | Before call to method WriteLine | Patterns.cs:31:35:31:48 | Before $"..." | | Patterns.cs:31:17:31:49 | call to method WriteLine | Patterns.cs:31:17:31:49 | After call to method WriteLine | @@ -5280,11 +5288,13 @@ dominance | Patterns.cs:31:44:31:47 | {...} | Patterns.cs:31:44:31:47 | After {...} | | Patterns.cs:31:45:31:46 | access to local variable s2 | Patterns.cs:31:44:31:47 | {...} | | Patterns.cs:32:17:32:22 | Before break; | Patterns.cs:32:17:32:22 | break; | -| Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:33:18:33:23 | Object v2 | +| Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:34:17:34:22 | Before break; | | Patterns.cs:33:13:33:24 | After case ...: [no-match] | Patterns.cs:35:13:35:20 | default: | -| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:33:13:33:24 | After case ...: [no-match] | -| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:34:17:34:22 | Before break; | +| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:33:18:33:23 | Object v2 | +| Patterns.cs:33:18:33:23 | After Object v2 [match] | Patterns.cs:33:13:33:24 | After case ...: [match] | +| Patterns.cs:33:18:33:23 | After Object v2 [no-match] | Patterns.cs:33:13:33:24 | After case ...: [no-match] | +| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | | Patterns.cs:34:17:34:22 | Before break; | Patterns.cs:34:17:34:22 | break; | | Patterns.cs:35:13:35:20 | After default: [match] | Patterns.cs:36:17:36:52 | ...; | | Patterns.cs:35:13:35:20 | default: | Patterns.cs:35:13:35:20 | After default: [match] | @@ -5365,17 +5375,19 @@ dominance | Patterns.cs:58:16:58:16 | access to parameter i | Patterns.cs:60:13:60:28 | ... => ... | | Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:58:16:58:16 | access to parameter i | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:58:9:62:10 | return ...; | -| Patterns.cs:60:13:60:17 | After not ... | Patterns.cs:60:22:60:28 | "not 1" | +| Patterns.cs:60:13:60:17 | After not ... [match] | Patterns.cs:60:13:60:28 | After ... => ... [match] | +| Patterns.cs:60:13:60:17 | After not ... [no-match] | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | | Patterns.cs:60:13:60:17 | Before not ... | Patterns.cs:60:17:60:17 | 1 | -| Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:13:60:17 | After not ... | -| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:60:13:60:28 | After ... => ... [match] | -| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | -| Patterns.cs:60:13:60:28 | After ... => ... [match] | Patterns.cs:60:13:60:17 | Before not ... | +| Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:13:60:17 | After not ... [match] | +| Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:13:60:17 | After not ... [no-match] | +| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:60:13:60:17 | Before not ... | +| Patterns.cs:60:13:60:28 | After ... => ... [match] | Patterns.cs:60:22:60:28 | "not 1" | | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | Patterns.cs:61:13:61:24 | ... => ... | | Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:13:60:17 | not ... | -| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:18:61:24 | "other" | -| Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:61:13:61:24 | After ... => ... [match] | -| Patterns.cs:61:13:61:24 | After ... => ... [match] | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:61:13:61:13 | After _ [match] | Patterns.cs:61:13:61:24 | After ... => ... [match] | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:13:61:13 | After _ [match] | +| Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:61:13:61:24 | After ... => ... [match] | Patterns.cs:61:18:61:24 | "other" | | Patterns.cs:65:26:65:27 | Entry | Patterns.cs:66:5:72:5 | {...} | | Patterns.cs:65:26:65:27 | Normal Exit | Patterns.cs:65:26:65:27 | Exit | | Patterns.cs:66:5:72:5 | {...} | Patterns.cs:67:9:71:10 | Before return ...; | @@ -5384,18 +5396,21 @@ dominance | Patterns.cs:67:16:67:16 | 2 | Patterns.cs:69:13:69:33 | ... => ... | | Patterns.cs:67:16:71:9 | ... switch { ... } | Patterns.cs:67:16:67:16 | 2 | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:67:9:71:10 | return ...; | -| Patterns.cs:69:13:69:17 | After not ... | Patterns.cs:69:22:69:33 | "impossible" | +| Patterns.cs:69:13:69:17 | After not ... [match] | Patterns.cs:69:13:69:33 | After ... => ... [match] | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | | Patterns.cs:69:13:69:17 | Before not ... | Patterns.cs:69:17:69:17 | 2 | -| Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:13:69:17 | After not ... | -| Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:69:13:69:33 | After ... => ... [match] | -| Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | -| Patterns.cs:69:13:69:33 | After ... => ... [match] | Patterns.cs:69:13:69:17 | Before not ... | +| Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:13:69:17 | After not ... [match] | +| Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:13:69:17 | After not ... [no-match] | +| Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:69:13:69:17 | Before not ... | +| Patterns.cs:69:13:69:33 | After ... => ... [match] | Patterns.cs:69:22:69:33 | "impossible" | | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | ... => ... | | Patterns.cs:69:17:69:17 | 2 | Patterns.cs:69:13:69:17 | not ... | -| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:18:70:27 | "possible" | -| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:70:13:70:27 | After ... => ... [match] | -| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | -| Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:13 | After 2 [match] | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:13 | After 2 [no-match] | +| Patterns.cs:70:13:70:13 | After 2 [match] | Patterns.cs:70:13:70:27 | After ... => ... [match] | +| Patterns.cs:70:13:70:13 | After 2 [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | +| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:70:18:70:27 | "possible" | | Patterns.cs:74:26:74:27 | Entry | Patterns.cs:74:33:74:33 | i | | Patterns.cs:74:26:74:27 | Normal Exit | Patterns.cs:74:26:74:27 | Exit | | Patterns.cs:74:33:74:33 | i | Patterns.cs:75:5:83:5 | {...} | @@ -5405,30 +5420,35 @@ dominance | Patterns.cs:76:16:76:16 | access to parameter i | Patterns.cs:78:13:78:24 | ... => ... | | Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:76:16:76:16 | access to parameter i | | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:76:9:82:10 | return ...; | -| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:13:78:15 | After > ... | -| Patterns.cs:78:13:78:15 | After > ... | Patterns.cs:78:20:78:24 | "> 1" | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:13:78:15 | After > ... [match] | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:13:78:15 | After > ... [no-match] | +| Patterns.cs:78:13:78:15 | After > ... [match] | Patterns.cs:78:13:78:24 | After ... => ... [match] | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | | Patterns.cs:78:13:78:15 | Before > ... | Patterns.cs:78:15:78:15 | 1 | -| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:78:13:78:24 | After ... => ... [match] | -| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | -| Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:78:13:78:15 | Before > ... | +| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:78:13:78:15 | Before > ... | +| Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:78:20:78:24 | "> 1" | | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:24 | ... => ... | | Patterns.cs:78:15:78:15 | 1 | Patterns.cs:78:13:78:15 | > ... | -| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:13:79:15 | After < ... | -| Patterns.cs:79:13:79:15 | After < ... | Patterns.cs:79:20:79:24 | "< 0" | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:13:79:15 | After < ... [match] | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:13:79:15 | After < ... [no-match] | +| Patterns.cs:79:13:79:15 | After < ... [match] | Patterns.cs:79:13:79:24 | After ... => ... [match] | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | | Patterns.cs:79:13:79:15 | Before < ... | Patterns.cs:79:15:79:15 | 0 | -| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:79:13:79:24 | After ... => ... [match] | -| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | -| Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:79:13:79:15 | Before < ... | +| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:79:13:79:15 | Before < ... | +| Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:79:20:79:24 | "< 0" | | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | ... => ... | | Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:13:79:15 | < ... | -| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:18:80:20 | "1" | -| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:13:80:20 | After ... => ... [match] | -| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | -| Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | After 1 [match] | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | After 1 [no-match] | +| Patterns.cs:80:13:80:13 | After 1 [match] | Patterns.cs:80:13:80:20 | After ... => ... [match] | +| Patterns.cs:80:13:80:13 | After 1 [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | +| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:80:18:80:20 | "1" | | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | Patterns.cs:81:13:81:20 | ... => ... | -| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" | -| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:13:81:20 | After ... => ... [match] | -| Patterns.cs:81:13:81:20 | After ... => ... [match] | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:81:13:81:13 | After _ [match] | Patterns.cs:81:13:81:20 | After ... => ... [match] | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | After _ [match] | +| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:81:13:81:20 | After ... => ... [match] | Patterns.cs:81:18:81:20 | "0" | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:33:85:33 | i | | Patterns.cs:85:26:85:27 | Normal Exit | Patterns.cs:85:26:85:27 | Exit | | Patterns.cs:85:33:85:33 | i | Patterns.cs:85:39:85:69 | ... ? ... : ... | @@ -5754,32 +5774,39 @@ dominance | Switch.cs:11:5:33:5 | {...} | Switch.cs:12:9:32:9 | switch (...) {...} | | Switch.cs:12:9:32:9 | switch (...) {...} | Switch.cs:12:17:12:17 | access to parameter o | | Switch.cs:12:17:12:17 | access to parameter o | Switch.cs:14:13:14:21 | case ...: | -| Switch.cs:14:13:14:21 | After case ...: [match] | Switch.cs:14:18:14:20 | "a" | +| Switch.cs:14:13:14:21 | After case ...: [match] | Switch.cs:15:17:15:23 | Before return ...; | | Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:16:13:16:19 | case ...: | -| Switch.cs:14:13:14:21 | case ...: | Switch.cs:14:13:14:21 | After case ...: [match] | -| Switch.cs:14:13:14:21 | case ...: | Switch.cs:14:13:14:21 | After case ...: [no-match] | -| Switch.cs:14:18:14:20 | "a" | Switch.cs:15:17:15:23 | Before return ...; | +| Switch.cs:14:13:14:21 | case ...: | Switch.cs:14:18:14:20 | "a" | +| Switch.cs:14:18:14:20 | "a" | Switch.cs:14:18:14:20 | After "a" [match] | +| Switch.cs:14:18:14:20 | "a" | Switch.cs:14:18:14:20 | After "a" [no-match] | +| Switch.cs:14:18:14:20 | After "a" [match] | Switch.cs:14:13:14:21 | After case ...: [match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:14:13:14:21 | After case ...: [no-match] | | Switch.cs:15:17:15:23 | Before return ...; | Switch.cs:15:17:15:23 | return ...; | -| Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:16:18:16:18 | 0 | +| Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:17:17:17:38 | Before throw ...; | | Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:18:13:18:22 | case ...: | -| Switch.cs:16:13:16:19 | case ...: | Switch.cs:16:13:16:19 | After case ...: [match] | -| Switch.cs:16:13:16:19 | case ...: | Switch.cs:16:13:16:19 | After case ...: [no-match] | -| Switch.cs:16:18:16:18 | 0 | Switch.cs:17:17:17:38 | Before throw ...; | +| Switch.cs:16:13:16:19 | case ...: | Switch.cs:16:18:16:18 | 0 | +| Switch.cs:16:18:16:18 | 0 | Switch.cs:16:18:16:18 | After 0 [match] | +| Switch.cs:16:18:16:18 | 0 | Switch.cs:16:18:16:18 | After 0 [no-match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:16:13:16:19 | After case ...: [no-match] | | Switch.cs:17:17:17:38 | Before throw ...; | Switch.cs:17:23:17:37 | Before object creation of type Exception | | Switch.cs:17:23:17:37 | After object creation of type Exception | Switch.cs:17:17:17:38 | throw ...; | | Switch.cs:17:23:17:37 | Before object creation of type Exception | Switch.cs:17:23:17:37 | object creation of type Exception | | Switch.cs:17:23:17:37 | object creation of type Exception | Switch.cs:17:23:17:37 | After object creation of type Exception | -| Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:18:18:18:21 | null | +| Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:19:17:19:29 | Before goto default; | | Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:20:13:20:23 | case ...: | -| Switch.cs:18:13:18:22 | case ...: | Switch.cs:18:13:18:22 | After case ...: [match] | -| Switch.cs:18:13:18:22 | case ...: | Switch.cs:18:13:18:22 | After case ...: [no-match] | -| Switch.cs:18:18:18:21 | null | Switch.cs:19:17:19:29 | Before goto default; | +| Switch.cs:18:13:18:22 | case ...: | Switch.cs:18:18:18:21 | null | +| Switch.cs:18:18:18:21 | After null [match] | Switch.cs:18:13:18:22 | After case ...: [match] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:18:13:18:22 | After case ...: [no-match] | +| Switch.cs:18:18:18:21 | null | Switch.cs:18:18:18:21 | After null [match] | +| Switch.cs:18:18:18:21 | null | Switch.cs:18:18:18:21 | After null [no-match] | | Switch.cs:19:17:19:29 | Before goto default; | Switch.cs:19:17:19:29 | goto default; | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:20:18:20:22 | Int32 i | +| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:21:17:22:27 | if (...) ... | | Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:13:24:56 | case ...: | -| Switch.cs:20:13:20:23 | case ...: | Switch.cs:20:13:20:23 | After case ...: [match] | -| Switch.cs:20:13:20:23 | case ...: | Switch.cs:20:13:20:23 | After case ...: [no-match] | -| Switch.cs:20:18:20:22 | Int32 i | Switch.cs:21:17:22:27 | if (...) ... | +| Switch.cs:20:13:20:23 | case ...: | Switch.cs:20:18:20:22 | Int32 i | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:20:13:20:23 | After case ...: [match] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | +| Switch.cs:20:18:20:22 | Int32 i | Switch.cs:20:18:20:22 | After Int32 i [match] | +| Switch.cs:20:18:20:22 | Int32 i | Switch.cs:20:18:20:22 | After Int32 i [no-match] | | Switch.cs:21:17:22:27 | After if (...) ... | Switch.cs:23:17:23:28 | Before goto case ...; | | Switch.cs:21:17:22:27 | if (...) ... | Switch.cs:21:21:21:29 | Before ... == ... | | Switch.cs:21:21:21:21 | access to parameter o | Switch.cs:21:26:21:29 | null | @@ -5792,10 +5819,12 @@ dominance | Switch.cs:22:21:22:27 | Before return ...; | Switch.cs:22:21:22:27 | return ...; | | Switch.cs:23:17:23:28 | Before goto case ...; | Switch.cs:23:27:23:27 | 0 | | Switch.cs:23:27:23:27 | 0 | Switch.cs:23:17:23:28 | goto case ...; | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:18:24:25 | String s | -| Switch.cs:24:13:24:56 | case ...: | Switch.cs:24:13:24:56 | After case ...: [match] | -| Switch.cs:24:13:24:56 | case ...: | Switch.cs:24:13:24:56 | After case ...: [no-match] | -| Switch.cs:24:18:24:25 | String s | Switch.cs:24:32:24:55 | ... && ... | +| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:32:24:55 | ... && ... | +| Switch.cs:24:13:24:56 | case ...: | Switch.cs:24:18:24:25 | String s | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:13:24:56 | After case ...: [match] | +| Switch.cs:24:18:24:25 | After String s [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | +| Switch.cs:24:18:24:25 | String s | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:24:18:24:25 | String s | Switch.cs:24:18:24:25 | After String s [no-match] | | Switch.cs:24:32:24:32 | access to local variable s | Switch.cs:24:32:24:39 | access to property Length | | Switch.cs:24:32:24:39 | After access to property Length | Switch.cs:24:43:24:43 | 0 | | Switch.cs:24:32:24:39 | Before access to property Length | Switch.cs:24:32:24:32 | access to local variable s | @@ -5820,11 +5849,13 @@ dominance | Switch.cs:25:17:25:37 | After ...; | Switch.cs:26:17:26:23 | Before return ...; | | Switch.cs:25:35:25:35 | access to local variable s | Switch.cs:25:17:25:36 | call to method WriteLine | | Switch.cs:26:17:26:23 | Before return ...; | Switch.cs:26:17:26:23 | return ...; | -| Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:27:18:27:25 | Double d | +| Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:27:32:27:38 | Before call to method Throw | | Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:30:13:30:20 | default: | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | After case ...: [no-match] | -| Switch.cs:27:18:27:25 | Double d | Switch.cs:27:32:27:38 | Before call to method Throw | +| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:18:27:25 | Double d | +| Switch.cs:27:18:27:25 | After Double d [match] | Switch.cs:27:13:27:39 | After case ...: [match] | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | +| Switch.cs:27:18:27:25 | Double d | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:27:18:27:25 | Double d | Switch.cs:27:18:27:25 | After Double d [no-match] | | Switch.cs:27:32:27:38 | Before call to method Throw | Switch.cs:27:32:27:38 | call to method Throw | | Switch.cs:28:13:28:17 | Label: | Switch.cs:29:17:29:23 | Before return ...; | | Switch.cs:29:17:29:23 | Before return ...; | Switch.cs:29:17:29:23 | return ...; | @@ -5845,16 +5876,20 @@ dominance | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:45:5:53:5 | After {...} | | Switch.cs:46:9:52:9 | switch (...) {...} | Switch.cs:46:17:46:17 | access to parameter o | | Switch.cs:46:17:46:17 | access to parameter o | Switch.cs:48:13:48:23 | case ...: | -| Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:48:18:48:20 | access to type Int32 | +| Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:49:17:49:22 | Before break; | | Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:13:50:39 | case ...: | -| Switch.cs:48:13:48:23 | case ...: | Switch.cs:48:13:48:23 | After case ...: [match] | -| Switch.cs:48:13:48:23 | case ...: | Switch.cs:48:13:48:23 | After case ...: [no-match] | -| Switch.cs:48:18:48:20 | access to type Int32 | Switch.cs:49:17:49:22 | Before break; | +| Switch.cs:48:13:48:23 | case ...: | Switch.cs:48:18:48:20 | access to type Int32 | +| Switch.cs:48:18:48:20 | After access to type Int32 [match] | Switch.cs:48:13:48:23 | After case ...: [match] | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:48:13:48:23 | After case ...: [no-match] | +| Switch.cs:48:18:48:20 | access to type Int32 | Switch.cs:48:18:48:20 | After access to type Int32 [match] | +| Switch.cs:48:18:48:20 | access to type Int32 | Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | | Switch.cs:49:17:49:22 | Before break; | Switch.cs:49:17:49:22 | break; | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:18:50:21 | access to type Boolean | -| Switch.cs:50:13:50:39 | case ...: | Switch.cs:50:13:50:39 | After case ...: [match] | -| Switch.cs:50:13:50:39 | case ...: | Switch.cs:50:13:50:39 | After case ...: [no-match] | -| Switch.cs:50:18:50:21 | access to type Boolean | Switch.cs:50:30:50:38 | Before ... != ... | +| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:30:50:38 | Before ... != ... | +| Switch.cs:50:13:50:39 | case ...: | Switch.cs:50:18:50:21 | access to type Boolean | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:50:13:50:39 | After case ...: [match] | +| Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | Switch.cs:50:13:50:39 | After case ...: [no-match] | +| Switch.cs:50:18:50:21 | access to type Boolean | Switch.cs:50:18:50:21 | After access to type Boolean [match] | +| Switch.cs:50:18:50:21 | access to type Boolean | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | | Switch.cs:50:30:50:30 | access to parameter o | Switch.cs:50:35:50:38 | null | | Switch.cs:50:30:50:38 | ... != ... | Switch.cs:50:30:50:38 | After ... != ... [false] | | Switch.cs:50:30:50:38 | ... != ... | Switch.cs:50:30:50:38 | After ... != ... [true] | @@ -5873,16 +5908,20 @@ dominance | Switch.cs:57:17:57:21 | After ... + ... | Switch.cs:59:13:59:19 | case ...: | | Switch.cs:57:17:57:21 | Before ... + ... | Switch.cs:57:17:57:17 | 1 | | Switch.cs:57:21:57:21 | 2 | Switch.cs:57:17:57:21 | ... + ... | -| Switch.cs:59:13:59:19 | After case ...: [match] | Switch.cs:59:18:59:18 | 2 | +| Switch.cs:59:13:59:19 | After case ...: [match] | Switch.cs:60:17:60:22 | Before break; | | Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | case ...: | -| Switch.cs:59:13:59:19 | case ...: | Switch.cs:59:13:59:19 | After case ...: [match] | -| Switch.cs:59:13:59:19 | case ...: | Switch.cs:59:13:59:19 | After case ...: [no-match] | -| Switch.cs:59:18:59:18 | 2 | Switch.cs:60:17:60:22 | Before break; | +| Switch.cs:59:13:59:19 | case ...: | Switch.cs:59:18:59:18 | 2 | +| Switch.cs:59:18:59:18 | 2 | Switch.cs:59:18:59:18 | After 2 [match] | +| Switch.cs:59:18:59:18 | 2 | Switch.cs:59:18:59:18 | After 2 [no-match] | +| Switch.cs:59:18:59:18 | After 2 [match] | Switch.cs:59:13:59:19 | After case ...: [match] | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:59:13:59:19 | After case ...: [no-match] | | Switch.cs:60:17:60:22 | Before break; | Switch.cs:60:17:60:22 | break; | -| Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:61:18:61:18 | 3 | -| Switch.cs:61:13:61:19 | case ...: | Switch.cs:61:13:61:19 | After case ...: [match] | -| Switch.cs:61:13:61:19 | case ...: | Switch.cs:61:13:61:19 | After case ...: [no-match] | -| Switch.cs:61:18:61:18 | 3 | Switch.cs:62:17:62:22 | Before break; | +| Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:62:17:62:22 | Before break; | +| Switch.cs:61:13:61:19 | case ...: | Switch.cs:61:18:61:18 | 3 | +| Switch.cs:61:18:61:18 | 3 | Switch.cs:61:18:61:18 | After 3 [match] | +| Switch.cs:61:18:61:18 | 3 | Switch.cs:61:18:61:18 | After 3 [no-match] | +| Switch.cs:61:18:61:18 | After 3 [match] | Switch.cs:61:13:61:19 | After case ...: [match] | +| Switch.cs:61:18:61:18 | After 3 [no-match] | Switch.cs:61:13:61:19 | After case ...: [no-match] | | Switch.cs:62:17:62:22 | Before break; | Switch.cs:62:17:62:22 | break; | | Switch.cs:66:10:66:11 | Entry | Switch.cs:66:20:66:20 | s | | Switch.cs:66:10:66:11 | Normal Exit | Switch.cs:66:10:66:11 | Exit | @@ -5895,16 +5934,20 @@ dominance | Switch.cs:68:17:68:25 | After (...) ... | Switch.cs:70:13:70:23 | case ...: | | Switch.cs:68:17:68:25 | Before (...) ... | Switch.cs:68:25:68:25 | access to parameter s | | Switch.cs:68:25:68:25 | access to parameter s | Switch.cs:68:17:68:25 | (...) ... | -| Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:70:18:70:20 | access to type Int32 | +| Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:71:17:71:22 | Before break; | | Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:72:13:72:20 | case ...: | -| Switch.cs:70:13:70:23 | case ...: | Switch.cs:70:13:70:23 | After case ...: [match] | -| Switch.cs:70:13:70:23 | case ...: | Switch.cs:70:13:70:23 | After case ...: [no-match] | -| Switch.cs:70:18:70:20 | access to type Int32 | Switch.cs:71:17:71:22 | Before break; | +| Switch.cs:70:13:70:23 | case ...: | Switch.cs:70:18:70:20 | access to type Int32 | +| Switch.cs:70:18:70:20 | After access to type Int32 [match] | Switch.cs:70:13:70:23 | After case ...: [match] | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:70:13:70:23 | After case ...: [no-match] | +| Switch.cs:70:18:70:20 | access to type Int32 | Switch.cs:70:18:70:20 | After access to type Int32 [match] | +| Switch.cs:70:18:70:20 | access to type Int32 | Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | | Switch.cs:71:17:71:22 | Before break; | Switch.cs:71:17:71:22 | break; | -| Switch.cs:72:13:72:20 | After case ...: [match] | Switch.cs:72:18:72:19 | "" | -| Switch.cs:72:13:72:20 | case ...: | Switch.cs:72:13:72:20 | After case ...: [match] | -| Switch.cs:72:13:72:20 | case ...: | Switch.cs:72:13:72:20 | After case ...: [no-match] | -| Switch.cs:72:18:72:19 | "" | Switch.cs:73:17:73:22 | Before break; | +| Switch.cs:72:13:72:20 | After case ...: [match] | Switch.cs:73:17:73:22 | Before break; | +| Switch.cs:72:13:72:20 | case ...: | Switch.cs:72:18:72:19 | "" | +| Switch.cs:72:18:72:19 | "" | Switch.cs:72:18:72:19 | After "" [match] | +| Switch.cs:72:18:72:19 | "" | Switch.cs:72:18:72:19 | After "" [no-match] | +| Switch.cs:72:18:72:19 | After "" [match] | Switch.cs:72:13:72:20 | After case ...: [match] | +| Switch.cs:72:18:72:19 | After "" [no-match] | Switch.cs:72:13:72:20 | After case ...: [no-match] | | Switch.cs:73:17:73:22 | Before break; | Switch.cs:73:17:73:22 | break; | | Switch.cs:77:10:77:11 | Entry | Switch.cs:77:17:77:17 | i | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:77:10:77:11 | Exit | @@ -5914,17 +5957,21 @@ dominance | Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:88:9:88:21 | Before return ...; | | Switch.cs:79:9:87:9 | switch (...) {...} | Switch.cs:79:17:79:17 | access to parameter i | | Switch.cs:79:17:79:17 | access to parameter i | Switch.cs:81:13:81:19 | case ...: | -| Switch.cs:81:13:81:19 | After case ...: [match] | Switch.cs:81:18:81:18 | 1 | +| Switch.cs:81:13:81:19 | After case ...: [match] | Switch.cs:82:17:82:28 | Before return ...; | | Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | case ...: | -| Switch.cs:81:13:81:19 | case ...: | Switch.cs:81:13:81:19 | After case ...: [match] | -| Switch.cs:81:13:81:19 | case ...: | Switch.cs:81:13:81:19 | After case ...: [no-match] | -| Switch.cs:81:18:81:18 | 1 | Switch.cs:82:17:82:28 | Before return ...; | +| Switch.cs:81:13:81:19 | case ...: | Switch.cs:81:18:81:18 | 1 | +| Switch.cs:81:18:81:18 | 1 | Switch.cs:81:18:81:18 | After 1 [match] | +| Switch.cs:81:18:81:18 | 1 | Switch.cs:81:18:81:18 | After 1 [no-match] | +| Switch.cs:81:18:81:18 | After 1 [match] | Switch.cs:81:13:81:19 | After case ...: [match] | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:81:13:81:19 | After case ...: [no-match] | | Switch.cs:82:17:82:28 | Before return ...; | Switch.cs:82:24:82:27 | true | | Switch.cs:82:24:82:27 | true | Switch.cs:82:17:82:28 | return ...; | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:83:18:83:18 | 2 | -| Switch.cs:83:13:83:19 | case ...: | Switch.cs:83:13:83:19 | After case ...: [match] | -| Switch.cs:83:13:83:19 | case ...: | Switch.cs:83:13:83:19 | After case ...: [no-match] | -| Switch.cs:83:18:83:18 | 2 | Switch.cs:84:17:85:26 | if (...) ... | +| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:84:17:85:26 | if (...) ... | +| Switch.cs:83:13:83:19 | case ...: | Switch.cs:83:18:83:18 | 2 | +| Switch.cs:83:18:83:18 | 2 | Switch.cs:83:18:83:18 | After 2 [match] | +| Switch.cs:83:18:83:18 | 2 | Switch.cs:83:18:83:18 | After 2 [no-match] | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:83:13:83:19 | After case ...: [match] | +| Switch.cs:83:18:83:18 | After 2 [no-match] | Switch.cs:83:13:83:19 | After case ...: [no-match] | | Switch.cs:84:17:85:26 | After if (...) ... | Switch.cs:86:17:86:28 | Before return ...; | | Switch.cs:84:17:85:26 | if (...) ... | Switch.cs:84:21:84:25 | Before ... > ... | | Switch.cs:84:21:84:21 | access to parameter j | Switch.cs:84:25:84:25 | 2 | @@ -5946,11 +5993,13 @@ dominance | Switch.cs:93:9:97:9 | After switch (...) {...} | Switch.cs:98:9:98:21 | Before return ...; | | Switch.cs:93:9:97:9 | switch (...) {...} | Switch.cs:93:17:93:17 | access to parameter o | | Switch.cs:93:17:93:17 | access to parameter o | Switch.cs:95:13:95:23 | case ...: | -| Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:95:18:95:20 | access to type Int32 | +| Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:96:17:96:28 | Before return ...; | | Switch.cs:95:13:95:23 | After case ...: [no-match] | Switch.cs:93:9:97:9 | After switch (...) {...} | -| Switch.cs:95:13:95:23 | case ...: | Switch.cs:95:13:95:23 | After case ...: [match] | -| Switch.cs:95:13:95:23 | case ...: | Switch.cs:95:13:95:23 | After case ...: [no-match] | -| Switch.cs:95:18:95:20 | access to type Int32 | Switch.cs:96:17:96:28 | Before return ...; | +| Switch.cs:95:13:95:23 | case ...: | Switch.cs:95:18:95:20 | access to type Int32 | +| Switch.cs:95:18:95:20 | After access to type Int32 [match] | Switch.cs:95:13:95:23 | After case ...: [match] | +| Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | Switch.cs:95:13:95:23 | After case ...: [no-match] | +| Switch.cs:95:18:95:20 | access to type Int32 | Switch.cs:95:18:95:20 | After access to type Int32 [match] | +| Switch.cs:95:18:95:20 | access to type Int32 | Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | | Switch.cs:96:17:96:28 | Before return ...; | Switch.cs:96:24:96:27 | true | | Switch.cs:96:24:96:27 | true | Switch.cs:96:17:96:28 | return ...; | | Switch.cs:98:9:98:21 | Before return ...; | Switch.cs:98:16:98:20 | false | @@ -5966,18 +6015,22 @@ dominance | Switch.cs:103:17:103:17 | access to parameter s | Switch.cs:103:17:103:17 | After access to parameter s [null] | | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:13:105:19 | case ...: | | Switch.cs:103:17:103:25 | Before access to property Length | Switch.cs:103:17:103:17 | access to parameter s | -| Switch.cs:105:13:105:19 | After case ...: [match] | Switch.cs:105:18:105:18 | 0 | +| Switch.cs:105:13:105:19 | After case ...: [match] | Switch.cs:105:21:105:29 | Before return ...; | | Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:106:13:106:19 | case ...: | -| Switch.cs:105:13:105:19 | case ...: | Switch.cs:105:13:105:19 | After case ...: [match] | -| Switch.cs:105:13:105:19 | case ...: | Switch.cs:105:13:105:19 | After case ...: [no-match] | -| Switch.cs:105:18:105:18 | 0 | Switch.cs:105:21:105:29 | Before return ...; | +| Switch.cs:105:13:105:19 | case ...: | Switch.cs:105:18:105:18 | 0 | +| Switch.cs:105:18:105:18 | 0 | Switch.cs:105:18:105:18 | After 0 [match] | +| Switch.cs:105:18:105:18 | 0 | Switch.cs:105:18:105:18 | After 0 [no-match] | +| Switch.cs:105:18:105:18 | After 0 [match] | Switch.cs:105:13:105:19 | After case ...: [match] | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:105:13:105:19 | After case ...: [no-match] | | Switch.cs:105:21:105:29 | Before return ...; | Switch.cs:105:28:105:28 | 0 | | Switch.cs:105:28:105:28 | 0 | Switch.cs:105:21:105:29 | return ...; | -| Switch.cs:106:13:106:19 | After case ...: [match] | Switch.cs:106:18:106:18 | 1 | +| Switch.cs:106:13:106:19 | After case ...: [match] | Switch.cs:106:21:106:29 | Before return ...; | | Switch.cs:106:13:106:19 | After case ...: [no-match] | Switch.cs:103:9:107:9 | After switch (...) {...} | -| Switch.cs:106:13:106:19 | case ...: | Switch.cs:106:13:106:19 | After case ...: [match] | -| Switch.cs:106:13:106:19 | case ...: | Switch.cs:106:13:106:19 | After case ...: [no-match] | -| Switch.cs:106:18:106:18 | 1 | Switch.cs:106:21:106:29 | Before return ...; | +| Switch.cs:106:13:106:19 | case ...: | Switch.cs:106:18:106:18 | 1 | +| Switch.cs:106:18:106:18 | 1 | Switch.cs:106:18:106:18 | After 1 [match] | +| Switch.cs:106:18:106:18 | 1 | Switch.cs:106:18:106:18 | After 1 [no-match] | +| Switch.cs:106:18:106:18 | After 1 [match] | Switch.cs:106:13:106:19 | After case ...: [match] | +| Switch.cs:106:18:106:18 | After 1 [no-match] | Switch.cs:106:13:106:19 | After case ...: [no-match] | | Switch.cs:106:21:106:29 | Before return ...; | Switch.cs:106:28:106:28 | 1 | | Switch.cs:106:28:106:28 | 1 | Switch.cs:106:21:106:29 | return ...; | | Switch.cs:108:9:108:18 | Before return ...; | Switch.cs:108:16:108:17 | Before -... | @@ -6002,10 +6055,12 @@ dominance | Switch.cs:115:17:115:24 | After access to property Length | Switch.cs:117:13:117:35 | case ...: | | Switch.cs:115:17:115:24 | Before access to property Length | Switch.cs:115:17:115:17 | access to parameter s | | Switch.cs:115:17:115:24 | access to property Length | Switch.cs:115:17:115:24 | After access to property Length | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:18:117:18 | 3 | -| Switch.cs:117:13:117:35 | case ...: | Switch.cs:117:13:117:35 | After case ...: [match] | -| Switch.cs:117:13:117:35 | case ...: | Switch.cs:117:13:117:35 | After case ...: [no-match] | -| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:25:117:34 | Before ... == ... | +| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:25:117:34 | Before ... == ... | +| Switch.cs:117:13:117:35 | case ...: | Switch.cs:117:18:117:18 | 3 | +| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:18:117:18 | After 3 [match] | +| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:18:117:18 | After 3 [no-match] | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:117:13:117:35 | After case ...: [match] | +| Switch.cs:117:18:117:18 | After 3 [no-match] | Switch.cs:117:13:117:35 | After case ...: [no-match] | | Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:30:117:34 | "foo" | | Switch.cs:117:25:117:34 | ... == ... | Switch.cs:117:25:117:34 | After ... == ... [false] | | Switch.cs:117:25:117:34 | ... == ... | Switch.cs:117:25:117:34 | After ... == ... [true] | @@ -6014,10 +6069,12 @@ dominance | Switch.cs:117:30:117:34 | "foo" | Switch.cs:117:25:117:34 | ... == ... | | Switch.cs:117:37:117:45 | Before return ...; | Switch.cs:117:44:117:44 | 1 | | Switch.cs:117:44:117:44 | 1 | Switch.cs:117:37:117:45 | return ...; | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:18:118:18 | 2 | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | After case ...: [match] | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | After case ...: [no-match] | -| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:25:118:33 | Before ... == ... | +| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:25:118:33 | Before ... == ... | +| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:18:118:18 | 2 | +| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:18:118:18 | After 2 [match] | +| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:18:118:18 | After 2 [no-match] | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:118:13:118:34 | After case ...: [match] | +| Switch.cs:118:18:118:18 | After 2 [no-match] | Switch.cs:118:13:118:34 | After case ...: [no-match] | | Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:30:118:33 | "fu" | | Switch.cs:118:25:118:33 | ... == ... | Switch.cs:118:25:118:33 | After ... == ... [false] | | Switch.cs:118:25:118:33 | ... == ... | Switch.cs:118:25:118:33 | After ... == ... [true] | @@ -6041,14 +6098,17 @@ dominance | Switch.cs:125:13:125:48 | ... switch { ... } | Switch.cs:125:13:125:13 | access to parameter o | | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | Switch.cs:125:9:126:19 | After if (...) ... | | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | Switch.cs:126:13:126:19 | Before return ...; | -| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:34:125:34 | access to local variable b | -| Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:24:125:34 | After ... => ... [match] | -| Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:24:125:34 | After ... => ... [no-match] | -| Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:125:24:125:29 | Boolean b | +| Switch.cs:125:24:125:29 | After Boolean b [match] | Switch.cs:125:24:125:34 | After ... => ... [match] | +| Switch.cs:125:24:125:29 | After Boolean b [no-match] | Switch.cs:125:24:125:34 | After ... => ... [no-match] | +| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:24:125:29 | After Boolean b [match] | +| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:24:125:29 | After Boolean b [no-match] | +| Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:24:125:29 | Boolean b | +| Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:125:34:125:34 | access to local variable b | | Switch.cs:125:24:125:34 | After ... => ... [no-match] | Switch.cs:125:37:125:46 | ... => ... | -| Switch.cs:125:37:125:37 | _ | Switch.cs:125:42:125:46 | false | -| Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:37:125:46 | After ... => ... [match] | -| Switch.cs:125:37:125:46 | After ... => ... [match] | Switch.cs:125:37:125:37 | _ | +| Switch.cs:125:37:125:37 | After _ [match] | Switch.cs:125:37:125:46 | After ... => ... [match] | +| Switch.cs:125:37:125:37 | _ | Switch.cs:125:37:125:37 | After _ [match] | +| Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:37:125:37 | _ | +| Switch.cs:125:37:125:46 | After ... => ... [match] | Switch.cs:125:42:125:46 | false | | Switch.cs:126:13:126:19 | Before return ...; | Switch.cs:126:13:126:19 | return ...; | | Switch.cs:129:12:129:14 | Entry | Switch.cs:129:23:129:23 | o | | Switch.cs:129:12:129:14 | Normal Exit | Switch.cs:129:12:129:14 | Exit | @@ -6061,14 +6121,17 @@ dominance | Switch.cs:131:17:131:17 | access to parameter o | Switch.cs:131:28:131:40 | ... => ... | | Switch.cs:131:17:131:53 | ... switch { ... } | Switch.cs:131:17:131:17 | access to parameter o | | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | Switch.cs:131:16:131:66 | call to method ToString | -| Switch.cs:131:28:131:35 | String s | Switch.cs:131:40:131:40 | access to local variable s | -| Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:28:131:40 | After ... => ... [match] | -| Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:28:131:40 | After ... => ... [no-match] | -| Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:131:28:131:35 | String s | +| Switch.cs:131:28:131:35 | After String s [match] | Switch.cs:131:28:131:40 | After ... => ... [match] | +| Switch.cs:131:28:131:35 | After String s [no-match] | Switch.cs:131:28:131:40 | After ... => ... [no-match] | +| Switch.cs:131:28:131:35 | String s | Switch.cs:131:28:131:35 | After String s [match] | +| Switch.cs:131:28:131:35 | String s | Switch.cs:131:28:131:35 | After String s [no-match] | +| Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:28:131:35 | String s | +| Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:131:40:131:40 | access to local variable s | | Switch.cs:131:28:131:40 | After ... => ... [no-match] | Switch.cs:131:43:131:51 | ... => ... | -| Switch.cs:131:43:131:43 | _ | Switch.cs:131:48:131:51 | null | -| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:51 | After ... => ... [match] | -| Switch.cs:131:43:131:51 | After ... => ... [match] | Switch.cs:131:43:131:43 | _ | +| Switch.cs:131:43:131:43 | After _ [match] | Switch.cs:131:43:131:51 | After ... => ... [match] | +| Switch.cs:131:43:131:43 | _ | Switch.cs:131:43:131:43 | After _ [match] | +| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:43 | _ | +| Switch.cs:131:43:131:51 | After ... => ... [match] | Switch.cs:131:48:131:51 | null | | Switch.cs:134:9:134:11 | Entry | Switch.cs:134:17:134:17 | i | | Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:134:9:134:11 | Exit | | Switch.cs:134:17:134:17 | i | Switch.cs:135:5:142:5 | {...} | @@ -6082,18 +6145,22 @@ dominance | Switch.cs:138:29:138:30 | After -... | Switch.cs:138:22:138:31 | return ...; | | Switch.cs:138:29:138:30 | Before -... | Switch.cs:138:30:138:30 | 1 | | Switch.cs:138:30:138:30 | 1 | Switch.cs:138:29:138:30 | -... | -| Switch.cs:139:13:139:19 | After case ...: [match] | Switch.cs:139:18:139:18 | 1 | +| Switch.cs:139:13:139:19 | After case ...: [match] | Switch.cs:139:21:139:29 | Before return ...; | | Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:140:13:140:19 | case ...: | -| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:13:139:19 | After case ...: [match] | -| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:13:139:19 | After case ...: [no-match] | -| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:21:139:29 | Before return ...; | +| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:18:139:18 | 1 | +| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:18:139:18 | After 1 [match] | +| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:18:139:18 | After 1 [no-match] | +| Switch.cs:139:18:139:18 | After 1 [match] | Switch.cs:139:13:139:19 | After case ...: [match] | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:139:13:139:19 | After case ...: [no-match] | | Switch.cs:139:21:139:29 | Before return ...; | Switch.cs:139:28:139:28 | 1 | | Switch.cs:139:28:139:28 | 1 | Switch.cs:139:21:139:29 | return ...; | -| Switch.cs:140:13:140:19 | After case ...: [match] | Switch.cs:140:18:140:18 | 2 | +| Switch.cs:140:13:140:19 | After case ...: [match] | Switch.cs:140:21:140:29 | Before return ...; | | Switch.cs:140:13:140:19 | After case ...: [no-match] | Switch.cs:138:13:138:20 | default: | -| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:13:140:19 | After case ...: [match] | -| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:13:140:19 | After case ...: [no-match] | -| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:21:140:29 | Before return ...; | +| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:18:140:18 | 2 | +| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:18:140:18 | After 2 [match] | +| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:18:140:18 | After 2 [no-match] | +| Switch.cs:140:18:140:18 | After 2 [match] | Switch.cs:140:13:140:19 | After case ...: [match] | +| Switch.cs:140:18:140:18 | After 2 [no-match] | Switch.cs:140:13:140:19 | After case ...: [no-match] | | Switch.cs:140:21:140:29 | Before return ...; | Switch.cs:140:28:140:28 | 2 | | Switch.cs:140:28:140:28 | 2 | Switch.cs:140:21:140:29 | return ...; | | Switch.cs:144:9:144:11 | Entry | Switch.cs:144:17:144:17 | i | @@ -6102,11 +6169,13 @@ dominance | Switch.cs:145:5:152:5 | {...} | Switch.cs:146:9:151:9 | switch (...) {...} | | Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:146:17:146:17 | access to parameter i | | Switch.cs:146:17:146:17 | access to parameter i | Switch.cs:148:13:148:19 | case ...: | -| Switch.cs:148:13:148:19 | After case ...: [match] | Switch.cs:148:18:148:18 | 1 | +| Switch.cs:148:13:148:19 | After case ...: [match] | Switch.cs:148:21:148:29 | Before return ...; | | Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:150:13:150:19 | case ...: | -| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:13:148:19 | After case ...: [match] | -| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:13:148:19 | After case ...: [no-match] | -| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:21:148:29 | Before return ...; | +| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:18:148:18 | 1 | +| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:18:148:18 | After 1 [match] | +| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:18:148:18 | After 1 [no-match] | +| Switch.cs:148:18:148:18 | After 1 [match] | Switch.cs:148:13:148:19 | After case ...: [match] | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:148:13:148:19 | After case ...: [no-match] | | Switch.cs:148:21:148:29 | Before return ...; | Switch.cs:148:28:148:28 | 1 | | Switch.cs:148:28:148:28 | 1 | Switch.cs:148:21:148:29 | return ...; | | Switch.cs:149:13:149:20 | After default: [match] | Switch.cs:149:22:149:31 | Before return ...; | @@ -6116,11 +6185,13 @@ dominance | Switch.cs:149:29:149:30 | After -... | Switch.cs:149:22:149:31 | return ...; | | Switch.cs:149:29:149:30 | Before -... | Switch.cs:149:30:149:30 | 1 | | Switch.cs:149:30:149:30 | 1 | Switch.cs:149:29:149:30 | -... | -| Switch.cs:150:13:150:19 | After case ...: [match] | Switch.cs:150:18:150:18 | 2 | +| Switch.cs:150:13:150:19 | After case ...: [match] | Switch.cs:150:21:150:29 | Before return ...; | | Switch.cs:150:13:150:19 | After case ...: [no-match] | Switch.cs:149:13:149:20 | default: | -| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:13:150:19 | After case ...: [match] | -| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:13:150:19 | After case ...: [no-match] | -| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:21:150:29 | Before return ...; | +| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:18:150:18 | 2 | +| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:18:150:18 | After 2 [match] | +| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:18:150:18 | After 2 [no-match] | +| Switch.cs:150:18:150:18 | After 2 [match] | Switch.cs:150:13:150:19 | After case ...: [match] | +| Switch.cs:150:18:150:18 | After 2 [no-match] | Switch.cs:150:13:150:19 | After case ...: [no-match] | | Switch.cs:150:21:150:29 | Before return ...; | Switch.cs:150:28:150:28 | 2 | | Switch.cs:150:28:150:28 | 2 | Switch.cs:150:21:150:29 | return ...; | | Switch.cs:154:10:154:12 | Entry | Switch.cs:154:19:154:19 | b | @@ -6137,15 +6208,19 @@ dominance | Switch.cs:156:17:156:17 | access to parameter b | Switch.cs:156:28:156:38 | ... => ... | | Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:156:17:156:17 | access to parameter b | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:13:156:54 | String s = ... | -| Switch.cs:156:28:156:31 | true | Switch.cs:156:36:156:38 | "a" | -| Switch.cs:156:28:156:38 | ... => ... | Switch.cs:156:28:156:38 | After ... => ... [match] | -| Switch.cs:156:28:156:38 | ... => ... | Switch.cs:156:28:156:38 | After ... => ... [no-match] | -| Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:156:28:156:31 | true | +| Switch.cs:156:28:156:31 | After true [match] | Switch.cs:156:28:156:38 | After ... => ... [match] | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:156:28:156:38 | After ... => ... [no-match] | +| Switch.cs:156:28:156:31 | true | Switch.cs:156:28:156:31 | After true [match] | +| Switch.cs:156:28:156:31 | true | Switch.cs:156:28:156:31 | After true [no-match] | +| Switch.cs:156:28:156:38 | ... => ... | Switch.cs:156:28:156:31 | true | +| Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:156:36:156:38 | "a" | | Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | ... => ... | -| Switch.cs:156:41:156:45 | false | Switch.cs:156:50:156:52 | "b" | -| Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:41:156:52 | After ... => ... [match] | -| Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:41:156:52 | After ... => ... [no-match] | -| Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:156:41:156:45 | false | +| Switch.cs:156:41:156:45 | After false [match] | Switch.cs:156:41:156:52 | After ... => ... [match] | +| Switch.cs:156:41:156:45 | After false [no-match] | Switch.cs:156:41:156:52 | After ... => ... [no-match] | +| Switch.cs:156:41:156:45 | false | Switch.cs:156:41:156:45 | After false [match] | +| Switch.cs:156:41:156:45 | false | Switch.cs:156:41:156:45 | After false [no-match] | +| Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:41:156:45 | false | +| Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:156:50:156:52 | "b" | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:155:5:161:5 | After {...} | | Switch.cs:157:9:160:49 | if (...) ... | Switch.cs:157:13:157:13 | access to parameter b | | Switch.cs:157:13:157:13 | After access to parameter b [false] | Switch.cs:160:13:160:49 | ...; | @@ -6184,14 +6259,18 @@ dominance | Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:164:5:178:5 | After {...} | | Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:165:17:165:17 | access to parameter i | | Switch.cs:165:17:165:17 | access to parameter i | Switch.cs:167:13:167:19 | case ...: | -| Switch.cs:167:13:167:19 | After case ...: [match] | Switch.cs:167:18:167:18 | 1 | | Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:168:13:168:19 | case ...: | -| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:13:167:19 | After case ...: [match] | -| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:13:167:19 | After case ...: [no-match] | -| Switch.cs:168:13:168:19 | After case ...: [match] | Switch.cs:168:18:168:18 | 2 | +| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:18:167:18 | 1 | +| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:18:167:18 | After 1 [match] | +| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:18:167:18 | After 1 [no-match] | +| Switch.cs:167:18:167:18 | After 1 [match] | Switch.cs:167:13:167:19 | After case ...: [match] | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:167:13:167:19 | After case ...: [no-match] | | Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | case ...: | -| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:13:168:19 | After case ...: [match] | -| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:13:168:19 | After case ...: [no-match] | +| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:18:168:18 | 2 | +| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:18:168:18 | After 2 [match] | +| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:18:168:18 | After 2 [no-match] | +| Switch.cs:168:18:168:18 | After 2 [match] | Switch.cs:168:13:168:19 | After case ...: [match] | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:168:13:168:19 | After case ...: [no-match] | | Switch.cs:169:17:169:50 | After call to method WriteLine | Switch.cs:169:17:169:51 | After ...; | | Switch.cs:169:17:169:50 | Before call to method WriteLine | Switch.cs:169:42:169:49 | "1 or 2" | | Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:169:17:169:50 | After call to method WriteLine | @@ -6199,11 +6278,13 @@ dominance | Switch.cs:169:17:169:51 | After ...; | Switch.cs:170:17:170:22 | Before break; | | Switch.cs:169:42:169:49 | "1 or 2" | Switch.cs:169:17:169:50 | call to method WriteLine | | Switch.cs:170:17:170:22 | Before break; | Switch.cs:170:17:170:22 | break; | -| Switch.cs:171:13:171:19 | After case ...: [match] | Switch.cs:171:18:171:18 | 3 | +| Switch.cs:171:13:171:19 | After case ...: [match] | Switch.cs:172:17:172:46 | ...; | | Switch.cs:171:13:171:19 | After case ...: [no-match] | Switch.cs:174:13:174:20 | default: | -| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:13:171:19 | After case ...: [match] | -| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:13:171:19 | After case ...: [no-match] | -| Switch.cs:171:18:171:18 | 3 | Switch.cs:172:17:172:46 | ...; | +| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:18:171:18 | 3 | +| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:18:171:18 | After 3 [match] | +| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:18:171:18 | After 3 [no-match] | +| Switch.cs:171:18:171:18 | After 3 [match] | Switch.cs:171:13:171:19 | After case ...: [match] | +| Switch.cs:171:18:171:18 | After 3 [no-match] | Switch.cs:171:13:171:19 | After case ...: [no-match] | | Switch.cs:172:17:172:45 | After call to method WriteLine | Switch.cs:172:17:172:46 | After ...; | | Switch.cs:172:17:172:45 | Before call to method WriteLine | Switch.cs:172:42:172:44 | "3" | | Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:172:17:172:45 | After call to method WriteLine | @@ -6569,11 +6650,12 @@ dominance | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:51:9:59:9 | switch (...) {...} | | cflow.cs:39:9:50:9 | switch (...) {...} | cflow.cs:39:17:39:17 | access to parameter a | | cflow.cs:39:17:39:17 | access to parameter a | cflow.cs:41:13:41:19 | case ...: | -| cflow.cs:41:13:41:19 | After case ...: [match] | cflow.cs:41:18:41:18 | 1 | +| cflow.cs:41:13:41:19 | After case ...: [match] | cflow.cs:42:17:42:39 | ...; | | cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:44:13:44:19 | case ...: | -| cflow.cs:41:13:41:19 | case ...: | cflow.cs:41:13:41:19 | After case ...: [match] | -| cflow.cs:41:13:41:19 | case ...: | cflow.cs:41:13:41:19 | After case ...: [no-match] | -| cflow.cs:41:18:41:18 | 1 | cflow.cs:42:17:42:39 | ...; | +| cflow.cs:41:13:41:19 | case ...: | cflow.cs:41:18:41:18 | 1 | +| cflow.cs:41:18:41:18 | 1 | cflow.cs:41:18:41:18 | After 1 [match] | +| cflow.cs:41:18:41:18 | 1 | cflow.cs:41:18:41:18 | After 1 [no-match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:41:13:41:19 | After case ...: [no-match] | | cflow.cs:42:17:42:38 | After call to method WriteLine | cflow.cs:42:17:42:39 | After ...; | | cflow.cs:42:17:42:38 | Before call to method WriteLine | cflow.cs:42:35:42:37 | "1" | | cflow.cs:42:17:42:38 | call to method WriteLine | cflow.cs:42:17:42:38 | After call to method WriteLine | @@ -6582,10 +6664,12 @@ dominance | cflow.cs:42:35:42:37 | "1" | cflow.cs:42:17:42:38 | call to method WriteLine | | cflow.cs:43:17:43:28 | Before goto case ...; | cflow.cs:43:27:43:27 | 2 | | cflow.cs:43:27:43:27 | 2 | cflow.cs:43:17:43:28 | goto case ...; | -| cflow.cs:44:13:44:19 | After case ...: [match] | cflow.cs:44:18:44:18 | 2 | +| cflow.cs:44:13:44:19 | After case ...: [match] | cflow.cs:45:17:45:39 | ...; | | cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | case ...: | -| cflow.cs:44:13:44:19 | case ...: | cflow.cs:44:13:44:19 | After case ...: [no-match] | -| cflow.cs:44:18:44:18 | 2 | cflow.cs:45:17:45:39 | ...; | +| cflow.cs:44:13:44:19 | case ...: | cflow.cs:44:18:44:18 | 2 | +| cflow.cs:44:18:44:18 | 2 | cflow.cs:44:18:44:18 | After 2 [match] | +| cflow.cs:44:18:44:18 | 2 | cflow.cs:44:18:44:18 | After 2 [no-match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:44:13:44:19 | After case ...: [no-match] | | cflow.cs:45:17:45:38 | After call to method WriteLine | cflow.cs:45:17:45:39 | After ...; | | cflow.cs:45:17:45:38 | Before call to method WriteLine | cflow.cs:45:35:45:37 | "2" | | cflow.cs:45:17:45:38 | call to method WriteLine | cflow.cs:45:17:45:38 | After call to method WriteLine | @@ -6594,10 +6678,12 @@ dominance | cflow.cs:45:35:45:37 | "2" | cflow.cs:45:17:45:38 | call to method WriteLine | | cflow.cs:46:17:46:28 | Before goto case ...; | cflow.cs:46:27:46:27 | 1 | | cflow.cs:46:27:46:27 | 1 | cflow.cs:46:17:46:28 | goto case ...; | -| cflow.cs:47:13:47:19 | After case ...: [match] | cflow.cs:47:18:47:18 | 3 | -| cflow.cs:47:13:47:19 | case ...: | cflow.cs:47:13:47:19 | After case ...: [match] | -| cflow.cs:47:13:47:19 | case ...: | cflow.cs:47:13:47:19 | After case ...: [no-match] | -| cflow.cs:47:18:47:18 | 3 | cflow.cs:48:17:48:39 | ...; | +| cflow.cs:47:13:47:19 | After case ...: [match] | cflow.cs:48:17:48:39 | ...; | +| cflow.cs:47:13:47:19 | case ...: | cflow.cs:47:18:47:18 | 3 | +| cflow.cs:47:18:47:18 | 3 | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:47:18:47:18 | 3 | cflow.cs:47:18:47:18 | After 3 [no-match] | +| cflow.cs:47:18:47:18 | After 3 [match] | cflow.cs:47:13:47:19 | After case ...: [match] | +| cflow.cs:47:18:47:18 | After 3 [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | | cflow.cs:48:17:48:38 | After call to method WriteLine | cflow.cs:48:17:48:39 | After ...; | | cflow.cs:48:17:48:38 | Before call to method WriteLine | cflow.cs:48:35:48:37 | "3" | | cflow.cs:48:17:48:38 | call to method WriteLine | cflow.cs:48:17:48:38 | After call to method WriteLine | @@ -6608,11 +6694,13 @@ dominance | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:60:9:66:9 | switch (...) {...} | | cflow.cs:51:9:59:9 | switch (...) {...} | cflow.cs:51:17:51:17 | access to parameter a | | cflow.cs:51:17:51:17 | access to parameter a | cflow.cs:53:13:53:20 | case ...: | -| cflow.cs:53:13:53:20 | After case ...: [match] | cflow.cs:53:18:53:19 | 42 | +| cflow.cs:53:13:53:20 | After case ...: [match] | cflow.cs:54:17:54:48 | ...; | | cflow.cs:53:13:53:20 | After case ...: [no-match] | cflow.cs:56:13:56:20 | default: | -| cflow.cs:53:13:53:20 | case ...: | cflow.cs:53:13:53:20 | After case ...: [match] | -| cflow.cs:53:13:53:20 | case ...: | cflow.cs:53:13:53:20 | After case ...: [no-match] | -| cflow.cs:53:18:53:19 | 42 | cflow.cs:54:17:54:48 | ...; | +| cflow.cs:53:13:53:20 | case ...: | cflow.cs:53:18:53:19 | 42 | +| cflow.cs:53:18:53:19 | 42 | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:53:18:53:19 | 42 | cflow.cs:53:18:53:19 | After 42 [no-match] | +| cflow.cs:53:18:53:19 | After 42 [match] | cflow.cs:53:13:53:20 | After case ...: [match] | +| cflow.cs:53:18:53:19 | After 42 [no-match] | cflow.cs:53:13:53:20 | After case ...: [no-match] | | cflow.cs:54:17:54:47 | After call to method WriteLine | cflow.cs:54:17:54:48 | After ...; | | cflow.cs:54:17:54:47 | Before call to method WriteLine | cflow.cs:54:35:54:46 | "The answer" | | cflow.cs:54:17:54:47 | call to method WriteLine | cflow.cs:54:17:54:47 | After call to method WriteLine | @@ -6638,10 +6726,12 @@ dominance | cflow.cs:60:27:60:31 | Before access to field Field | cflow.cs:60:27:60:31 | this access | | cflow.cs:60:27:60:31 | access to field Field | cflow.cs:60:27:60:31 | After access to field Field | | cflow.cs:60:27:60:31 | this access | cflow.cs:60:27:60:31 | access to field Field | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:62:18:62:18 | 0 | -| cflow.cs:62:13:62:19 | case ...: | cflow.cs:62:13:62:19 | After case ...: [match] | -| cflow.cs:62:13:62:19 | case ...: | cflow.cs:62:13:62:19 | After case ...: [no-match] | -| cflow.cs:62:18:62:18 | 0 | cflow.cs:63:17:64:55 | if (...) ... | +| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:63:17:64:55 | if (...) ... | +| cflow.cs:62:13:62:19 | case ...: | cflow.cs:62:18:62:18 | 0 | +| cflow.cs:62:18:62:18 | 0 | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:62:18:62:18 | 0 | cflow.cs:62:18:62:18 | After 0 [no-match] | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:62:13:62:19 | After case ...: [match] | +| cflow.cs:62:18:62:18 | After 0 [no-match] | cflow.cs:62:13:62:19 | After case ...: [no-match] | | cflow.cs:63:17:64:55 | After if (...) ... | cflow.cs:65:17:65:22 | Before break; | | cflow.cs:63:17:64:55 | if (...) ... | cflow.cs:63:21:63:34 | !... | | cflow.cs:63:21:63:34 | !... | cflow.cs:63:23:63:33 | Before ... == ... | @@ -7528,17 +7618,21 @@ dominance | cflow.cs:246:17:246:32 | After ... + ... | cflow.cs:248:13:248:19 | case ...: | | cflow.cs:246:17:246:32 | Before ... + ... | cflow.cs:246:17:246:28 | Before access to property Length | | cflow.cs:246:32:246:32 | 3 | cflow.cs:246:17:246:32 | ... + ... | -| cflow.cs:248:13:248:19 | After case ...: [match] | cflow.cs:248:18:248:18 | 0 | +| cflow.cs:248:13:248:19 | After case ...: [match] | cflow.cs:249:17:249:29 | Before goto default; | | cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:250:13:250:19 | case ...: | -| cflow.cs:248:13:248:19 | case ...: | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:248:13:248:19 | case ...: | cflow.cs:248:13:248:19 | After case ...: [no-match] | -| cflow.cs:248:18:248:18 | 0 | cflow.cs:249:17:249:29 | Before goto default; | +| cflow.cs:248:13:248:19 | case ...: | cflow.cs:248:18:248:18 | 0 | +| cflow.cs:248:18:248:18 | 0 | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:248:18:248:18 | 0 | cflow.cs:248:18:248:18 | After 0 [no-match] | +| cflow.cs:248:18:248:18 | After 0 [match] | cflow.cs:248:13:248:19 | After case ...: [match] | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:248:13:248:19 | After case ...: [no-match] | | cflow.cs:249:17:249:29 | Before goto default; | cflow.cs:249:17:249:29 | goto default; | -| cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:250:18:250:18 | 1 | +| cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:251:17:251:37 | ...; | | cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | case ...: | -| cflow.cs:250:13:250:19 | case ...: | cflow.cs:250:13:250:19 | After case ...: [match] | -| cflow.cs:250:13:250:19 | case ...: | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:250:18:250:18 | 1 | cflow.cs:251:17:251:37 | ...; | +| cflow.cs:250:13:250:19 | case ...: | cflow.cs:250:18:250:18 | 1 | +| cflow.cs:250:18:250:18 | 1 | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:250:18:250:18 | 1 | cflow.cs:250:18:250:18 | After 1 [no-match] | +| cflow.cs:250:18:250:18 | After 1 [match] | cflow.cs:250:13:250:19 | After case ...: [match] | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:250:13:250:19 | After case ...: [no-match] | | cflow.cs:251:17:251:36 | After call to method WriteLine | cflow.cs:251:17:251:37 | After ...; | | cflow.cs:251:17:251:36 | Before call to method WriteLine | cflow.cs:251:35:251:35 | 1 | | cflow.cs:251:17:251:36 | call to method WriteLine | cflow.cs:251:17:251:36 | After call to method WriteLine | @@ -7546,11 +7640,13 @@ dominance | cflow.cs:251:17:251:37 | After ...; | cflow.cs:252:17:252:22 | Before break; | | cflow.cs:251:35:251:35 | 1 | cflow.cs:251:17:251:36 | call to method WriteLine | | cflow.cs:252:17:252:22 | Before break; | cflow.cs:252:17:252:22 | break; | -| cflow.cs:253:13:253:19 | After case ...: [match] | cflow.cs:253:18:253:18 | 2 | +| cflow.cs:253:13:253:19 | After case ...: [match] | cflow.cs:254:17:254:27 | Before goto ...; | | cflow.cs:253:13:253:19 | After case ...: [no-match] | cflow.cs:255:13:255:20 | default: | -| cflow.cs:253:13:253:19 | case ...: | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:253:13:253:19 | case ...: | cflow.cs:253:13:253:19 | After case ...: [no-match] | -| cflow.cs:253:18:253:18 | 2 | cflow.cs:254:17:254:27 | Before goto ...; | +| cflow.cs:253:13:253:19 | case ...: | cflow.cs:253:18:253:18 | 2 | +| cflow.cs:253:18:253:18 | 2 | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:253:18:253:18 | 2 | cflow.cs:253:18:253:18 | After 2 [no-match] | +| cflow.cs:253:18:253:18 | After 2 [match] | cflow.cs:253:13:253:19 | After case ...: [match] | +| cflow.cs:253:18:253:18 | After 2 [no-match] | cflow.cs:253:13:253:19 | After case ...: [no-match] | | cflow.cs:254:17:254:27 | Before goto ...; | cflow.cs:254:17:254:27 | goto ...; | | cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:256:17:256:37 | ...; | | cflow.cs:256:17:256:36 | After call to method WriteLine | cflow.cs:256:17:256:37 | After ...; | @@ -12871,15 +12967,19 @@ postDominance | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:37:17:37:22 | break; | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:8:9:18:9 | After if (...) ... | | Patterns.cs:20:17:20:17 | access to local variable o | Patterns.cs:20:9:38:9 | switch (...) {...} | +| Patterns.cs:22:13:22:23 | After case ...: [match] | Patterns.cs:22:18:22:22 | After "xyz" [match] | +| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:22:18:22:22 | After "xyz" [no-match] | | Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:20:17:20:17 | access to local variable o | -| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:22:13:22:23 | After case ...: [match] | -| Patterns.cs:23:17:23:22 | Before break; | Patterns.cs:22:18:22:22 | "xyz" | +| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:22:13:22:23 | case ...: | +| Patterns.cs:23:17:23:22 | Before break; | Patterns.cs:22:13:22:23 | After case ...: [match] | | Patterns.cs:23:17:23:22 | break; | Patterns.cs:23:17:23:22 | Before break; | +| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | +| Patterns.cs:24:13:24:36 | After case ...: [no-match] | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | | Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:22:13:22:23 | After case ...: [no-match] | -| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:24:13:24:36 | After case ...: [match] | +| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:24:13:24:36 | case ...: | | Patterns.cs:24:30:24:31 | access to local variable i2 | Patterns.cs:24:30:24:35 | Before ... > ... | | Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:24:35:24:35 | 0 | -| Patterns.cs:24:30:24:35 | Before ... > ... | Patterns.cs:24:18:24:23 | Int32 i2 | +| Patterns.cs:24:30:24:35 | Before ... > ... | Patterns.cs:24:13:24:36 | After case ...: [match] | | Patterns.cs:24:35:24:35 | 0 | Patterns.cs:24:30:24:31 | access to local variable i2 | | Patterns.cs:25:17:25:51 | After call to method WriteLine | Patterns.cs:25:17:25:51 | call to method WriteLine | | Patterns.cs:25:17:25:51 | Before call to method WriteLine | Patterns.cs:25:17:25:52 | ...; | @@ -12896,13 +12996,15 @@ postDominance | Patterns.cs:25:47:25:48 | access to local variable i2 | Patterns.cs:25:46:25:49 | Before {...} | | Patterns.cs:26:17:26:22 | Before break; | Patterns.cs:25:17:25:52 | After ...; | | Patterns.cs:26:17:26:22 | break; | Patterns.cs:26:17:26:22 | Before break; | +| Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | +| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | | Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:24:13:24:36 | After case ...: [no-match] | | Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:24:30:24:35 | After ... > ... [false] | -| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:27:13:27:24 | After case ...: [match] | +| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:27:13:27:24 | case ...: | | Patterns.cs:28:17:28:46 | After call to method WriteLine | Patterns.cs:28:17:28:46 | call to method WriteLine | | Patterns.cs:28:17:28:46 | Before call to method WriteLine | Patterns.cs:28:17:28:47 | ...; | | Patterns.cs:28:17:28:46 | call to method WriteLine | Patterns.cs:28:35:28:45 | After $"..." | -| Patterns.cs:28:17:28:47 | ...; | Patterns.cs:27:18:27:23 | Int32 i3 | +| Patterns.cs:28:17:28:47 | ...; | Patterns.cs:27:13:27:24 | After case ...: [match] | | Patterns.cs:28:17:28:47 | After ...; | Patterns.cs:28:17:28:46 | After call to method WriteLine | | Patterns.cs:28:35:28:45 | $"..." | Patterns.cs:28:41:28:44 | After {...} | | Patterns.cs:28:35:28:45 | After $"..." | Patterns.cs:28:35:28:45 | $"..." | @@ -12914,12 +13016,14 @@ postDominance | Patterns.cs:28:42:28:43 | access to local variable i3 | Patterns.cs:28:41:28:44 | Before {...} | | Patterns.cs:29:17:29:22 | Before break; | Patterns.cs:28:17:28:47 | After ...; | | Patterns.cs:29:17:29:22 | break; | Patterns.cs:29:17:29:22 | Before break; | +| Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:30:18:30:26 | After String s2 [no-match] | | Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:27:13:27:24 | After case ...: [no-match] | -| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:30:13:30:27 | After case ...: [match] | +| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:30:13:30:27 | case ...: | | Patterns.cs:31:17:31:49 | After call to method WriteLine | Patterns.cs:31:17:31:49 | call to method WriteLine | | Patterns.cs:31:17:31:49 | Before call to method WriteLine | Patterns.cs:31:17:31:50 | ...; | | Patterns.cs:31:17:31:49 | call to method WriteLine | Patterns.cs:31:35:31:48 | After $"..." | -| Patterns.cs:31:17:31:50 | ...; | Patterns.cs:30:18:30:26 | String s2 | +| Patterns.cs:31:17:31:50 | ...; | Patterns.cs:30:13:30:27 | After case ...: [match] | | Patterns.cs:31:17:31:50 | After ...; | Patterns.cs:31:17:31:49 | After call to method WriteLine | | Patterns.cs:31:35:31:48 | $"..." | Patterns.cs:31:44:31:47 | After {...} | | Patterns.cs:31:35:31:48 | After $"..." | Patterns.cs:31:35:31:48 | $"..." | @@ -12931,9 +13035,11 @@ postDominance | Patterns.cs:31:45:31:46 | access to local variable s2 | Patterns.cs:31:44:31:47 | Before {...} | | Patterns.cs:32:17:32:22 | Before break; | Patterns.cs:31:17:31:50 | After ...; | | Patterns.cs:32:17:32:22 | break; | Patterns.cs:32:17:32:22 | Before break; | +| Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:33:13:33:24 | After case ...: [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | | Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:34:17:34:22 | Before break; | Patterns.cs:33:18:33:23 | Object v2 | +| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:33:13:33:24 | case ...: | +| Patterns.cs:34:17:34:22 | Before break; | Patterns.cs:33:13:33:24 | After case ...: [match] | | Patterns.cs:34:17:34:22 | break; | Patterns.cs:34:17:34:22 | Before break; | | Patterns.cs:35:13:35:20 | After default: [match] | Patterns.cs:35:13:35:20 | default: | | Patterns.cs:35:13:35:20 | default: | Patterns.cs:33:13:33:24 | After case ...: [no-match] | @@ -13016,16 +13122,18 @@ postDominance | Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:58:9:62:10 | Before return ...; | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:60:22:60:28 | "not 1" | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:61:18:61:24 | "other" | -| Patterns.cs:60:13:60:17 | After not ... | Patterns.cs:60:13:60:17 | not ... | -| Patterns.cs:60:13:60:17 | Before not ... | Patterns.cs:60:13:60:28 | After ... => ... [match] | +| Patterns.cs:60:13:60:17 | Before not ... | Patterns.cs:60:13:60:28 | ... => ... | | Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:17:60:17 | 1 | | Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:58:16:58:16 | access to parameter i | +| Patterns.cs:60:13:60:28 | After ... => ... [match] | Patterns.cs:60:13:60:17 | After not ... [match] | +| Patterns.cs:60:13:60:28 | After ... => ... [no-match] | Patterns.cs:60:13:60:17 | After not ... [no-match] | | Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:13:60:17 | Before not ... | -| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:13:60:17 | After not ... | -| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:13:61:24 | After ... => ... [match] | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:13:60:28 | After ... => ... [match] | +| Patterns.cs:61:13:61:13 | After _ [match] | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:13:61:24 | ... => ... | | Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | -| Patterns.cs:61:13:61:24 | After ... => ... [match] | Patterns.cs:61:13:61:24 | ... => ... | -| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:61:13:61:24 | After ... => ... [match] | Patterns.cs:61:13:61:13 | After _ [match] | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:13:61:24 | After ... => ... [match] | | Patterns.cs:65:26:65:27 | Exit | Patterns.cs:65:26:65:27 | Normal Exit | | Patterns.cs:65:26:65:27 | Normal Exit | Patterns.cs:67:9:71:10 | return ...; | | Patterns.cs:66:5:72:5 | {...} | Patterns.cs:65:26:65:27 | Entry | @@ -13036,15 +13144,18 @@ postDominance | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:69:22:69:33 | "impossible" | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:70:18:70:27 | "possible" | -| Patterns.cs:69:13:69:17 | After not ... | Patterns.cs:69:13:69:17 | not ... | -| Patterns.cs:69:13:69:17 | Before not ... | Patterns.cs:69:13:69:33 | After ... => ... [match] | +| Patterns.cs:69:13:69:17 | Before not ... | Patterns.cs:69:13:69:33 | ... => ... | | Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:17:69:17 | 2 | | Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:67:16:67:16 | 2 | +| Patterns.cs:69:13:69:33 | After ... => ... [match] | Patterns.cs:69:13:69:17 | After not ... [match] | +| Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:69:13:69:17 | After not ... [no-match] | | Patterns.cs:69:17:69:17 | 2 | Patterns.cs:69:13:69:17 | Before not ... | -| Patterns.cs:69:22:69:33 | "impossible" | Patterns.cs:69:13:69:17 | After not ... | -| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:27 | After ... => ... [match] | +| Patterns.cs:69:22:69:33 | "impossible" | Patterns.cs:69:13:69:33 | After ... => ... [match] | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:27 | ... => ... | | Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | -| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:70:13:70:13 | After 2 [match] | +| Patterns.cs:70:13:70:27 | After ... => ... [no-match] | Patterns.cs:70:13:70:13 | After 2 [no-match] | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:13:70:27 | After ... => ... [match] | | Patterns.cs:74:26:74:27 | Exit | Patterns.cs:74:26:74:27 | Normal Exit | | Patterns.cs:74:26:74:27 | Normal Exit | Patterns.cs:76:9:82:10 | return ...; | | Patterns.cs:74:33:74:33 | i | Patterns.cs:74:26:74:27 | Entry | @@ -13058,24 +13169,29 @@ postDominance | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:80:18:80:20 | "1" | | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:81:18:81:20 | "0" | | Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:15:78:15 | 1 | -| Patterns.cs:78:13:78:15 | After > ... | Patterns.cs:78:13:78:15 | > ... | -| Patterns.cs:78:13:78:15 | Before > ... | Patterns.cs:78:13:78:24 | After ... => ... [match] | +| Patterns.cs:78:13:78:15 | Before > ... | Patterns.cs:78:13:78:24 | ... => ... | | Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:76:16:76:16 | access to parameter i | +| Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:78:13:78:15 | After > ... [match] | +| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:78:13:78:15 | After > ... [no-match] | | Patterns.cs:78:15:78:15 | 1 | Patterns.cs:78:13:78:15 | Before > ... | -| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:78:13:78:15 | After > ... | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:78:13:78:24 | After ... => ... [match] | | Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:15:79:15 | 0 | -| Patterns.cs:79:13:79:15 | After < ... | Patterns.cs:79:13:79:15 | < ... | -| Patterns.cs:79:13:79:15 | Before < ... | Patterns.cs:79:13:79:24 | After ... => ... [match] | +| Patterns.cs:79:13:79:15 | Before < ... | Patterns.cs:79:13:79:24 | ... => ... | | Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | +| Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:79:13:79:15 | After < ... [match] | +| Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:15 | After < ... [no-match] | | Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:13:79:15 | Before < ... | -| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:79:13:79:15 | After < ... | -| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:20 | After ... => ... [match] | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:79:13:79:24 | After ... => ... [match] | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:20 | ... => ... | | Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | -| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:13:80:13 | 1 | -| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:20 | After ... => ... [match] | +| Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:80:13:80:13 | After 1 [match] | +| Patterns.cs:80:13:80:20 | After ... => ... [no-match] | Patterns.cs:80:13:80:13 | After 1 [no-match] | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:13:80:20 | After ... => ... [match] | +| Patterns.cs:81:13:81:13 | After _ [match] | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:20 | ... => ... | | Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | -| Patterns.cs:81:13:81:20 | After ... => ... [match] | Patterns.cs:81:13:81:20 | ... => ... | -| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:81:13:81:20 | After ... => ... [match] | Patterns.cs:81:13:81:13 | After _ [match] | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:20 | After ... => ... [match] | | Patterns.cs:85:26:85:27 | Exit | Patterns.cs:85:26:85:27 | Normal Exit | | Patterns.cs:85:26:85:27 | Normal Exit | Patterns.cs:85:39:85:69 | After ... ? ... : ... | | Patterns.cs:85:33:85:33 | i | Patterns.cs:85:26:85:27 | Entry | @@ -13403,26 +13519,33 @@ postDominance | Switch.cs:11:5:33:5 | {...} | Switch.cs:10:20:10:20 | o | | Switch.cs:12:9:32:9 | switch (...) {...} | Switch.cs:11:5:33:5 | {...} | | Switch.cs:12:17:12:17 | access to parameter o | Switch.cs:12:9:32:9 | switch (...) {...} | +| Switch.cs:14:13:14:21 | After case ...: [match] | Switch.cs:14:18:14:20 | After "a" [match] | +| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:14:18:14:20 | After "a" [no-match] | | Switch.cs:14:13:14:21 | case ...: | Switch.cs:12:17:12:17 | access to parameter o | -| Switch.cs:14:18:14:20 | "a" | Switch.cs:14:13:14:21 | After case ...: [match] | -| Switch.cs:15:17:15:23 | Before return ...; | Switch.cs:14:18:14:20 | "a" | +| Switch.cs:14:18:14:20 | "a" | Switch.cs:14:13:14:21 | case ...: | +| Switch.cs:15:17:15:23 | Before return ...; | Switch.cs:14:13:14:21 | After case ...: [match] | | Switch.cs:15:17:15:23 | return ...; | Switch.cs:15:17:15:23 | Before return ...; | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:16:13:16:19 | case ...: | +| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:16:18:16:18 | After 0 [no-match] | | Switch.cs:16:13:16:19 | case ...: | Switch.cs:14:13:14:21 | After case ...: [no-match] | -| Switch.cs:16:18:16:18 | 0 | Switch.cs:16:13:16:19 | After case ...: [match] | -| Switch.cs:17:17:17:38 | Before throw ...; | Switch.cs:16:18:16:18 | 0 | +| Switch.cs:16:18:16:18 | 0 | Switch.cs:16:13:16:19 | case ...: | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:16:18:16:18 | 0 | +| Switch.cs:17:17:17:38 | Before throw ...; | Switch.cs:16:13:16:19 | After case ...: [match] | | Switch.cs:17:17:17:38 | throw ...; | Switch.cs:17:23:17:37 | After object creation of type Exception | | Switch.cs:17:23:17:37 | After object creation of type Exception | Switch.cs:17:23:17:37 | object creation of type Exception | | Switch.cs:17:23:17:37 | Before object creation of type Exception | Switch.cs:17:17:17:38 | Before throw ...; | | Switch.cs:17:23:17:37 | object creation of type Exception | Switch.cs:17:23:17:37 | Before object creation of type Exception | +| Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:18:18:18:21 | After null [match] | +| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:18:18:18:21 | After null [no-match] | | Switch.cs:18:13:18:22 | case ...: | Switch.cs:16:13:16:19 | After case ...: [no-match] | -| Switch.cs:18:18:18:21 | null | Switch.cs:18:13:18:22 | After case ...: [match] | -| Switch.cs:19:17:19:29 | Before goto default; | Switch.cs:18:18:18:21 | null | +| Switch.cs:18:18:18:21 | null | Switch.cs:18:13:18:22 | case ...: | +| Switch.cs:19:17:19:29 | Before goto default; | Switch.cs:18:13:18:22 | After case ...: [match] | | Switch.cs:19:17:19:29 | goto default; | Switch.cs:19:17:19:29 | Before goto default; | +| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:20:18:20:22 | After Int32 i [match] | +| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:20:18:20:22 | After Int32 i [no-match] | | Switch.cs:20:13:20:23 | case ...: | Switch.cs:18:13:18:22 | After case ...: [no-match] | -| Switch.cs:20:18:20:22 | Int32 i | Switch.cs:20:13:20:23 | After case ...: [match] | +| Switch.cs:20:18:20:22 | Int32 i | Switch.cs:20:13:20:23 | case ...: | | Switch.cs:21:17:22:27 | After if (...) ... | Switch.cs:21:21:21:29 | After ... == ... [false] | -| Switch.cs:21:17:22:27 | if (...) ... | Switch.cs:20:18:20:22 | Int32 i | +| Switch.cs:21:17:22:27 | if (...) ... | Switch.cs:20:13:20:23 | After case ...: [match] | | Switch.cs:21:21:21:21 | access to parameter o | Switch.cs:21:21:21:29 | Before ... == ... | | Switch.cs:21:21:21:29 | ... == ... | Switch.cs:21:26:21:29 | null | | Switch.cs:21:21:21:29 | After ... == ... [true] | Switch.cs:21:21:21:29 | ... == ... | @@ -13433,15 +13556,17 @@ postDominance | Switch.cs:23:17:23:28 | Before goto case ...; | Switch.cs:21:17:22:27 | After if (...) ... | | Switch.cs:23:17:23:28 | goto case ...; | Switch.cs:23:27:23:27 | 0 | | Switch.cs:23:27:23:27 | 0 | Switch.cs:23:17:23:28 | Before goto case ...; | +| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:24:13:24:56 | After case ...: [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | | Switch.cs:24:13:24:56 | case ...: | Switch.cs:20:13:20:23 | After case ...: [no-match] | -| Switch.cs:24:18:24:25 | String s | Switch.cs:24:13:24:56 | After case ...: [match] | +| Switch.cs:24:18:24:25 | String s | Switch.cs:24:13:24:56 | case ...: | | Switch.cs:24:32:24:32 | access to local variable s | Switch.cs:24:32:24:39 | Before access to property Length | | Switch.cs:24:32:24:39 | After access to property Length | Switch.cs:24:32:24:39 | access to property Length | | Switch.cs:24:32:24:39 | Before access to property Length | Switch.cs:24:32:24:43 | Before ... > ... | | Switch.cs:24:32:24:39 | access to property Length | Switch.cs:24:32:24:32 | access to local variable s | | Switch.cs:24:32:24:43 | ... > ... | Switch.cs:24:43:24:43 | 0 | | Switch.cs:24:32:24:43 | Before ... > ... | Switch.cs:24:32:24:55 | ... && ... | -| Switch.cs:24:32:24:55 | ... && ... | Switch.cs:24:18:24:25 | String s | +| Switch.cs:24:32:24:55 | ... && ... | Switch.cs:24:13:24:56 | After case ...: [match] | | Switch.cs:24:32:24:55 | After ... && ... [false] | Switch.cs:24:32:24:43 | After ... > ... [false] | | Switch.cs:24:32:24:55 | After ... && ... [false] | Switch.cs:24:48:24:55 | After ... != ... [false] | | Switch.cs:24:32:24:55 | After ... && ... [true] | Switch.cs:24:48:24:55 | After ... != ... [true] | @@ -13458,11 +13583,13 @@ postDominance | Switch.cs:25:35:25:35 | access to local variable s | Switch.cs:25:17:25:36 | Before call to method WriteLine | | Switch.cs:26:17:26:23 | Before return ...; | Switch.cs:25:17:25:37 | After ...; | | Switch.cs:26:17:26:23 | return ...; | Switch.cs:26:17:26:23 | Before return ...; | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | | Switch.cs:27:13:27:39 | case ...: | Switch.cs:24:13:24:56 | After case ...: [no-match] | | Switch.cs:27:13:27:39 | case ...: | Switch.cs:24:32:24:55 | After ... && ... [false] | -| Switch.cs:27:18:27:25 | Double d | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:27:32:27:38 | Before call to method Throw | Switch.cs:27:18:27:25 | Double d | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:27:18:27:25 | Double d | +| Switch.cs:27:18:27:25 | Double d | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:27:32:27:38 | Before call to method Throw | Switch.cs:27:13:27:39 | After case ...: [match] | | Switch.cs:27:32:27:38 | call to method Throw | Switch.cs:27:32:27:38 | Before call to method Throw | | Switch.cs:28:13:28:17 | Label: | Switch.cs:31:17:31:27 | goto ...; | | Switch.cs:29:17:29:23 | Before return ...; | Switch.cs:28:13:28:17 | Label: | @@ -13489,15 +13616,19 @@ postDominance | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:51:17:51:22 | break; | | Switch.cs:46:9:52:9 | switch (...) {...} | Switch.cs:45:5:53:5 | {...} | | Switch.cs:46:17:46:17 | access to parameter o | Switch.cs:46:9:52:9 | switch (...) {...} | +| Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:48:18:48:20 | After access to type Int32 [match] | +| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | | Switch.cs:48:13:48:23 | case ...: | Switch.cs:46:17:46:17 | access to parameter o | -| Switch.cs:48:18:48:20 | access to type Int32 | Switch.cs:48:13:48:23 | After case ...: [match] | -| Switch.cs:49:17:49:22 | Before break; | Switch.cs:48:18:48:20 | access to type Int32 | +| Switch.cs:48:18:48:20 | access to type Int32 | Switch.cs:48:13:48:23 | case ...: | +| Switch.cs:49:17:49:22 | Before break; | Switch.cs:48:13:48:23 | After case ...: [match] | | Switch.cs:49:17:49:22 | break; | Switch.cs:49:17:49:22 | Before break; | +| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:18:50:21 | After access to type Boolean [match] | +| Switch.cs:50:13:50:39 | After case ...: [no-match] | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | | Switch.cs:50:13:50:39 | case ...: | Switch.cs:48:13:48:23 | After case ...: [no-match] | -| Switch.cs:50:18:50:21 | access to type Boolean | Switch.cs:50:13:50:39 | After case ...: [match] | +| Switch.cs:50:18:50:21 | access to type Boolean | Switch.cs:50:13:50:39 | case ...: | | Switch.cs:50:30:50:30 | access to parameter o | Switch.cs:50:30:50:38 | Before ... != ... | | Switch.cs:50:30:50:38 | ... != ... | Switch.cs:50:35:50:38 | null | -| Switch.cs:50:30:50:38 | Before ... != ... | Switch.cs:50:18:50:21 | access to type Boolean | +| Switch.cs:50:30:50:38 | Before ... != ... | Switch.cs:50:13:50:39 | After case ...: [match] | | Switch.cs:50:35:50:38 | null | Switch.cs:50:30:50:30 | access to parameter o | | Switch.cs:51:17:51:22 | Before break; | Switch.cs:50:30:50:38 | After ... != ... [true] | | Switch.cs:51:17:51:22 | break; | Switch.cs:51:17:51:22 | Before break; | @@ -13514,13 +13645,17 @@ postDominance | Switch.cs:57:17:57:21 | After ... + ... | Switch.cs:57:17:57:21 | ... + ... | | Switch.cs:57:17:57:21 | Before ... + ... | Switch.cs:57:9:63:9 | switch (...) {...} | | Switch.cs:57:21:57:21 | 2 | Switch.cs:57:17:57:17 | 1 | +| Switch.cs:59:13:59:19 | After case ...: [match] | Switch.cs:59:18:59:18 | After 2 [match] | +| Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:59:18:59:18 | After 2 [no-match] | | Switch.cs:59:13:59:19 | case ...: | Switch.cs:57:17:57:21 | After ... + ... | -| Switch.cs:59:18:59:18 | 2 | Switch.cs:59:13:59:19 | After case ...: [match] | -| Switch.cs:60:17:60:22 | Before break; | Switch.cs:59:18:59:18 | 2 | +| Switch.cs:59:18:59:18 | 2 | Switch.cs:59:13:59:19 | case ...: | +| Switch.cs:60:17:60:22 | Before break; | Switch.cs:59:13:59:19 | After case ...: [match] | | Switch.cs:60:17:60:22 | break; | Switch.cs:60:17:60:22 | Before break; | +| Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:61:18:61:18 | After 3 [match] | +| Switch.cs:61:13:61:19 | After case ...: [no-match] | Switch.cs:61:18:61:18 | After 3 [no-match] | | Switch.cs:61:13:61:19 | case ...: | Switch.cs:59:13:59:19 | After case ...: [no-match] | -| Switch.cs:61:18:61:18 | 3 | Switch.cs:61:13:61:19 | After case ...: [match] | -| Switch.cs:62:17:62:22 | Before break; | Switch.cs:61:18:61:18 | 3 | +| Switch.cs:61:18:61:18 | 3 | Switch.cs:61:13:61:19 | case ...: | +| Switch.cs:62:17:62:22 | Before break; | Switch.cs:61:13:61:19 | After case ...: [match] | | Switch.cs:62:17:62:22 | break; | Switch.cs:62:17:62:22 | Before break; | | Switch.cs:66:10:66:11 | Exit | Switch.cs:66:10:66:11 | Normal Exit | | Switch.cs:66:10:66:11 | Normal Exit | Switch.cs:67:5:75:5 | After {...} | @@ -13535,13 +13670,17 @@ postDominance | Switch.cs:68:17:68:25 | After (...) ... | Switch.cs:68:17:68:25 | (...) ... | | Switch.cs:68:17:68:25 | Before (...) ... | Switch.cs:68:9:74:9 | switch (...) {...} | | Switch.cs:68:25:68:25 | access to parameter s | Switch.cs:68:17:68:25 | Before (...) ... | +| Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:70:18:70:20 | After access to type Int32 [match] | +| Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | | Switch.cs:70:13:70:23 | case ...: | Switch.cs:68:17:68:25 | After (...) ... | -| Switch.cs:70:18:70:20 | access to type Int32 | Switch.cs:70:13:70:23 | After case ...: [match] | -| Switch.cs:71:17:71:22 | Before break; | Switch.cs:70:18:70:20 | access to type Int32 | +| Switch.cs:70:18:70:20 | access to type Int32 | Switch.cs:70:13:70:23 | case ...: | +| Switch.cs:71:17:71:22 | Before break; | Switch.cs:70:13:70:23 | After case ...: [match] | | Switch.cs:71:17:71:22 | break; | Switch.cs:71:17:71:22 | Before break; | +| Switch.cs:72:13:72:20 | After case ...: [match] | Switch.cs:72:18:72:19 | After "" [match] | +| Switch.cs:72:13:72:20 | After case ...: [no-match] | Switch.cs:72:18:72:19 | After "" [no-match] | | Switch.cs:72:13:72:20 | case ...: | Switch.cs:70:13:70:23 | After case ...: [no-match] | -| Switch.cs:72:18:72:19 | "" | Switch.cs:72:13:72:20 | After case ...: [match] | -| Switch.cs:73:17:73:22 | Before break; | Switch.cs:72:18:72:19 | "" | +| Switch.cs:72:18:72:19 | "" | Switch.cs:72:13:72:20 | case ...: | +| Switch.cs:73:17:73:22 | Before break; | Switch.cs:72:13:72:20 | After case ...: [match] | | Switch.cs:73:17:73:22 | break; | Switch.cs:73:17:73:22 | Before break; | | Switch.cs:77:10:77:11 | Exit | Switch.cs:77:10:77:11 | Normal Exit | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:82:17:82:28 | return ...; | @@ -13554,15 +13693,19 @@ postDominance | Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:85:21:85:26 | break; | | Switch.cs:79:9:87:9 | switch (...) {...} | Switch.cs:78:5:89:5 | {...} | | Switch.cs:79:17:79:17 | access to parameter i | Switch.cs:79:9:87:9 | switch (...) {...} | +| Switch.cs:81:13:81:19 | After case ...: [match] | Switch.cs:81:18:81:18 | After 1 [match] | +| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:81:18:81:18 | After 1 [no-match] | | Switch.cs:81:13:81:19 | case ...: | Switch.cs:79:17:79:17 | access to parameter i | -| Switch.cs:81:18:81:18 | 1 | Switch.cs:81:13:81:19 | After case ...: [match] | -| Switch.cs:82:17:82:28 | Before return ...; | Switch.cs:81:18:81:18 | 1 | +| Switch.cs:81:18:81:18 | 1 | Switch.cs:81:13:81:19 | case ...: | +| Switch.cs:82:17:82:28 | Before return ...; | Switch.cs:81:13:81:19 | After case ...: [match] | | Switch.cs:82:17:82:28 | return ...; | Switch.cs:82:24:82:27 | true | | Switch.cs:82:24:82:27 | true | Switch.cs:82:17:82:28 | Before return ...; | +| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:83:18:83:18 | After 2 [match] | +| Switch.cs:83:13:83:19 | After case ...: [no-match] | Switch.cs:83:18:83:18 | After 2 [no-match] | | Switch.cs:83:13:83:19 | case ...: | Switch.cs:81:13:81:19 | After case ...: [no-match] | -| Switch.cs:83:18:83:18 | 2 | Switch.cs:83:13:83:19 | After case ...: [match] | +| Switch.cs:83:18:83:18 | 2 | Switch.cs:83:13:83:19 | case ...: | | Switch.cs:84:17:85:26 | After if (...) ... | Switch.cs:84:21:84:25 | After ... > ... [false] | -| Switch.cs:84:17:85:26 | if (...) ... | Switch.cs:83:18:83:18 | 2 | +| Switch.cs:84:17:85:26 | if (...) ... | Switch.cs:83:13:83:19 | After case ...: [match] | | Switch.cs:84:21:84:21 | access to parameter j | Switch.cs:84:21:84:25 | Before ... > ... | | Switch.cs:84:21:84:25 | ... > ... | Switch.cs:84:25:84:25 | 2 | | Switch.cs:84:21:84:25 | Before ... > ... | Switch.cs:84:17:85:26 | if (...) ... | @@ -13583,9 +13726,11 @@ postDominance | Switch.cs:93:9:97:9 | After switch (...) {...} | Switch.cs:95:13:95:23 | After case ...: [no-match] | | Switch.cs:93:9:97:9 | switch (...) {...} | Switch.cs:92:5:99:5 | {...} | | Switch.cs:93:17:93:17 | access to parameter o | Switch.cs:93:9:97:9 | switch (...) {...} | +| Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:95:18:95:20 | After access to type Int32 [match] | +| Switch.cs:95:13:95:23 | After case ...: [no-match] | Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | | Switch.cs:95:13:95:23 | case ...: | Switch.cs:93:17:93:17 | access to parameter o | -| Switch.cs:95:18:95:20 | access to type Int32 | Switch.cs:95:13:95:23 | After case ...: [match] | -| Switch.cs:96:17:96:28 | Before return ...; | Switch.cs:95:18:95:20 | access to type Int32 | +| Switch.cs:95:18:95:20 | access to type Int32 | Switch.cs:95:13:95:23 | case ...: | +| Switch.cs:96:17:96:28 | Before return ...; | Switch.cs:95:13:95:23 | After case ...: [match] | | Switch.cs:96:17:96:28 | return ...; | Switch.cs:96:24:96:27 | true | | Switch.cs:96:24:96:27 | true | Switch.cs:96:17:96:28 | Before return ...; | | Switch.cs:98:9:98:21 | Before return ...; | Switch.cs:93:9:97:9 | After switch (...) {...} | @@ -13604,14 +13749,18 @@ postDominance | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:103:17:103:25 | access to property Length | | Switch.cs:103:17:103:25 | Before access to property Length | Switch.cs:103:9:107:9 | switch (...) {...} | | Switch.cs:103:17:103:25 | access to property Length | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | +| Switch.cs:105:13:105:19 | After case ...: [match] | Switch.cs:105:18:105:18 | After 0 [match] | +| Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:105:18:105:18 | After 0 [no-match] | | Switch.cs:105:13:105:19 | case ...: | Switch.cs:103:17:103:25 | After access to property Length | -| Switch.cs:105:18:105:18 | 0 | Switch.cs:105:13:105:19 | After case ...: [match] | -| Switch.cs:105:21:105:29 | Before return ...; | Switch.cs:105:18:105:18 | 0 | +| Switch.cs:105:18:105:18 | 0 | Switch.cs:105:13:105:19 | case ...: | +| Switch.cs:105:21:105:29 | Before return ...; | Switch.cs:105:13:105:19 | After case ...: [match] | | Switch.cs:105:21:105:29 | return ...; | Switch.cs:105:28:105:28 | 0 | | Switch.cs:105:28:105:28 | 0 | Switch.cs:105:21:105:29 | Before return ...; | +| Switch.cs:106:13:106:19 | After case ...: [match] | Switch.cs:106:18:106:18 | After 1 [match] | +| Switch.cs:106:13:106:19 | After case ...: [no-match] | Switch.cs:106:18:106:18 | After 1 [no-match] | | Switch.cs:106:13:106:19 | case ...: | Switch.cs:105:13:105:19 | After case ...: [no-match] | -| Switch.cs:106:18:106:18 | 1 | Switch.cs:106:13:106:19 | After case ...: [match] | -| Switch.cs:106:21:106:29 | Before return ...; | Switch.cs:106:18:106:18 | 1 | +| Switch.cs:106:18:106:18 | 1 | Switch.cs:106:13:106:19 | case ...: | +| Switch.cs:106:21:106:29 | Before return ...; | Switch.cs:106:13:106:19 | After case ...: [match] | | Switch.cs:106:21:106:29 | return ...; | Switch.cs:106:28:106:28 | 1 | | Switch.cs:106:28:106:28 | 1 | Switch.cs:106:21:106:29 | Before return ...; | | Switch.cs:108:9:108:18 | Before return ...; | Switch.cs:103:9:107:9 | After switch (...) {...} | @@ -13640,21 +13789,25 @@ postDominance | Switch.cs:115:17:115:24 | After access to property Length | Switch.cs:115:17:115:24 | access to property Length | | Switch.cs:115:17:115:24 | Before access to property Length | Switch.cs:115:9:119:9 | switch (...) {...} | | Switch.cs:115:17:115:24 | access to property Length | Switch.cs:115:17:115:17 | access to parameter s | +| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:18:117:18 | After 3 [match] | +| Switch.cs:117:13:117:35 | After case ...: [no-match] | Switch.cs:117:18:117:18 | After 3 [no-match] | | Switch.cs:117:13:117:35 | case ...: | Switch.cs:115:17:115:24 | After access to property Length | -| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:13:117:35 | After case ...: [match] | +| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:13:117:35 | case ...: | | Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:25:117:34 | Before ... == ... | | Switch.cs:117:25:117:34 | ... == ... | Switch.cs:117:30:117:34 | "foo" | -| Switch.cs:117:25:117:34 | Before ... == ... | Switch.cs:117:18:117:18 | 3 | +| Switch.cs:117:25:117:34 | Before ... == ... | Switch.cs:117:13:117:35 | After case ...: [match] | | Switch.cs:117:30:117:34 | "foo" | Switch.cs:117:25:117:25 | access to parameter s | | Switch.cs:117:37:117:45 | Before return ...; | Switch.cs:117:25:117:34 | After ... == ... [true] | | Switch.cs:117:37:117:45 | return ...; | Switch.cs:117:44:117:44 | 1 | | Switch.cs:117:44:117:44 | 1 | Switch.cs:117:37:117:45 | Before return ...; | +| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:18:118:18 | After 2 [match] | +| Switch.cs:118:13:118:34 | After case ...: [no-match] | Switch.cs:118:18:118:18 | After 2 [no-match] | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:117:13:117:35 | After case ...: [no-match] | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:117:25:117:34 | After ... == ... [false] | -| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:13:118:34 | After case ...: [match] | +| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:13:118:34 | case ...: | | Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:25:118:33 | Before ... == ... | | Switch.cs:118:25:118:33 | ... == ... | Switch.cs:118:30:118:33 | "fu" | -| Switch.cs:118:25:118:33 | Before ... == ... | Switch.cs:118:18:118:18 | 2 | +| Switch.cs:118:25:118:33 | Before ... == ... | Switch.cs:118:13:118:34 | After case ...: [match] | | Switch.cs:118:30:118:33 | "fu" | Switch.cs:118:25:118:25 | access to parameter s | | Switch.cs:118:36:118:44 | Before return ...; | Switch.cs:118:25:118:33 | After ... == ... [true] | | Switch.cs:118:36:118:44 | return ...; | Switch.cs:118:43:118:43 | 2 | @@ -13675,13 +13828,16 @@ postDominance | Switch.cs:125:9:126:19 | if (...) ... | Switch.cs:124:5:127:5 | {...} | | Switch.cs:125:13:125:13 | access to parameter o | Switch.cs:125:13:125:48 | ... switch { ... } | | Switch.cs:125:13:125:48 | ... switch { ... } | Switch.cs:125:9:126:19 | if (...) ... | -| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:24:125:34 | After ... => ... [match] | +| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:24:125:34 | ... => ... | | Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:13:125:13 | access to parameter o | -| Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:125:24:125:29 | Boolean b | -| Switch.cs:125:37:125:37 | _ | Switch.cs:125:37:125:46 | After ... => ... [match] | +| Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:125:24:125:29 | After Boolean b [match] | +| Switch.cs:125:24:125:34 | After ... => ... [no-match] | Switch.cs:125:24:125:29 | After Boolean b [no-match] | +| Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:125:24:125:34 | After ... => ... [match] | +| Switch.cs:125:37:125:37 | After _ [match] | Switch.cs:125:37:125:37 | _ | +| Switch.cs:125:37:125:37 | _ | Switch.cs:125:37:125:46 | ... => ... | | Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:24:125:34 | After ... => ... [no-match] | -| Switch.cs:125:37:125:46 | After ... => ... [match] | Switch.cs:125:37:125:46 | ... => ... | -| Switch.cs:125:42:125:46 | false | Switch.cs:125:37:125:37 | _ | +| Switch.cs:125:37:125:46 | After ... => ... [match] | Switch.cs:125:37:125:37 | After _ [match] | +| Switch.cs:125:42:125:46 | false | Switch.cs:125:37:125:46 | After ... => ... [match] | | Switch.cs:126:13:126:19 | Before return ...; | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | | Switch.cs:126:13:126:19 | return ...; | Switch.cs:126:13:126:19 | Before return ...; | | Switch.cs:129:12:129:14 | Exit | Switch.cs:129:12:129:14 | Normal Exit | @@ -13696,13 +13852,16 @@ postDominance | Switch.cs:131:16:131:66 | call to method ToString | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | | Switch.cs:131:17:131:17 | access to parameter o | Switch.cs:131:17:131:53 | ... switch { ... } | | Switch.cs:131:17:131:53 | ... switch { ... } | Switch.cs:131:16:131:66 | Before call to method ToString | -| Switch.cs:131:28:131:35 | String s | Switch.cs:131:28:131:40 | After ... => ... [match] | +| Switch.cs:131:28:131:35 | String s | Switch.cs:131:28:131:40 | ... => ... | | Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:17:131:17 | access to parameter o | -| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:28:131:35 | String s | -| Switch.cs:131:43:131:43 | _ | Switch.cs:131:43:131:51 | After ... => ... [match] | +| Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:131:28:131:35 | After String s [match] | +| Switch.cs:131:28:131:40 | After ... => ... [no-match] | Switch.cs:131:28:131:35 | After String s [no-match] | +| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:28:131:40 | After ... => ... [match] | +| Switch.cs:131:43:131:43 | After _ [match] | Switch.cs:131:43:131:43 | _ | +| Switch.cs:131:43:131:43 | _ | Switch.cs:131:43:131:51 | ... => ... | | Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:28:131:40 | After ... => ... [no-match] | -| Switch.cs:131:43:131:51 | After ... => ... [match] | Switch.cs:131:43:131:51 | ... => ... | -| Switch.cs:131:48:131:51 | null | Switch.cs:131:43:131:43 | _ | +| Switch.cs:131:43:131:51 | After ... => ... [match] | Switch.cs:131:43:131:43 | After _ [match] | +| Switch.cs:131:48:131:51 | null | Switch.cs:131:43:131:51 | After ... => ... [match] | | Switch.cs:134:9:134:11 | Exit | Switch.cs:134:9:134:11 | Normal Exit | | Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:138:22:138:31 | return ...; | | Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:139:21:139:29 | return ...; | @@ -13719,14 +13878,18 @@ postDominance | Switch.cs:138:29:138:30 | After -... | Switch.cs:138:29:138:30 | -... | | Switch.cs:138:29:138:30 | Before -... | Switch.cs:138:22:138:31 | Before return ...; | | Switch.cs:138:30:138:30 | 1 | Switch.cs:138:29:138:30 | Before -... | +| Switch.cs:139:13:139:19 | After case ...: [match] | Switch.cs:139:18:139:18 | After 1 [match] | +| Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:139:18:139:18 | After 1 [no-match] | | Switch.cs:139:13:139:19 | case ...: | Switch.cs:136:17:136:17 | access to parameter i | -| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:13:139:19 | After case ...: [match] | -| Switch.cs:139:21:139:29 | Before return ...; | Switch.cs:139:18:139:18 | 1 | +| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:13:139:19 | case ...: | +| Switch.cs:139:21:139:29 | Before return ...; | Switch.cs:139:13:139:19 | After case ...: [match] | | Switch.cs:139:21:139:29 | return ...; | Switch.cs:139:28:139:28 | 1 | | Switch.cs:139:28:139:28 | 1 | Switch.cs:139:21:139:29 | Before return ...; | +| Switch.cs:140:13:140:19 | After case ...: [match] | Switch.cs:140:18:140:18 | After 2 [match] | +| Switch.cs:140:13:140:19 | After case ...: [no-match] | Switch.cs:140:18:140:18 | After 2 [no-match] | | Switch.cs:140:13:140:19 | case ...: | Switch.cs:139:13:139:19 | After case ...: [no-match] | -| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:13:140:19 | After case ...: [match] | -| Switch.cs:140:21:140:29 | Before return ...; | Switch.cs:140:18:140:18 | 2 | +| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:13:140:19 | case ...: | +| Switch.cs:140:21:140:29 | Before return ...; | Switch.cs:140:13:140:19 | After case ...: [match] | | Switch.cs:140:21:140:29 | return ...; | Switch.cs:140:28:140:28 | 2 | | Switch.cs:140:28:140:28 | 2 | Switch.cs:140:21:140:29 | Before return ...; | | Switch.cs:144:9:144:11 | Exit | Switch.cs:144:9:144:11 | Normal Exit | @@ -13737,9 +13900,11 @@ postDominance | Switch.cs:145:5:152:5 | {...} | Switch.cs:144:17:144:17 | i | | Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:145:5:152:5 | {...} | | Switch.cs:146:17:146:17 | access to parameter i | Switch.cs:146:9:151:9 | switch (...) {...} | +| Switch.cs:148:13:148:19 | After case ...: [match] | Switch.cs:148:18:148:18 | After 1 [match] | +| Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:148:18:148:18 | After 1 [no-match] | | Switch.cs:148:13:148:19 | case ...: | Switch.cs:146:17:146:17 | access to parameter i | -| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:13:148:19 | After case ...: [match] | -| Switch.cs:148:21:148:29 | Before return ...; | Switch.cs:148:18:148:18 | 1 | +| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:13:148:19 | case ...: | +| Switch.cs:148:21:148:29 | Before return ...; | Switch.cs:148:13:148:19 | After case ...: [match] | | Switch.cs:148:21:148:29 | return ...; | Switch.cs:148:28:148:28 | 1 | | Switch.cs:148:28:148:28 | 1 | Switch.cs:148:21:148:29 | Before return ...; | | Switch.cs:149:13:149:20 | After default: [match] | Switch.cs:149:13:149:20 | default: | @@ -13750,9 +13915,11 @@ postDominance | Switch.cs:149:29:149:30 | After -... | Switch.cs:149:29:149:30 | -... | | Switch.cs:149:29:149:30 | Before -... | Switch.cs:149:22:149:31 | Before return ...; | | Switch.cs:149:30:149:30 | 1 | Switch.cs:149:29:149:30 | Before -... | +| Switch.cs:150:13:150:19 | After case ...: [match] | Switch.cs:150:18:150:18 | After 2 [match] | +| Switch.cs:150:13:150:19 | After case ...: [no-match] | Switch.cs:150:18:150:18 | After 2 [no-match] | | Switch.cs:150:13:150:19 | case ...: | Switch.cs:148:13:148:19 | After case ...: [no-match] | -| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:13:150:19 | After case ...: [match] | -| Switch.cs:150:21:150:29 | Before return ...; | Switch.cs:150:18:150:18 | 2 | +| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:13:150:19 | case ...: | +| Switch.cs:150:21:150:29 | Before return ...; | Switch.cs:150:13:150:19 | After case ...: [match] | | Switch.cs:150:21:150:29 | return ...; | Switch.cs:150:28:150:28 | 2 | | Switch.cs:150:28:150:28 | 2 | Switch.cs:150:21:150:29 | Before return ...; | | Switch.cs:154:10:154:12 | Exit | Switch.cs:154:10:154:12 | Normal Exit | @@ -13771,12 +13938,16 @@ postDominance | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:36:156:38 | "a" | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:41:156:52 | After ... => ... [no-match] | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:50:156:52 | "b" | -| Switch.cs:156:28:156:31 | true | Switch.cs:156:28:156:38 | After ... => ... [match] | +| Switch.cs:156:28:156:31 | true | Switch.cs:156:28:156:38 | ... => ... | | Switch.cs:156:28:156:38 | ... => ... | Switch.cs:156:17:156:17 | access to parameter b | -| Switch.cs:156:36:156:38 | "a" | Switch.cs:156:28:156:31 | true | -| Switch.cs:156:41:156:45 | false | Switch.cs:156:41:156:52 | After ... => ... [match] | +| Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:156:28:156:31 | After true [match] | +| Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:28:156:31 | After true [no-match] | +| Switch.cs:156:36:156:38 | "a" | Switch.cs:156:28:156:38 | After ... => ... [match] | +| Switch.cs:156:41:156:45 | false | Switch.cs:156:41:156:52 | ... => ... | | Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:28:156:38 | After ... => ... [no-match] | -| Switch.cs:156:50:156:52 | "b" | Switch.cs:156:41:156:45 | false | +| Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:156:41:156:45 | After false [match] | +| Switch.cs:156:41:156:52 | After ... => ... [no-match] | Switch.cs:156:41:156:45 | After false [no-match] | +| Switch.cs:156:50:156:52 | "b" | Switch.cs:156:41:156:52 | After ... => ... [match] | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:158:13:158:49 | After ...; | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:160:13:160:49 | After ...; | | Switch.cs:157:9:160:49 | if (...) ... | Switch.cs:156:9:156:55 | After ... ...; | @@ -13817,25 +13988,31 @@ postDominance | Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:176:17:176:22 | break; | | Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:164:5:178:5 | {...} | | Switch.cs:165:17:165:17 | access to parameter i | Switch.cs:165:9:177:9 | switch (...) {...} | +| Switch.cs:167:13:167:19 | After case ...: [match] | Switch.cs:167:18:167:18 | After 1 [match] | +| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:167:18:167:18 | After 1 [no-match] | | Switch.cs:167:13:167:19 | case ...: | Switch.cs:165:17:165:17 | access to parameter i | -| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:13:167:19 | After case ...: [match] | +| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:13:167:19 | case ...: | +| Switch.cs:168:13:168:19 | After case ...: [match] | Switch.cs:168:18:168:18 | After 2 [match] | +| Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:168:18:168:18 | After 2 [no-match] | | Switch.cs:168:13:168:19 | case ...: | Switch.cs:167:13:167:19 | After case ...: [no-match] | -| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:13:168:19 | After case ...: [match] | +| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:13:168:19 | case ...: | | Switch.cs:169:17:169:50 | After call to method WriteLine | Switch.cs:169:17:169:50 | call to method WriteLine | | Switch.cs:169:17:169:50 | Before call to method WriteLine | Switch.cs:169:17:169:51 | ...; | | Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:169:42:169:49 | "1 or 2" | -| Switch.cs:169:17:169:51 | ...; | Switch.cs:167:18:167:18 | 1 | -| Switch.cs:169:17:169:51 | ...; | Switch.cs:168:18:168:18 | 2 | +| Switch.cs:169:17:169:51 | ...; | Switch.cs:167:13:167:19 | After case ...: [match] | +| Switch.cs:169:17:169:51 | ...; | Switch.cs:168:13:168:19 | After case ...: [match] | | Switch.cs:169:17:169:51 | After ...; | Switch.cs:169:17:169:50 | After call to method WriteLine | | Switch.cs:169:42:169:49 | "1 or 2" | Switch.cs:169:17:169:50 | Before call to method WriteLine | | Switch.cs:170:17:170:22 | Before break; | Switch.cs:169:17:169:51 | After ...; | | Switch.cs:170:17:170:22 | break; | Switch.cs:170:17:170:22 | Before break; | +| Switch.cs:171:13:171:19 | After case ...: [match] | Switch.cs:171:18:171:18 | After 3 [match] | +| Switch.cs:171:13:171:19 | After case ...: [no-match] | Switch.cs:171:18:171:18 | After 3 [no-match] | | Switch.cs:171:13:171:19 | case ...: | Switch.cs:168:13:168:19 | After case ...: [no-match] | -| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:13:171:19 | After case ...: [match] | +| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:13:171:19 | case ...: | | Switch.cs:172:17:172:45 | After call to method WriteLine | Switch.cs:172:17:172:45 | call to method WriteLine | | Switch.cs:172:17:172:45 | Before call to method WriteLine | Switch.cs:172:17:172:46 | ...; | | Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:172:42:172:44 | "3" | -| Switch.cs:172:17:172:46 | ...; | Switch.cs:171:18:171:18 | 3 | +| Switch.cs:172:17:172:46 | ...; | Switch.cs:171:13:171:19 | After case ...: [match] | | Switch.cs:172:17:172:46 | After ...; | Switch.cs:172:17:172:45 | After call to method WriteLine | | Switch.cs:172:42:172:44 | "3" | Switch.cs:172:17:172:45 | Before call to method WriteLine | | Switch.cs:173:17:173:22 | Before break; | Switch.cs:172:17:172:46 | After ...; | @@ -14201,36 +14378,40 @@ postDominance | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:49:17:49:22 | break; | | cflow.cs:39:9:50:9 | switch (...) {...} | cflow.cs:38:5:68:5 | {...} | | cflow.cs:39:17:39:17 | access to parameter a | cflow.cs:39:9:50:9 | switch (...) {...} | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:41:13:41:19 | case ...: | +| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:41:18:41:18 | After 1 [no-match] | | cflow.cs:41:13:41:19 | case ...: | cflow.cs:39:17:39:17 | access to parameter a | -| cflow.cs:41:18:41:18 | 1 | cflow.cs:41:13:41:19 | After case ...: [match] | +| cflow.cs:41:18:41:18 | 1 | cflow.cs:41:13:41:19 | case ...: | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:41:18:41:18 | 1 | | cflow.cs:42:17:42:38 | After call to method WriteLine | cflow.cs:42:17:42:38 | call to method WriteLine | | cflow.cs:42:17:42:38 | Before call to method WriteLine | cflow.cs:42:17:42:39 | ...; | | cflow.cs:42:17:42:38 | call to method WriteLine | cflow.cs:42:35:42:37 | "1" | -| cflow.cs:42:17:42:39 | ...; | cflow.cs:41:18:41:18 | 1 | +| cflow.cs:42:17:42:39 | ...; | cflow.cs:41:13:41:19 | After case ...: [match] | | cflow.cs:42:17:42:39 | After ...; | cflow.cs:42:17:42:38 | After call to method WriteLine | | cflow.cs:42:35:42:37 | "1" | cflow.cs:42:17:42:38 | Before call to method WriteLine | | cflow.cs:43:17:43:28 | Before goto case ...; | cflow.cs:42:17:42:39 | After ...; | | cflow.cs:43:17:43:28 | goto case ...; | cflow.cs:43:27:43:27 | 2 | | cflow.cs:43:27:43:27 | 2 | cflow.cs:43:17:43:28 | Before goto case ...; | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:44:13:44:19 | case ...: | +| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:44:18:44:18 | After 2 [no-match] | | cflow.cs:44:13:44:19 | case ...: | cflow.cs:41:13:41:19 | After case ...: [no-match] | -| cflow.cs:44:18:44:18 | 2 | cflow.cs:44:13:44:19 | After case ...: [match] | +| cflow.cs:44:18:44:18 | 2 | cflow.cs:44:13:44:19 | case ...: | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:44:18:44:18 | 2 | | cflow.cs:45:17:45:38 | After call to method WriteLine | cflow.cs:45:17:45:38 | call to method WriteLine | | cflow.cs:45:17:45:38 | Before call to method WriteLine | cflow.cs:45:17:45:39 | ...; | | cflow.cs:45:17:45:38 | call to method WriteLine | cflow.cs:45:35:45:37 | "2" | -| cflow.cs:45:17:45:39 | ...; | cflow.cs:44:18:44:18 | 2 | +| cflow.cs:45:17:45:39 | ...; | cflow.cs:44:13:44:19 | After case ...: [match] | | cflow.cs:45:17:45:39 | After ...; | cflow.cs:45:17:45:38 | After call to method WriteLine | | cflow.cs:45:35:45:37 | "2" | cflow.cs:45:17:45:38 | Before call to method WriteLine | | cflow.cs:46:17:46:28 | Before goto case ...; | cflow.cs:45:17:45:39 | After ...; | | cflow.cs:46:17:46:28 | goto case ...; | cflow.cs:46:27:46:27 | 1 | | cflow.cs:46:27:46:27 | 1 | cflow.cs:46:17:46:28 | Before goto case ...; | +| cflow.cs:47:13:47:19 | After case ...: [match] | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:47:13:47:19 | After case ...: [no-match] | cflow.cs:47:18:47:18 | After 3 [no-match] | | cflow.cs:47:13:47:19 | case ...: | cflow.cs:44:13:44:19 | After case ...: [no-match] | -| cflow.cs:47:18:47:18 | 3 | cflow.cs:47:13:47:19 | After case ...: [match] | +| cflow.cs:47:18:47:18 | 3 | cflow.cs:47:13:47:19 | case ...: | | cflow.cs:48:17:48:38 | After call to method WriteLine | cflow.cs:48:17:48:38 | call to method WriteLine | | cflow.cs:48:17:48:38 | Before call to method WriteLine | cflow.cs:48:17:48:39 | ...; | | cflow.cs:48:17:48:38 | call to method WriteLine | cflow.cs:48:35:48:37 | "3" | -| cflow.cs:48:17:48:39 | ...; | cflow.cs:47:18:47:18 | 3 | +| cflow.cs:48:17:48:39 | ...; | cflow.cs:47:13:47:19 | After case ...: [match] | | cflow.cs:48:17:48:39 | After ...; | cflow.cs:48:17:48:38 | After call to method WriteLine | | cflow.cs:48:35:48:37 | "3" | cflow.cs:48:17:48:38 | Before call to method WriteLine | | cflow.cs:49:17:49:22 | Before break; | cflow.cs:48:17:48:39 | After ...; | @@ -14239,12 +14420,14 @@ postDominance | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:58:17:58:22 | break; | | cflow.cs:51:9:59:9 | switch (...) {...} | cflow.cs:39:9:50:9 | After switch (...) {...} | | cflow.cs:51:17:51:17 | access to parameter a | cflow.cs:51:9:59:9 | switch (...) {...} | +| cflow.cs:53:13:53:20 | After case ...: [match] | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:53:13:53:20 | After case ...: [no-match] | cflow.cs:53:18:53:19 | After 42 [no-match] | | cflow.cs:53:13:53:20 | case ...: | cflow.cs:51:17:51:17 | access to parameter a | -| cflow.cs:53:18:53:19 | 42 | cflow.cs:53:13:53:20 | After case ...: [match] | +| cflow.cs:53:18:53:19 | 42 | cflow.cs:53:13:53:20 | case ...: | | cflow.cs:54:17:54:47 | After call to method WriteLine | cflow.cs:54:17:54:47 | call to method WriteLine | | cflow.cs:54:17:54:47 | Before call to method WriteLine | cflow.cs:54:17:54:48 | ...; | | cflow.cs:54:17:54:47 | call to method WriteLine | cflow.cs:54:35:54:46 | "The answer" | -| cflow.cs:54:17:54:48 | ...; | cflow.cs:53:18:53:19 | 42 | +| cflow.cs:54:17:54:48 | ...; | cflow.cs:53:13:53:20 | After case ...: [match] | | cflow.cs:54:17:54:48 | After ...; | cflow.cs:54:17:54:47 | After call to method WriteLine | | cflow.cs:54:35:54:46 | "The answer" | cflow.cs:54:17:54:47 | Before call to method WriteLine | | cflow.cs:55:17:55:22 | Before break; | cflow.cs:54:17:54:48 | After ...; | @@ -14269,10 +14452,12 @@ postDominance | cflow.cs:60:27:60:31 | Before access to field Field | cflow.cs:60:17:60:32 | Before call to method Parse | | cflow.cs:60:27:60:31 | access to field Field | cflow.cs:60:27:60:31 | this access | | cflow.cs:60:27:60:31 | this access | cflow.cs:60:27:60:31 | Before access to field Field | +| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:62:13:62:19 | After case ...: [no-match] | cflow.cs:62:18:62:18 | After 0 [no-match] | | cflow.cs:62:13:62:19 | case ...: | cflow.cs:60:17:60:32 | After call to method Parse | -| cflow.cs:62:18:62:18 | 0 | cflow.cs:62:13:62:19 | After case ...: [match] | +| cflow.cs:62:18:62:18 | 0 | cflow.cs:62:13:62:19 | case ...: | | cflow.cs:63:17:64:55 | After if (...) ... | cflow.cs:63:21:63:34 | After !... [false] | -| cflow.cs:63:17:64:55 | if (...) ... | cflow.cs:62:18:62:18 | 0 | +| cflow.cs:63:17:64:55 | if (...) ... | cflow.cs:62:13:62:19 | After case ...: [match] | | cflow.cs:63:21:63:34 | !... | cflow.cs:63:17:64:55 | if (...) ... | | cflow.cs:63:21:63:34 | After !... [false] | cflow.cs:63:23:63:33 | After ... == ... [true] | | cflow.cs:63:21:63:34 | After !... [true] | cflow.cs:63:23:63:33 | After ... == ... [false] | @@ -15151,23 +15336,29 @@ postDominance | cflow.cs:246:17:246:32 | After ... + ... | cflow.cs:246:17:246:32 | ... + ... | | cflow.cs:246:17:246:32 | Before ... + ... | cflow.cs:246:9:258:9 | switch (...) {...} | | cflow.cs:246:32:246:32 | 3 | cflow.cs:246:17:246:28 | After access to property Length | +| cflow.cs:248:13:248:19 | After case ...: [match] | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:248:18:248:18 | After 0 [no-match] | | cflow.cs:248:13:248:19 | case ...: | cflow.cs:246:17:246:32 | After ... + ... | -| cflow.cs:248:18:248:18 | 0 | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:249:17:249:29 | Before goto default; | cflow.cs:248:18:248:18 | 0 | +| cflow.cs:248:18:248:18 | 0 | cflow.cs:248:13:248:19 | case ...: | +| cflow.cs:249:17:249:29 | Before goto default; | cflow.cs:248:13:248:19 | After case ...: [match] | | cflow.cs:249:17:249:29 | goto default; | cflow.cs:249:17:249:29 | Before goto default; | +| cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:250:18:250:18 | After 1 [no-match] | | cflow.cs:250:13:250:19 | case ...: | cflow.cs:248:13:248:19 | After case ...: [no-match] | -| cflow.cs:250:18:250:18 | 1 | cflow.cs:250:13:250:19 | After case ...: [match] | +| cflow.cs:250:18:250:18 | 1 | cflow.cs:250:13:250:19 | case ...: | | cflow.cs:251:17:251:36 | After call to method WriteLine | cflow.cs:251:17:251:36 | call to method WriteLine | | cflow.cs:251:17:251:36 | Before call to method WriteLine | cflow.cs:251:17:251:37 | ...; | | cflow.cs:251:17:251:36 | call to method WriteLine | cflow.cs:251:35:251:35 | 1 | -| cflow.cs:251:17:251:37 | ...; | cflow.cs:250:18:250:18 | 1 | +| cflow.cs:251:17:251:37 | ...; | cflow.cs:250:13:250:19 | After case ...: [match] | | cflow.cs:251:17:251:37 | After ...; | cflow.cs:251:17:251:36 | After call to method WriteLine | | cflow.cs:251:35:251:35 | 1 | cflow.cs:251:17:251:36 | Before call to method WriteLine | | cflow.cs:252:17:252:22 | Before break; | cflow.cs:251:17:251:37 | After ...; | | cflow.cs:252:17:252:22 | break; | cflow.cs:252:17:252:22 | Before break; | +| cflow.cs:253:13:253:19 | After case ...: [match] | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:253:13:253:19 | After case ...: [no-match] | cflow.cs:253:18:253:18 | After 2 [no-match] | | cflow.cs:253:13:253:19 | case ...: | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:253:18:253:18 | 2 | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:254:17:254:27 | Before goto ...; | cflow.cs:253:18:253:18 | 2 | +| cflow.cs:253:18:253:18 | 2 | cflow.cs:253:13:253:19 | case ...: | +| cflow.cs:254:17:254:27 | Before goto ...; | cflow.cs:253:13:253:19 | After case ...: [match] | | cflow.cs:254:17:254:27 | goto ...; | cflow.cs:254:17:254:27 | Before goto ...; | | cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:249:17:249:29 | goto default; | | cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:255:13:255:20 | default: | @@ -18387,34 +18578,34 @@ blockDominance | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:16:18:16:28 | After ... is ... [false] | | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:16:18:16:28 | [MatchTrue] ... is ... | | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:20:9:38:9 | After switch (...) {...} | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:22:13:22:23 | After case ...: [match] | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:22:13:22:23 | After case ...: [no-match] | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:24:13:24:36 | After case ...: [match] | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:24:13:24:36 | After case ...: [no-match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:22:18:22:22 | After "xyz" [match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:22:18:22:22 | After "xyz" [no-match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:24:30:24:35 | After ... > ... [false] | | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:24:30:24:35 | After ... > ... [true] | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:27:13:27:24 | After case ...: [match] | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:27:13:27:24 | After case ...: [no-match] | | Patterns.cs:5:10:5:11 | Entry | Patterns.cs:27:13:27:24 | case ...: | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:30:13:30:27 | After case ...: [match] | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:33:13:33:24 | After case ...: [no-match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:30:18:30:26 | After String s2 [no-match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:5:10:5:11 | Entry | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | | Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:8:9:18:9 | After if (...) ... | | Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:20:9:38:9 | After switch (...) {...} | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:13:22:23 | After case ...: [match] | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:13:22:23 | After case ...: [no-match] | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:13:24:36 | After case ...: [match] | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:13:24:36 | After case ...: [no-match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:18:22:22 | After "xyz" [match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:22:18:22:22 | After "xyz" [no-match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | | Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:30:24:35 | After ... > ... [false] | | Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:24:30:24:35 | After ... > ... [true] | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:13:27:24 | After case ...: [match] | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:13:27:24 | After case ...: [no-match] | | Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:13:27:24 | case ...: | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:30:13:30:27 | After case ...: [match] | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:33:13:33:24 | After case ...: [no-match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:30:18:30:26 | After String s2 [no-match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:8:9:18:9 | After if (...) ... | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | | Patterns.cs:8:13:8:23 | After ... is ... [false] | Patterns.cs:8:13:8:23 | After ... is ... [false] | | Patterns.cs:8:13:8:23 | After ... is ... [false] | Patterns.cs:12:14:18:9 | After if (...) ... | | Patterns.cs:8:13:8:23 | After ... is ... [false] | Patterns.cs:12:18:12:31 | After ... is ... [false] | @@ -18433,44 +18624,44 @@ blockDominance | Patterns.cs:16:18:16:28 | After ... is ... [false] | Patterns.cs:16:18:16:28 | After ... is ... [false] | | Patterns.cs:16:18:16:28 | [MatchTrue] ... is ... | Patterns.cs:16:18:16:28 | [MatchTrue] ... is ... | | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:20:9:38:9 | After switch (...) {...} | -| Patterns.cs:22:13:22:23 | After case ...: [match] | Patterns.cs:22:13:22:23 | After case ...: [match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:22:13:22:23 | After case ...: [no-match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | After case ...: [match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | After case ...: [no-match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:30:24:35 | After ... > ... [false] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:30:24:35 | After ... > ... [true] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:27:13:27:24 | After case ...: [match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:27:13:27:24 | After case ...: [no-match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:27:13:27:24 | case ...: | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | After case ...: [match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [no-match] | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:13:24:36 | After case ...: [match] | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:30:24:35 | After ... > ... [false] | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:30:24:35 | After ... > ... [true] | -| Patterns.cs:24:13:24:36 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | After case ...: [no-match] | +| Patterns.cs:22:18:22:22 | After "xyz" [match] | Patterns.cs:22:18:22:22 | After "xyz" [match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:22:18:22:22 | After "xyz" [no-match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:24:30:24:35 | After ... > ... [false] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:24:30:24:35 | After ... > ... [true] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:27:13:27:24 | case ...: | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:30:18:30:26 | After String s2 [no-match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:24:30:24:35 | After ... > ... [false] | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:24:30:24:35 | After ... > ... [true] | +| Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | | Patterns.cs:24:30:24:35 | After ... > ... [false] | Patterns.cs:24:30:24:35 | After ... > ... [false] | | Patterns.cs:24:30:24:35 | After ... > ... [true] | Patterns.cs:24:30:24:35 | After ... > ... [true] | -| Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:27:13:27:24 | After case ...: [match] | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:27:13:27:24 | After case ...: [no-match] | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | After case ...: [match] | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [no-match] | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | After case ...: [match] | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | After case ...: [no-match] | | Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | case ...: | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:30:13:30:27 | After case ...: [match] | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:33:13:33:24 | After case ...: [no-match] | -| Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:30:13:30:27 | After case ...: [match] | -| Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [no-match] | -| Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:33:13:33:24 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [no-match] | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:30:18:30:26 | After String s2 [no-match] | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | +| Patterns.cs:27:18:27:23 | After Int32 i3 [match] | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:30:18:30:26 | After String s2 [no-match] | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | +| Patterns.cs:30:18:30:26 | After String s2 [match] | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:30:18:30:26 | After String s2 [no-match] | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | +| Patterns.cs:33:18:33:23 | After Object v2 [match] | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:33:18:33:23 | After Object v2 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | | Patterns.cs:47:24:47:25 | Entry | Patterns.cs:47:24:47:25 | Entry | | Patterns.cs:47:24:47:25 | Entry | Patterns.cs:48:9:48:20 | After ... is ... | | Patterns.cs:47:24:47:25 | Entry | Patterns.cs:48:9:48:20 | [MatchTrue] ... is ... | @@ -18502,45 +18693,45 @@ blockDominance | Patterns.cs:54:9:54:37 | [MatchTrue] ... is ... | Patterns.cs:54:9:54:37 | [MatchTrue] ... is ... | | Patterns.cs:56:26:56:27 | Entry | Patterns.cs:56:26:56:27 | Entry | | Patterns.cs:56:26:56:27 | Entry | Patterns.cs:58:16:62:9 | After ... switch { ... } | -| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:28 | After ... => ... [match] | -| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | +| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:17 | After not ... [match] | +| Patterns.cs:56:26:56:27 | Entry | Patterns.cs:60:13:60:17 | After not ... [no-match] | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:58:16:62:9 | After ... switch { ... } | -| Patterns.cs:60:13:60:28 | After ... => ... [match] | Patterns.cs:60:13:60:28 | After ... => ... [match] | -| Patterns.cs:60:13:60:28 | After ... => ... [no-match] | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | +| Patterns.cs:60:13:60:17 | After not ... [match] | Patterns.cs:60:13:60:17 | After not ... [match] | +| Patterns.cs:60:13:60:17 | After not ... [no-match] | Patterns.cs:60:13:60:17 | After not ... [no-match] | | Patterns.cs:65:26:65:27 | Entry | Patterns.cs:65:26:65:27 | Entry | | Patterns.cs:65:26:65:27 | Entry | Patterns.cs:67:16:71:9 | After ... switch { ... } | -| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:33 | After ... => ... [match] | -| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | -| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:70:13:70:27 | After ... => ... [match] | -| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | +| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:17 | After not ... [match] | +| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:69:13:69:17 | After not ... [no-match] | +| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:70:13:70:13 | After 2 [match] | +| Patterns.cs:65:26:65:27 | Entry | Patterns.cs:70:13:70:13 | After 2 [no-match] | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:67:16:71:9 | After ... switch { ... } | -| Patterns.cs:69:13:69:33 | After ... => ... [match] | Patterns.cs:69:13:69:33 | After ... => ... [match] | -| Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | -| Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [match] | -| Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | -| Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:70:13:70:27 | After ... => ... [match] | -| Patterns.cs:70:13:70:27 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | +| Patterns.cs:69:13:69:17 | After not ... [match] | Patterns.cs:69:13:69:17 | After not ... [match] | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:69:13:69:17 | After not ... [no-match] | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:70:13:70:13 | After 2 [match] | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:70:13:70:13 | After 2 [no-match] | +| Patterns.cs:70:13:70:13 | After 2 [match] | Patterns.cs:70:13:70:13 | After 2 [match] | +| Patterns.cs:70:13:70:13 | After 2 [no-match] | Patterns.cs:70:13:70:13 | After 2 [no-match] | | Patterns.cs:74:26:74:27 | Entry | Patterns.cs:74:26:74:27 | Entry | | Patterns.cs:74:26:74:27 | Entry | Patterns.cs:76:16:82:9 | After ... switch { ... } | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:24 | After ... => ... [match] | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:79:13:79:24 | After ... => ... [match] | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:80:13:80:20 | After ... => ... [match] | -| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:15 | After > ... [match] | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:78:13:78:15 | After > ... [no-match] | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:79:13:79:15 | After < ... [match] | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:79:13:79:15 | After < ... [no-match] | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:80:13:80:13 | After 1 [match] | +| Patterns.cs:74:26:74:27 | Entry | Patterns.cs:80:13:80:13 | After 1 [no-match] | | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:76:16:82:9 | After ... switch { ... } | -| Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:78:13:78:24 | After ... => ... [match] | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:24 | After ... => ... [match] | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [match] | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | -| Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:79:13:79:24 | After ... => ... [match] | -| Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | -| Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [match] | -| Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | -| Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:80:13:80:20 | After ... => ... [match] | -| Patterns.cs:80:13:80:20 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | +| Patterns.cs:78:13:78:15 | After > ... [match] | Patterns.cs:78:13:78:15 | After > ... [match] | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:78:13:78:15 | After > ... [no-match] | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:79:13:79:15 | After < ... [match] | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:79:13:79:15 | After < ... [no-match] | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:80:13:80:13 | After 1 [match] | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:80:13:80:13 | After 1 [no-match] | +| Patterns.cs:79:13:79:15 | After < ... [match] | Patterns.cs:79:13:79:15 | After < ... [match] | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:79:13:79:15 | After < ... [no-match] | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:80:13:80:13 | After 1 [match] | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:80:13:80:13 | After 1 [no-match] | +| Patterns.cs:80:13:80:13 | After 1 [match] | Patterns.cs:80:13:80:13 | After 1 [match] | +| Patterns.cs:80:13:80:13 | After 1 [no-match] | Patterns.cs:80:13:80:13 | After 1 [no-match] | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:26:85:27 | Entry | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:39:85:53 | After ... is ... [false] | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:39:85:53 | [MatchTrue] ... is ... | @@ -18588,110 +18779,113 @@ blockDominance | Switch.cs:10:10:10:11 | Entry | Switch.cs:10:10:10:11 | Exceptional Exit | | Switch.cs:10:10:10:11 | Entry | Switch.cs:10:10:10:11 | Exit | | Switch.cs:10:10:10:11 | Entry | Switch.cs:10:10:10:11 | Normal Exit | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:13:14:21 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:13:14:21 | After case ...: [no-match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:18:14:20 | After "a" [match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:14:18:14:20 | After "a" [no-match] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:16:13:16:19 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:16:13:16:19 | After case ...: [no-match] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:18:13:18:22 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:18:13:18:22 | After case ...: [no-match] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:20:13:20:23 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:20:13:20:23 | After case ...: [no-match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:16:18:16:18 | After 0 [match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:16:18:16:18 | After 0 [no-match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:18:18:18:21 | After null [match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:18:18:18:21 | After null [no-match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:20:18:20:22 | After Int32 i [match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:20:18:20:22 | After Int32 i [no-match] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:21:21:21:29 | After ... == ... [false] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:21:21:21:29 | After ... == ... [true] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:24:13:24:56 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:24:13:24:56 | After case ...: [no-match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:24:18:24:25 | After String s [no-match] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:32:24:43 | After ... > ... [false] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:32:24:43 | After ... > ... [true] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:32:24:55 | After ... && ... [false] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:48:24:55 | After ... != ... [false] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:24:48:24:55 | After ... != ... [true] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Entry | Switch.cs:27:13:27:39 | After case ...: [no-match] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:10:10:10:11 | Entry | Switch.cs:27:18:27:25 | After Double d [no-match] | | Switch.cs:10:10:10:11 | Entry | Switch.cs:30:13:30:20 | After default: [match] | | Switch.cs:10:10:10:11 | Exceptional Exit | Switch.cs:10:10:10:11 | Exceptional Exit | | Switch.cs:10:10:10:11 | Exit | Switch.cs:10:10:10:11 | Exit | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:10:10:10:11 | Normal Exit | -| Switch.cs:14:13:14:21 | After case ...: [match] | Switch.cs:14:13:14:21 | After case ...: [match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:10:10:10:11 | Exceptional Exit | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:14:13:14:21 | After case ...: [no-match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:16:13:16:19 | After case ...: [match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:16:13:16:19 | After case ...: [no-match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [no-match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:30:13:30:20 | After default: [match] | +| Switch.cs:14:18:14:20 | After "a" [match] | Switch.cs:14:18:14:20 | After "a" [match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:10:10:10:11 | Exceptional Exit | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:14:18:14:20 | After "a" [no-match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:16:13:16:19 | After case ...: [match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:16:18:16:18 | After 0 [match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:16:18:16:18 | After 0 [no-match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:18:18:18:21 | After null [match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:18:18:18:21 | After null [no-match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:20:18:20:22 | After Int32 i [match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:20:18:20:22 | After Int32 i [no-match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:30:13:30:20 | After default: [match] | | Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:16:13:16:19 | After case ...: [match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:16:13:16:19 | After case ...: [no-match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [no-match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:30:13:30:20 | After default: [match] | -| Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:18:13:18:22 | After case ...: [match] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [no-match] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [match] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [match] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:20:13:20:23 | After case ...: [match] | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:21:21:21:29 | After ... == ... [false] | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:21:21:21:29 | After ... == ... [true] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [match] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:16:18:16:18 | After 0 [match] | Switch.cs:16:18:16:18 | After 0 [match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:16:18:16:18 | After 0 [no-match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:18:18:18:21 | After null [match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:18:18:18:21 | After null [no-match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:20:18:20:22 | After Int32 i [match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:20:18:20:22 | After Int32 i [no-match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:30:13:30:20 | After default: [match] | +| Switch.cs:18:18:18:21 | After null [match] | Switch.cs:18:18:18:21 | After null [match] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:18:18:18:21 | After null [no-match] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:20:18:20:22 | After Int32 i [match] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:20:18:20:22 | After Int32 i [no-match] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:21:21:21:29 | After ... == ... [false] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:21:21:21:29 | After ... == ... [true] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:20:18:20:22 | After Int32 i [match] | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:21:21:21:29 | After ... == ... [false] | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:21:21:21:29 | After ... == ... [true] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:20:18:20:22 | After Int32 i [no-match] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:32:24:43 | After ... > ... [true] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:24:48:24:55 | After ... != ... [true] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | | Switch.cs:21:21:21:29 | After ... == ... [false] | Switch.cs:21:21:21:29 | After ... == ... [false] | | Switch.cs:21:21:21:29 | After ... == ... [true] | Switch.cs:21:21:21:29 | After ... == ... [true] | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:13:24:56 | After case ...: [match] | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:32:24:43 | After ... > ... [false] | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:32:24:43 | After ... > ... [true] | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:32:24:55 | After ... && ... [false] | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:48:24:55 | After ... != ... [false] | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:48:24:55 | After ... != ... [true] | -| Switch.cs:24:13:24:56 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:32:24:43 | After ... > ... [false] | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:32:24:43 | After ... > ... [true] | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:32:24:55 | After ... && ... [false] | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:48:24:55 | After ... != ... [false] | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:48:24:55 | After ... != ... [true] | +| Switch.cs:24:18:24:25 | After String s [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | | Switch.cs:24:32:24:43 | After ... > ... [false] | Switch.cs:24:32:24:43 | After ... > ... [false] | | Switch.cs:24:32:24:43 | After ... > ... [true] | Switch.cs:24:32:24:43 | After ... > ... [true] | | Switch.cs:24:32:24:43 | After ... > ... [true] | Switch.cs:24:48:24:55 | After ... != ... [false] | @@ -18699,202 +18893,202 @@ blockDominance | Switch.cs:24:32:24:55 | After ... && ... [false] | Switch.cs:24:32:24:55 | After ... && ... [false] | | Switch.cs:24:48:24:55 | After ... != ... [false] | Switch.cs:24:48:24:55 | After ... != ... [false] | | Switch.cs:24:48:24:55 | After ... != ... [true] | Switch.cs:24:48:24:55 | After ... != ... [true] | -| Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | After case ...: [no-match] | | Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:18:27:25 | After Double d [no-match] | +| Switch.cs:27:18:27:25 | After Double d [match] | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | | Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:30:13:30:20 | After default: [match] | | Switch.cs:35:10:35:11 | Entry | Switch.cs:35:10:35:11 | Entry | | Switch.cs:44:10:44:11 | Entry | Switch.cs:44:10:44:11 | Entry | | Switch.cs:44:10:44:11 | Entry | Switch.cs:46:9:52:9 | After switch (...) {...} | -| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:13:48:23 | After case ...: [match] | -| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:13:48:23 | After case ...: [no-match] | -| Switch.cs:44:10:44:11 | Entry | Switch.cs:50:13:50:39 | After case ...: [match] | -| Switch.cs:44:10:44:11 | Entry | Switch.cs:50:13:50:39 | After case ...: [no-match] | +| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:18:48:20 | After access to type Int32 [match] | +| Switch.cs:44:10:44:11 | Entry | Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | +| Switch.cs:44:10:44:11 | Entry | Switch.cs:50:18:50:21 | After access to type Boolean [match] | +| Switch.cs:44:10:44:11 | Entry | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | | Switch.cs:44:10:44:11 | Entry | Switch.cs:50:30:50:38 | After ... != ... [false] | | Switch.cs:44:10:44:11 | Entry | Switch.cs:50:30:50:38 | After ... != ... [true] | | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:46:9:52:9 | After switch (...) {...} | -| Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:48:13:48:23 | After case ...: [match] | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:48:13:48:23 | After case ...: [no-match] | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:13:50:39 | After case ...: [match] | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:13:50:39 | After case ...: [no-match] | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:30:50:38 | After ... != ... [false] | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:30:50:38 | After ... != ... [true] | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:13:50:39 | After case ...: [match] | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:30:50:38 | After ... != ... [false] | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:30:50:38 | After ... != ... [true] | -| Switch.cs:50:13:50:39 | After case ...: [no-match] | Switch.cs:50:13:50:39 | After case ...: [no-match] | +| Switch.cs:48:18:48:20 | After access to type Int32 [match] | Switch.cs:48:18:48:20 | After access to type Int32 [match] | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:50:18:50:21 | After access to type Boolean [match] | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:50:30:50:38 | After ... != ... [false] | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:50:30:50:38 | After ... != ... [true] | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:50:18:50:21 | After access to type Boolean [match] | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:50:30:50:38 | After ... != ... [false] | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:50:30:50:38 | After ... != ... [true] | +| Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | | Switch.cs:50:30:50:38 | After ... != ... [false] | Switch.cs:50:30:50:38 | After ... != ... [false] | | Switch.cs:50:30:50:38 | After ... != ... [true] | Switch.cs:50:30:50:38 | After ... != ... [true] | | Switch.cs:55:10:55:11 | Entry | Switch.cs:55:10:55:11 | Entry | | Switch.cs:55:10:55:11 | Entry | Switch.cs:57:9:63:9 | After switch (...) {...} | -| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:13:59:19 | After case ...: [match] | -| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:13:59:19 | After case ...: [no-match] | -| Switch.cs:55:10:55:11 | Entry | Switch.cs:61:13:61:19 | After case ...: [match] | -| Switch.cs:55:10:55:11 | Entry | Switch.cs:61:13:61:19 | After case ...: [no-match] | +| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:18:59:18 | After 2 [match] | +| Switch.cs:55:10:55:11 | Entry | Switch.cs:59:18:59:18 | After 2 [no-match] | +| Switch.cs:55:10:55:11 | Entry | Switch.cs:61:18:61:18 | After 3 [match] | +| Switch.cs:55:10:55:11 | Entry | Switch.cs:61:18:61:18 | After 3 [no-match] | | Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:57:9:63:9 | After switch (...) {...} | -| Switch.cs:59:13:59:19 | After case ...: [match] | Switch.cs:59:13:59:19 | After case ...: [match] | -| Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:59:13:59:19 | After case ...: [no-match] | -| Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | After case ...: [match] | -| Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | After case ...: [no-match] | -| Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:61:13:61:19 | After case ...: [match] | -| Switch.cs:61:13:61:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | After case ...: [no-match] | +| Switch.cs:59:18:59:18 | After 2 [match] | Switch.cs:59:18:59:18 | After 2 [match] | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:59:18:59:18 | After 2 [no-match] | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:61:18:61:18 | After 3 [match] | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:61:18:61:18 | After 3 [no-match] | +| Switch.cs:61:18:61:18 | After 3 [match] | Switch.cs:61:18:61:18 | After 3 [match] | +| Switch.cs:61:18:61:18 | After 3 [no-match] | Switch.cs:61:18:61:18 | After 3 [no-match] | | Switch.cs:66:10:66:11 | Entry | Switch.cs:66:10:66:11 | Entry | | Switch.cs:66:10:66:11 | Entry | Switch.cs:68:9:74:9 | After switch (...) {...} | -| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:13:70:23 | After case ...: [match] | -| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:13:70:23 | After case ...: [no-match] | -| Switch.cs:66:10:66:11 | Entry | Switch.cs:72:13:72:20 | After case ...: [match] | -| Switch.cs:66:10:66:11 | Entry | Switch.cs:72:13:72:20 | After case ...: [no-match] | +| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:18:70:20 | After access to type Int32 [match] | +| Switch.cs:66:10:66:11 | Entry | Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | +| Switch.cs:66:10:66:11 | Entry | Switch.cs:72:18:72:19 | After "" [match] | +| Switch.cs:66:10:66:11 | Entry | Switch.cs:72:18:72:19 | After "" [no-match] | | Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:68:9:74:9 | After switch (...) {...} | -| Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:70:13:70:23 | After case ...: [match] | -| Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:70:13:70:23 | After case ...: [no-match] | -| Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:72:13:72:20 | After case ...: [match] | -| Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:72:13:72:20 | After case ...: [no-match] | -| Switch.cs:72:13:72:20 | After case ...: [match] | Switch.cs:72:13:72:20 | After case ...: [match] | -| Switch.cs:72:13:72:20 | After case ...: [no-match] | Switch.cs:72:13:72:20 | After case ...: [no-match] | +| Switch.cs:70:18:70:20 | After access to type Int32 [match] | Switch.cs:70:18:70:20 | After access to type Int32 [match] | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:72:18:72:19 | After "" [match] | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:72:18:72:19 | After "" [no-match] | +| Switch.cs:72:18:72:19 | After "" [match] | Switch.cs:72:18:72:19 | After "" [match] | +| Switch.cs:72:18:72:19 | After "" [no-match] | Switch.cs:72:18:72:19 | After "" [no-match] | | Switch.cs:77:10:77:11 | Entry | Switch.cs:77:10:77:11 | Entry | | Switch.cs:77:10:77:11 | Entry | Switch.cs:77:10:77:11 | Normal Exit | | Switch.cs:77:10:77:11 | Entry | Switch.cs:79:9:87:9 | After switch (...) {...} | -| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:13:81:19 | After case ...: [match] | -| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:13:81:19 | After case ...: [no-match] | -| Switch.cs:77:10:77:11 | Entry | Switch.cs:83:13:83:19 | After case ...: [match] | -| Switch.cs:77:10:77:11 | Entry | Switch.cs:83:13:83:19 | After case ...: [no-match] | +| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:18:81:18 | After 1 [match] | +| Switch.cs:77:10:77:11 | Entry | Switch.cs:81:18:81:18 | After 1 [no-match] | +| Switch.cs:77:10:77:11 | Entry | Switch.cs:83:18:83:18 | After 2 [match] | +| Switch.cs:77:10:77:11 | Entry | Switch.cs:83:18:83:18 | After 2 [no-match] | | Switch.cs:77:10:77:11 | Entry | Switch.cs:84:21:84:25 | After ... > ... [false] | | Switch.cs:77:10:77:11 | Entry | Switch.cs:84:21:84:25 | After ... > ... [true] | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:77:10:77:11 | Normal Exit | | Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:79:9:87:9 | After switch (...) {...} | -| Switch.cs:81:13:81:19 | After case ...: [match] | Switch.cs:81:13:81:19 | After case ...: [match] | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:79:9:87:9 | After switch (...) {...} | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:81:13:81:19 | After case ...: [no-match] | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | After case ...: [match] | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | After case ...: [no-match] | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:84:21:84:25 | After ... > ... [false] | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:84:21:84:25 | After ... > ... [true] | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:83:13:83:19 | After case ...: [match] | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:84:21:84:25 | After ... > ... [false] | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:84:21:84:25 | After ... > ... [true] | -| Switch.cs:83:13:83:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | After case ...: [no-match] | +| Switch.cs:81:18:81:18 | After 1 [match] | Switch.cs:81:18:81:18 | After 1 [match] | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:79:9:87:9 | After switch (...) {...} | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:81:18:81:18 | After 1 [no-match] | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:83:18:83:18 | After 2 [match] | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:83:18:83:18 | After 2 [no-match] | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:84:21:84:25 | After ... > ... [false] | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:84:21:84:25 | After ... > ... [true] | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:83:18:83:18 | After 2 [match] | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:84:21:84:25 | After ... > ... [false] | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:84:21:84:25 | After ... > ... [true] | +| Switch.cs:83:18:83:18 | After 2 [no-match] | Switch.cs:83:18:83:18 | After 2 [no-match] | | Switch.cs:84:21:84:25 | After ... > ... [false] | Switch.cs:84:21:84:25 | After ... > ... [false] | | Switch.cs:84:21:84:25 | After ... > ... [true] | Switch.cs:84:21:84:25 | After ... > ... [true] | | Switch.cs:91:10:91:11 | Entry | Switch.cs:91:10:91:11 | Entry | | Switch.cs:91:10:91:11 | Entry | Switch.cs:91:10:91:11 | Normal Exit | -| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:13:95:23 | After case ...: [match] | -| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:13:95:23 | After case ...: [no-match] | +| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:18:95:20 | After access to type Int32 [match] | +| Switch.cs:91:10:91:11 | Entry | Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | | Switch.cs:91:10:91:11 | Normal Exit | Switch.cs:91:10:91:11 | Normal Exit | -| Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:95:13:95:23 | After case ...: [match] | -| Switch.cs:95:13:95:23 | After case ...: [no-match] | Switch.cs:95:13:95:23 | After case ...: [no-match] | +| Switch.cs:95:18:95:20 | After access to type Int32 [match] | Switch.cs:95:18:95:20 | After access to type Int32 [match] | +| Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | | Switch.cs:101:9:101:10 | Entry | Switch.cs:101:9:101:10 | Entry | | Switch.cs:101:9:101:10 | Entry | Switch.cs:101:9:101:10 | Normal Exit | | Switch.cs:101:9:101:10 | Entry | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | | Switch.cs:101:9:101:10 | Entry | Switch.cs:103:17:103:17 | After access to parameter s [null] | | Switch.cs:101:9:101:10 | Entry | Switch.cs:103:17:103:25 | After access to property Length | -| Switch.cs:101:9:101:10 | Entry | Switch.cs:105:13:105:19 | After case ...: [match] | -| Switch.cs:101:9:101:10 | Entry | Switch.cs:105:13:105:19 | After case ...: [no-match] | -| Switch.cs:101:9:101:10 | Entry | Switch.cs:106:13:106:19 | After case ...: [match] | -| Switch.cs:101:9:101:10 | Entry | Switch.cs:106:13:106:19 | After case ...: [no-match] | +| Switch.cs:101:9:101:10 | Entry | Switch.cs:105:18:105:18 | After 0 [match] | +| Switch.cs:101:9:101:10 | Entry | Switch.cs:105:18:105:18 | After 0 [no-match] | +| Switch.cs:101:9:101:10 | Entry | Switch.cs:106:18:106:18 | After 1 [match] | +| Switch.cs:101:9:101:10 | Entry | Switch.cs:106:18:106:18 | After 1 [no-match] | | Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:101:9:101:10 | Normal Exit | | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | | Switch.cs:103:17:103:17 | After access to parameter s [null] | Switch.cs:103:17:103:17 | After access to parameter s [null] | | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:101:9:101:10 | Normal Exit | | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:103:17:103:25 | After access to property Length | -| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:13:105:19 | After case ...: [match] | -| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:13:105:19 | After case ...: [no-match] | -| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:106:13:106:19 | After case ...: [match] | -| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:106:13:106:19 | After case ...: [no-match] | -| Switch.cs:105:13:105:19 | After case ...: [match] | Switch.cs:105:13:105:19 | After case ...: [match] | -| Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:105:13:105:19 | After case ...: [no-match] | -| Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:106:13:106:19 | After case ...: [match] | -| Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:106:13:106:19 | After case ...: [no-match] | -| Switch.cs:106:13:106:19 | After case ...: [match] | Switch.cs:106:13:106:19 | After case ...: [match] | -| Switch.cs:106:13:106:19 | After case ...: [no-match] | Switch.cs:106:13:106:19 | After case ...: [no-match] | +| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:18:105:18 | After 0 [match] | +| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:18:105:18 | After 0 [no-match] | +| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:106:18:106:18 | After 1 [match] | +| Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:106:18:106:18 | After 1 [no-match] | +| Switch.cs:105:18:105:18 | After 0 [match] | Switch.cs:105:18:105:18 | After 0 [match] | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:105:18:105:18 | After 0 [no-match] | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:106:18:106:18 | After 1 [match] | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:106:18:106:18 | After 1 [no-match] | +| Switch.cs:106:18:106:18 | After 1 [match] | Switch.cs:106:18:106:18 | After 1 [match] | +| Switch.cs:106:18:106:18 | After 1 [no-match] | Switch.cs:106:18:106:18 | After 1 [no-match] | | Switch.cs:111:17:111:21 | Entry | Switch.cs:111:17:111:21 | Entry | | Switch.cs:113:9:113:11 | Entry | Switch.cs:113:9:113:11 | Entry | | Switch.cs:113:9:113:11 | Entry | Switch.cs:113:9:113:11 | Normal Exit | | Switch.cs:113:9:113:11 | Entry | Switch.cs:115:9:119:9 | After switch (...) {...} | -| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:13:117:35 | After case ...: [match] | -| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:13:117:35 | After case ...: [no-match] | +| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:18:117:18 | After 3 [match] | +| Switch.cs:113:9:113:11 | Entry | Switch.cs:117:18:117:18 | After 3 [no-match] | | Switch.cs:113:9:113:11 | Entry | Switch.cs:117:25:117:34 | After ... == ... [false] | | Switch.cs:113:9:113:11 | Entry | Switch.cs:117:25:117:34 | After ... == ... [true] | -| Switch.cs:113:9:113:11 | Entry | Switch.cs:118:13:118:34 | After case ...: [match] | -| Switch.cs:113:9:113:11 | Entry | Switch.cs:118:13:118:34 | After case ...: [no-match] | | Switch.cs:113:9:113:11 | Entry | Switch.cs:118:13:118:34 | case ...: | +| Switch.cs:113:9:113:11 | Entry | Switch.cs:118:18:118:18 | After 2 [match] | +| Switch.cs:113:9:113:11 | Entry | Switch.cs:118:18:118:18 | After 2 [no-match] | | Switch.cs:113:9:113:11 | Entry | Switch.cs:118:25:118:33 | After ... == ... [false] | | Switch.cs:113:9:113:11 | Entry | Switch.cs:118:25:118:33 | After ... == ... [true] | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:113:9:113:11 | Normal Exit | | Switch.cs:115:9:119:9 | After switch (...) {...} | Switch.cs:115:9:119:9 | After switch (...) {...} | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:13:117:35 | After case ...: [match] | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:25:117:34 | After ... == ... [false] | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:25:117:34 | After ... == ... [true] | -| Switch.cs:117:13:117:35 | After case ...: [no-match] | Switch.cs:117:13:117:35 | After case ...: [no-match] | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:117:18:117:18 | After 3 [match] | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:117:25:117:34 | After ... == ... [false] | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:117:25:117:34 | After ... == ... [true] | +| Switch.cs:117:18:117:18 | After 3 [no-match] | Switch.cs:117:18:117:18 | After 3 [no-match] | | Switch.cs:117:25:117:34 | After ... == ... [false] | Switch.cs:117:25:117:34 | After ... == ... [false] | | Switch.cs:117:25:117:34 | After ... == ... [true] | Switch.cs:117:25:117:34 | After ... == ... [true] | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:13:118:34 | After case ...: [match] | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:25:118:33 | After ... == ... [false] | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:25:118:33 | After ... == ... [true] | -| Switch.cs:118:13:118:34 | After case ...: [no-match] | Switch.cs:118:13:118:34 | After case ...: [no-match] | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:115:9:119:9 | After switch (...) {...} | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | After case ...: [match] | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | After case ...: [no-match] | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | case ...: | +| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:18:118:18 | After 2 [match] | +| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:18:118:18 | After 2 [no-match] | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:25:118:33 | After ... == ... [false] | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:25:118:33 | After ... == ... [true] | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:118:18:118:18 | After 2 [match] | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:118:25:118:33 | After ... == ... [false] | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:118:25:118:33 | After ... == ... [true] | +| Switch.cs:118:18:118:18 | After 2 [no-match] | Switch.cs:118:18:118:18 | After 2 [no-match] | | Switch.cs:118:25:118:33 | After ... == ... [false] | Switch.cs:118:25:118:33 | After ... == ... [false] | | Switch.cs:118:25:118:33 | After ... == ... [true] | Switch.cs:118:25:118:33 | After ... == ... [true] | | Switch.cs:123:10:123:12 | Entry | Switch.cs:123:10:123:12 | Entry | | Switch.cs:123:10:123:12 | Entry | Switch.cs:123:10:123:12 | Normal Exit | | Switch.cs:123:10:123:12 | Entry | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | | Switch.cs:123:10:123:12 | Entry | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | -| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:34 | After ... => ... [match] | -| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:34 | After ... => ... [no-match] | +| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:29 | After Boolean b [match] | +| Switch.cs:123:10:123:12 | Entry | Switch.cs:125:24:125:29 | After Boolean b [no-match] | | Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:123:10:123:12 | Normal Exit | | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | -| Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:125:24:125:34 | After ... => ... [match] | -| Switch.cs:125:24:125:34 | After ... => ... [no-match] | Switch.cs:125:24:125:34 | After ... => ... [no-match] | +| Switch.cs:125:24:125:29 | After Boolean b [match] | Switch.cs:125:24:125:29 | After Boolean b [match] | +| Switch.cs:125:24:125:29 | After Boolean b [no-match] | Switch.cs:125:24:125:29 | After Boolean b [no-match] | | Switch.cs:129:12:129:14 | Entry | Switch.cs:129:12:129:14 | Entry | | Switch.cs:129:12:129:14 | Entry | Switch.cs:131:16:131:66 | After call to method ToString | | Switch.cs:129:12:129:14 | Entry | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | | Switch.cs:129:12:129:14 | Entry | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | -| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:40 | After ... => ... [match] | -| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:40 | After ... => ... [no-match] | +| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:35 | After String s [match] | +| Switch.cs:129:12:129:14 | Entry | Switch.cs:131:28:131:35 | After String s [no-match] | | Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:131:16:131:66 | After call to method ToString | | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | -| Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:131:28:131:40 | After ... => ... [match] | -| Switch.cs:131:28:131:40 | After ... => ... [no-match] | Switch.cs:131:28:131:40 | After ... => ... [no-match] | +| Switch.cs:131:28:131:35 | After String s [match] | Switch.cs:131:28:131:35 | After String s [match] | +| Switch.cs:131:28:131:35 | After String s [no-match] | Switch.cs:131:28:131:35 | After String s [no-match] | | Switch.cs:134:9:134:11 | Entry | Switch.cs:134:9:134:11 | Entry | | Switch.cs:134:9:134:11 | Entry | Switch.cs:134:9:134:11 | Normal Exit | -| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:13:139:19 | After case ...: [match] | -| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:13:139:19 | After case ...: [no-match] | -| Switch.cs:134:9:134:11 | Entry | Switch.cs:140:13:140:19 | After case ...: [match] | -| Switch.cs:134:9:134:11 | Entry | Switch.cs:140:13:140:19 | After case ...: [no-match] | +| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:18:139:18 | After 1 [match] | +| Switch.cs:134:9:134:11 | Entry | Switch.cs:139:18:139:18 | After 1 [no-match] | +| Switch.cs:134:9:134:11 | Entry | Switch.cs:140:18:140:18 | After 2 [match] | +| Switch.cs:134:9:134:11 | Entry | Switch.cs:140:18:140:18 | After 2 [no-match] | | Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:134:9:134:11 | Normal Exit | -| Switch.cs:139:13:139:19 | After case ...: [match] | Switch.cs:139:13:139:19 | After case ...: [match] | -| Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:139:13:139:19 | After case ...: [no-match] | -| Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:140:13:140:19 | After case ...: [match] | -| Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:140:13:140:19 | After case ...: [no-match] | -| Switch.cs:140:13:140:19 | After case ...: [match] | Switch.cs:140:13:140:19 | After case ...: [match] | -| Switch.cs:140:13:140:19 | After case ...: [no-match] | Switch.cs:140:13:140:19 | After case ...: [no-match] | +| Switch.cs:139:18:139:18 | After 1 [match] | Switch.cs:139:18:139:18 | After 1 [match] | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:139:18:139:18 | After 1 [no-match] | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:140:18:140:18 | After 2 [match] | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:140:18:140:18 | After 2 [no-match] | +| Switch.cs:140:18:140:18 | After 2 [match] | Switch.cs:140:18:140:18 | After 2 [match] | +| Switch.cs:140:18:140:18 | After 2 [no-match] | Switch.cs:140:18:140:18 | After 2 [no-match] | | Switch.cs:144:9:144:11 | Entry | Switch.cs:144:9:144:11 | Entry | | Switch.cs:144:9:144:11 | Entry | Switch.cs:144:9:144:11 | Normal Exit | -| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:13:148:19 | After case ...: [match] | -| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:13:148:19 | After case ...: [no-match] | -| Switch.cs:144:9:144:11 | Entry | Switch.cs:150:13:150:19 | After case ...: [match] | -| Switch.cs:144:9:144:11 | Entry | Switch.cs:150:13:150:19 | After case ...: [no-match] | +| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:18:148:18 | After 1 [match] | +| Switch.cs:144:9:144:11 | Entry | Switch.cs:148:18:148:18 | After 1 [no-match] | +| Switch.cs:144:9:144:11 | Entry | Switch.cs:150:18:150:18 | After 2 [match] | +| Switch.cs:144:9:144:11 | Entry | Switch.cs:150:18:150:18 | After 2 [no-match] | | Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:144:9:144:11 | Normal Exit | -| Switch.cs:148:13:148:19 | After case ...: [match] | Switch.cs:148:13:148:19 | After case ...: [match] | -| Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:148:13:148:19 | After case ...: [no-match] | -| Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:150:13:150:19 | After case ...: [match] | -| Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:150:13:150:19 | After case ...: [no-match] | -| Switch.cs:150:13:150:19 | After case ...: [match] | Switch.cs:150:13:150:19 | After case ...: [match] | -| Switch.cs:150:13:150:19 | After case ...: [no-match] | Switch.cs:150:13:150:19 | After case ...: [no-match] | +| Switch.cs:148:18:148:18 | After 1 [match] | Switch.cs:148:18:148:18 | After 1 [match] | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:148:18:148:18 | After 1 [no-match] | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:150:18:150:18 | After 2 [match] | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:150:18:150:18 | After 2 [no-match] | +| Switch.cs:150:18:150:18 | After 2 [match] | Switch.cs:150:18:150:18 | After 2 [match] | +| Switch.cs:150:18:150:18 | After 2 [no-match] | Switch.cs:150:18:150:18 | After 2 [no-match] | | Switch.cs:154:10:154:12 | Entry | Switch.cs:154:10:154:12 | Entry | | Switch.cs:154:10:154:12 | Entry | Switch.cs:156:17:156:54 | After ... switch { ... } | -| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:38 | After ... => ... [match] | -| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:38 | After ... => ... [no-match] | -| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:41:156:52 | After ... => ... [match] | -| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:41:156:52 | After ... => ... [no-match] | +| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:31 | After true [match] | +| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:28:156:31 | After true [no-match] | +| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:41:156:45 | After false [match] | +| Switch.cs:154:10:154:12 | Entry | Switch.cs:156:41:156:45 | After false [no-match] | | Switch.cs:154:10:154:12 | Entry | Switch.cs:157:9:160:49 | After if (...) ... | | Switch.cs:154:10:154:12 | Entry | Switch.cs:157:13:157:13 | After access to parameter b [false] | | Switch.cs:154:10:154:12 | Entry | Switch.cs:157:13:157:13 | After access to parameter b [true] | @@ -18902,38 +19096,38 @@ blockDominance | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:157:9:160:49 | After if (...) ... | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:157:13:157:13 | After access to parameter b [false] | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:157:13:157:13 | After access to parameter b [true] | -| Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:156:28:156:38 | After ... => ... [match] | -| Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:28:156:38 | After ... => ... [no-match] | -| Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | After ... => ... [match] | -| Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | After ... => ... [no-match] | -| Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:156:41:156:52 | After ... => ... [match] | -| Switch.cs:156:41:156:52 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | After ... => ... [no-match] | +| Switch.cs:156:28:156:31 | After true [match] | Switch.cs:156:28:156:31 | After true [match] | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:156:28:156:31 | After true [no-match] | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:156:41:156:45 | After false [match] | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:156:41:156:45 | After false [no-match] | +| Switch.cs:156:41:156:45 | After false [match] | Switch.cs:156:41:156:45 | After false [match] | +| Switch.cs:156:41:156:45 | After false [no-match] | Switch.cs:156:41:156:45 | After false [no-match] | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:157:9:160:49 | After if (...) ... | | Switch.cs:157:13:157:13 | After access to parameter b [false] | Switch.cs:157:13:157:13 | After access to parameter b [false] | | Switch.cs:157:13:157:13 | After access to parameter b [true] | Switch.cs:157:13:157:13 | After access to parameter b [true] | | Switch.cs:163:10:163:12 | Entry | Switch.cs:163:10:163:12 | Entry | | Switch.cs:163:10:163:12 | Entry | Switch.cs:165:9:177:9 | After switch (...) {...} | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:13:167:19 | After case ...: [match] | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:13:167:19 | After case ...: [no-match] | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:168:13:168:19 | After case ...: [match] | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:168:13:168:19 | After case ...: [no-match] | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:18:167:18 | After 1 [match] | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:167:18:167:18 | After 1 [no-match] | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:168:18:168:18 | After 2 [match] | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:168:18:168:18 | After 2 [no-match] | | Switch.cs:163:10:163:12 | Entry | Switch.cs:169:17:169:51 | ...; | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:171:13:171:19 | After case ...: [match] | -| Switch.cs:163:10:163:12 | Entry | Switch.cs:171:13:171:19 | After case ...: [no-match] | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:171:18:171:18 | After 3 [match] | +| Switch.cs:163:10:163:12 | Entry | Switch.cs:171:18:171:18 | After 3 [no-match] | | Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:165:9:177:9 | After switch (...) {...} | -| Switch.cs:167:13:167:19 | After case ...: [match] | Switch.cs:167:13:167:19 | After case ...: [match] | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:167:13:167:19 | After case ...: [no-match] | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:168:13:168:19 | After case ...: [match] | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:168:13:168:19 | After case ...: [no-match] | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [match] | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [no-match] | -| Switch.cs:168:13:168:19 | After case ...: [match] | Switch.cs:168:13:168:19 | After case ...: [match] | -| Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:168:13:168:19 | After case ...: [no-match] | -| Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [match] | -| Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [no-match] | +| Switch.cs:167:18:167:18 | After 1 [match] | Switch.cs:167:18:167:18 | After 1 [match] | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:167:18:167:18 | After 1 [no-match] | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:168:18:168:18 | After 2 [match] | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:168:18:168:18 | After 2 [no-match] | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:171:18:171:18 | After 3 [match] | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:171:18:171:18 | After 3 [no-match] | +| Switch.cs:168:18:168:18 | After 2 [match] | Switch.cs:168:18:168:18 | After 2 [match] | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:168:18:168:18 | After 2 [no-match] | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:171:18:171:18 | After 3 [match] | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:171:18:171:18 | After 3 [no-match] | | Switch.cs:169:17:169:51 | ...; | Switch.cs:169:17:169:51 | ...; | -| Switch.cs:171:13:171:19 | After case ...: [match] | Switch.cs:171:13:171:19 | After case ...: [match] | -| Switch.cs:171:13:171:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [no-match] | +| Switch.cs:171:18:171:18 | After 3 [match] | Switch.cs:171:18:171:18 | After 3 [match] | +| Switch.cs:171:18:171:18 | After 3 [no-match] | Switch.cs:171:18:171:18 | After 3 [no-match] | | TypeAccesses.cs:1:7:1:18 | Entry | TypeAccesses.cs:1:7:1:18 | Entry | | TypeAccesses.cs:3:10:3:10 | Entry | TypeAccesses.cs:3:10:3:10 | Entry | | TypeAccesses.cs:3:10:3:10 | Entry | TypeAccesses.cs:7:9:7:25 | After if (...) ... | @@ -19135,75 +19329,80 @@ blockDominance | cflow.cs:37:17:37:22 | Entry | cflow.cs:37:17:37:22 | Exit | | cflow.cs:37:17:37:22 | Entry | cflow.cs:39:9:50:9 | After switch (...) {...} | | cflow.cs:37:17:37:22 | Entry | cflow.cs:41:13:41:19 | After case ...: [match] | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:41:13:41:19 | After case ...: [no-match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:41:18:41:18 | After 1 [match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:41:18:41:18 | After 1 [no-match] | | cflow.cs:37:17:37:22 | Entry | cflow.cs:44:13:44:19 | After case ...: [match] | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:44:13:44:19 | After case ...: [no-match] | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:47:13:47:19 | After case ...: [match] | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:47:13:47:19 | After case ...: [no-match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:44:18:44:18 | After 2 [match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:44:18:44:18 | After 2 [no-match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:47:18:47:18 | After 3 [no-match] | | cflow.cs:37:17:37:22 | Entry | cflow.cs:51:9:59:9 | After switch (...) {...} | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:53:13:53:20 | After case ...: [match] | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:53:13:53:20 | After case ...: [no-match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:53:18:53:19 | After 42 [no-match] | | cflow.cs:37:17:37:22 | Entry | cflow.cs:60:9:66:9 | After switch (...) {...} | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:62:13:62:19 | After case ...: [match] | -| cflow.cs:37:17:37:22 | Entry | cflow.cs:62:13:62:19 | After case ...: [no-match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:37:17:37:22 | Entry | cflow.cs:62:18:62:18 | After 0 [no-match] | | cflow.cs:37:17:37:22 | Entry | cflow.cs:63:23:63:33 | After ... == ... [false] | | cflow.cs:37:17:37:22 | Entry | cflow.cs:63:23:63:33 | After ... == ... [true] | | cflow.cs:37:17:37:22 | Exit | cflow.cs:37:17:37:22 | Exit | | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:37:17:37:22 | Exit | | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:39:9:50:9 | After switch (...) {...} | | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:51:9:59:9 | After switch (...) {...} | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:13:53:20 | After case ...: [match] | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:13:53:20 | After case ...: [no-match] | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:53:18:53:19 | After 42 [no-match] | | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:60:9:66:9 | After switch (...) {...} | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:62:13:62:19 | After case ...: [match] | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:62:13:62:19 | After case ...: [no-match] | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:62:18:62:18 | After 0 [no-match] | | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:63:23:63:33 | After ... == ... [false] | | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:63:23:63:33 | After ... == ... [true] | | cflow.cs:41:13:41:19 | After case ...: [match] | cflow.cs:41:13:41:19 | After case ...: [match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Exit | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:39:9:50:9 | After switch (...) {...} | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:41:13:41:19 | After case ...: [no-match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:44:13:44:19 | After case ...: [no-match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:51:9:59:9 | After switch (...) {...} | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:53:13:53:20 | After case ...: [match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:53:13:53:20 | After case ...: [no-match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:60:9:66:9 | After switch (...) {...} | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:62:13:62:19 | After case ...: [match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:62:13:62:19 | After case ...: [no-match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:63:23:63:33 | After ... == ... [false] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:63:23:63:33 | After ... == ... [true] | +| cflow.cs:41:18:41:18 | After 1 [match] | cflow.cs:41:18:41:18 | After 1 [match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:37:17:37:22 | Exit | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:39:9:50:9 | After switch (...) {...} | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:41:18:41:18 | After 1 [no-match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:44:18:44:18 | After 2 [match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:44:18:44:18 | After 2 [no-match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:47:18:47:18 | After 3 [no-match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:51:9:59:9 | After switch (...) {...} | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:53:18:53:19 | After 42 [no-match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:60:9:66:9 | After switch (...) {...} | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:62:18:62:18 | After 0 [no-match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:63:23:63:33 | After ... == ... [false] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:63:23:63:33 | After ... == ... [true] | | cflow.cs:44:13:44:19 | After case ...: [match] | cflow.cs:44:13:44:19 | After case ...: [match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Exit | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:39:9:50:9 | After switch (...) {...} | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:44:13:44:19 | After case ...: [no-match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:51:9:59:9 | After switch (...) {...} | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:53:13:53:20 | After case ...: [match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:53:13:53:20 | After case ...: [no-match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:60:9:66:9 | After switch (...) {...} | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:62:13:62:19 | After case ...: [match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:62:13:62:19 | After case ...: [no-match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:63:23:63:33 | After ... == ... [false] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:63:23:63:33 | After ... == ... [true] | -| cflow.cs:47:13:47:19 | After case ...: [match] | cflow.cs:47:13:47:19 | After case ...: [match] | -| cflow.cs:47:13:47:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | +| cflow.cs:44:18:44:18 | After 2 [match] | cflow.cs:44:18:44:18 | After 2 [match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:37:17:37:22 | Exit | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:39:9:50:9 | After switch (...) {...} | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:44:18:44:18 | After 2 [no-match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:47:18:47:18 | After 3 [no-match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:51:9:59:9 | After switch (...) {...} | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:53:18:53:19 | After 42 [no-match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:60:9:66:9 | After switch (...) {...} | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:62:18:62:18 | After 0 [no-match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:63:23:63:33 | After ... == ... [false] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:63:23:63:33 | After ... == ... [true] | +| cflow.cs:47:18:47:18 | After 3 [match] | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:47:18:47:18 | After 3 [no-match] | cflow.cs:47:18:47:18 | After 3 [no-match] | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:37:17:37:22 | Exit | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:51:9:59:9 | After switch (...) {...} | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:60:9:66:9 | After switch (...) {...} | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:13:62:19 | After case ...: [match] | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:13:62:19 | After case ...: [no-match] | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:62:18:62:18 | After 0 [no-match] | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:63:23:63:33 | After ... == ... [false] | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:63:23:63:33 | After ... == ... [true] | -| cflow.cs:53:13:53:20 | After case ...: [match] | cflow.cs:53:13:53:20 | After case ...: [match] | -| cflow.cs:53:13:53:20 | After case ...: [no-match] | cflow.cs:53:13:53:20 | After case ...: [no-match] | +| cflow.cs:53:18:53:19 | After 42 [match] | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:53:18:53:19 | After 42 [no-match] | cflow.cs:53:18:53:19 | After 42 [no-match] | | cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:60:9:66:9 | After switch (...) {...} | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:62:13:62:19 | After case ...: [match] | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:63:23:63:33 | After ... == ... [false] | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:63:23:63:33 | After ... == ... [true] | -| cflow.cs:62:13:62:19 | After case ...: [no-match] | cflow.cs:62:13:62:19 | After case ...: [no-match] | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:63:23:63:33 | After ... == ... [false] | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:63:23:63:33 | After ... == ... [true] | +| cflow.cs:62:18:62:18 | After 0 [no-match] | cflow.cs:62:18:62:18 | After 0 [no-match] | | cflow.cs:63:23:63:33 | After ... == ... [false] | cflow.cs:63:23:63:33 | After ... == ... [false] | | cflow.cs:63:23:63:33 | After ... == ... [true] | cflow.cs:63:23:63:33 | After ... == ... [true] | | cflow.cs:70:18:70:18 | Entry | cflow.cs:70:18:70:18 | Entry | @@ -19588,12 +19787,12 @@ blockDominance | cflow.cs:240:10:240:13 | Entry | cflow.cs:244:13:244:28 | After ... > ... [false] | | cflow.cs:240:10:240:13 | Entry | cflow.cs:244:13:244:28 | After ... > ... [true] | | cflow.cs:240:10:240:13 | Entry | cflow.cs:246:9:258:9 | After switch (...) {...} | -| cflow.cs:240:10:240:13 | Entry | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:240:10:240:13 | Entry | cflow.cs:248:13:248:19 | After case ...: [no-match] | -| cflow.cs:240:10:240:13 | Entry | cflow.cs:250:13:250:19 | After case ...: [match] | -| cflow.cs:240:10:240:13 | Entry | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:240:10:240:13 | Entry | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:240:10:240:13 | Entry | cflow.cs:253:13:253:19 | After case ...: [no-match] | +| cflow.cs:240:10:240:13 | Entry | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:240:10:240:13 | Entry | cflow.cs:248:18:248:18 | After 0 [no-match] | +| cflow.cs:240:10:240:13 | Entry | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:240:10:240:13 | Entry | cflow.cs:250:18:250:18 | After 1 [no-match] | +| cflow.cs:240:10:240:13 | Entry | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:240:10:240:13 | Entry | cflow.cs:253:18:253:18 | After 2 [no-match] | | cflow.cs:240:10:240:13 | Entry | cflow.cs:255:13:255:20 | After default: [match] | | cflow.cs:242:5:242:9 | Label: | cflow.cs:242:5:242:9 | Label: | | cflow.cs:242:5:242:9 | Label: | cflow.cs:242:12:242:41 | After if (...) ... | @@ -19602,49 +19801,49 @@ blockDominance | cflow.cs:242:5:242:9 | Label: | cflow.cs:244:13:244:28 | After ... > ... [false] | | cflow.cs:242:5:242:9 | Label: | cflow.cs:244:13:244:28 | After ... > ... [true] | | cflow.cs:242:5:242:9 | Label: | cflow.cs:246:9:258:9 | After switch (...) {...} | -| cflow.cs:242:5:242:9 | Label: | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:242:5:242:9 | Label: | cflow.cs:248:13:248:19 | After case ...: [no-match] | -| cflow.cs:242:5:242:9 | Label: | cflow.cs:250:13:250:19 | After case ...: [match] | -| cflow.cs:242:5:242:9 | Label: | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:242:5:242:9 | Label: | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:242:5:242:9 | Label: | cflow.cs:253:13:253:19 | After case ...: [no-match] | +| cflow.cs:242:5:242:9 | Label: | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:242:5:242:9 | Label: | cflow.cs:248:18:248:18 | After 0 [no-match] | +| cflow.cs:242:5:242:9 | Label: | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:242:5:242:9 | Label: | cflow.cs:250:18:250:18 | After 1 [no-match] | +| cflow.cs:242:5:242:9 | Label: | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:242:5:242:9 | Label: | cflow.cs:253:18:253:18 | After 2 [no-match] | | cflow.cs:242:5:242:9 | Label: | cflow.cs:255:13:255:20 | After default: [match] | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:242:12:242:41 | After if (...) ... | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:244:13:244:28 | After ... > ... [false] | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:244:13:244:28 | After ... > ... [true] | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:246:9:258:9 | After switch (...) {...} | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:248:13:248:19 | After case ...: [no-match] | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:250:13:250:19 | After case ...: [match] | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:13:253:19 | After case ...: [no-match] | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:248:18:248:18 | After 0 [no-match] | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:250:18:250:18 | After 1 [no-match] | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:18:253:18 | After 2 [no-match] | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:255:13:255:20 | After default: [match] | | cflow.cs:242:19:242:35 | After ... == ... [false] | cflow.cs:242:19:242:35 | After ... == ... [false] | | cflow.cs:242:19:242:35 | After ... == ... [true] | cflow.cs:242:19:242:35 | After ... == ... [true] | | cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:244:13:244:28 | After ... > ... [false] | | cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:246:9:258:9 | After switch (...) {...} | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:13:248:19 | After case ...: [no-match] | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:250:13:250:19 | After case ...: [match] | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:13:253:19 | After case ...: [no-match] | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:248:18:248:18 | After 0 [no-match] | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:250:18:250:18 | After 1 [no-match] | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:18:253:18 | After 2 [no-match] | | cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:255:13:255:20 | After default: [match] | | cflow.cs:244:13:244:28 | After ... > ... [true] | cflow.cs:244:13:244:28 | After ... > ... [true] | | cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:246:9:258:9 | After switch (...) {...} | -| cflow.cs:248:13:248:19 | After case ...: [match] | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:248:13:248:19 | After case ...: [no-match] | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:250:13:250:19 | After case ...: [match] | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [no-match] | -| cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:250:13:250:19 | After case ...: [match] | -| cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [no-match] | -| cflow.cs:253:13:253:19 | After case ...: [match] | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:253:13:253:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [no-match] | +| cflow.cs:248:18:248:18 | After 0 [match] | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:248:18:248:18 | After 0 [no-match] | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:250:18:250:18 | After 1 [no-match] | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:253:18:253:18 | After 2 [no-match] | +| cflow.cs:250:18:250:18 | After 1 [match] | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:250:18:250:18 | After 1 [no-match] | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:253:18:253:18 | After 2 [no-match] | +| cflow.cs:253:18:253:18 | After 2 [match] | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:253:18:253:18 | After 2 [no-match] | cflow.cs:253:18:253:18 | After 2 [no-match] | | cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:255:13:255:20 | After default: [match] | | cflow.cs:261:49:261:53 | Entry | cflow.cs:261:49:261:53 | Entry | | cflow.cs:261:49:261:53 | Entry | cflow.cs:261:49:261:53 | Exceptional Exit | @@ -22546,34 +22745,34 @@ postBlockDominance | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:16:18:16:28 | After ... is ... [false] | | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:16:18:16:28 | [MatchTrue] ... is ... | | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:20:9:38:9 | After switch (...) {...} | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:22:13:22:23 | After case ...: [match] | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:22:13:22:23 | After case ...: [no-match] | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:24:13:24:36 | After case ...: [match] | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:24:13:24:36 | After case ...: [no-match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:22:18:22:22 | After "xyz" [match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:22:18:22:22 | After "xyz" [no-match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:24:30:24:35 | After ... > ... [false] | | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:24:30:24:35 | After ... > ... [true] | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:27:13:27:24 | After case ...: [match] | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:27:13:27:24 | After case ...: [no-match] | | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:27:13:27:24 | case ...: | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:30:13:30:27 | After case ...: [match] | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:33:13:33:24 | After case ...: [no-match] | -| Patterns.cs:22:13:22:23 | After case ...: [match] | Patterns.cs:22:13:22:23 | After case ...: [match] | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:22:13:22:23 | After case ...: [no-match] | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:13:24:36 | After case ...: [match] | -| Patterns.cs:24:13:24:36 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | After case ...: [no-match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:30:18:30:26 | After String s2 [no-match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | +| Patterns.cs:22:18:22:22 | After "xyz" [match] | Patterns.cs:22:18:22:22 | After "xyz" [match] | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:22:18:22:22 | After "xyz" [no-match] | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | +| Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | | Patterns.cs:24:30:24:35 | After ... > ... [false] | Patterns.cs:24:30:24:35 | After ... > ... [false] | | Patterns.cs:24:30:24:35 | After ... > ... [true] | Patterns.cs:24:30:24:35 | After ... > ... [true] | -| Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:27:13:27:24 | After case ...: [match] | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:27:13:27:24 | After case ...: [no-match] | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:24:13:24:36 | After case ...: [no-match] | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | | Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:24:30:24:35 | After ... > ... [false] | | Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | case ...: | -| Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:30:13:30:27 | After case ...: [match] | -| Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | After case ...: [no-match] | -| Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:33:13:33:24 | After case ...: [match] | -| Patterns.cs:33:13:33:24 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | After case ...: [no-match] | +| Patterns.cs:27:18:27:23 | After Int32 i3 [match] | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | +| Patterns.cs:30:18:30:26 | After String s2 [match] | Patterns.cs:30:18:30:26 | After String s2 [match] | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:30:18:30:26 | After String s2 [no-match] | +| Patterns.cs:33:18:33:23 | After Object v2 [match] | Patterns.cs:33:18:33:23 | After Object v2 [match] | +| Patterns.cs:33:18:33:23 | After Object v2 [no-match] | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | | Patterns.cs:47:24:47:25 | Entry | Patterns.cs:47:24:47:25 | Entry | | Patterns.cs:48:9:48:20 | After ... is ... | Patterns.cs:47:24:47:25 | Entry | | Patterns.cs:48:9:48:20 | After ... is ... | Patterns.cs:48:9:48:20 | After ... is ... | @@ -22606,36 +22805,36 @@ postBlockDominance | Patterns.cs:56:26:56:27 | Entry | Patterns.cs:56:26:56:27 | Entry | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:56:26:56:27 | Entry | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:58:16:62:9 | After ... switch { ... } | -| Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:60:13:60:28 | After ... => ... [match] | -| Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | -| Patterns.cs:60:13:60:28 | After ... => ... [match] | Patterns.cs:60:13:60:28 | After ... => ... [match] | -| Patterns.cs:60:13:60:28 | After ... => ... [no-match] | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | +| Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:60:13:60:17 | After not ... [match] | +| Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:60:13:60:17 | After not ... [no-match] | +| Patterns.cs:60:13:60:17 | After not ... [match] | Patterns.cs:60:13:60:17 | After not ... [match] | +| Patterns.cs:60:13:60:17 | After not ... [no-match] | Patterns.cs:60:13:60:17 | After not ... [no-match] | | Patterns.cs:65:26:65:27 | Entry | Patterns.cs:65:26:65:27 | Entry | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:65:26:65:27 | Entry | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:67:16:71:9 | After ... switch { ... } | -| Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:69:13:69:33 | After ... => ... [match] | -| Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | -| Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:70:13:70:27 | After ... => ... [match] | -| Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | -| Patterns.cs:69:13:69:33 | After ... => ... [match] | Patterns.cs:69:13:69:33 | After ... => ... [match] | -| Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | -| Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:70:13:70:27 | After ... => ... [match] | -| Patterns.cs:70:13:70:27 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | +| Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:69:13:69:17 | After not ... [match] | +| Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:69:13:69:17 | After not ... [no-match] | +| Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:70:13:70:13 | After 2 [match] | +| Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:70:13:70:13 | After 2 [no-match] | +| Patterns.cs:69:13:69:17 | After not ... [match] | Patterns.cs:69:13:69:17 | After not ... [match] | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:69:13:69:17 | After not ... [no-match] | +| Patterns.cs:70:13:70:13 | After 2 [match] | Patterns.cs:70:13:70:13 | After 2 [match] | +| Patterns.cs:70:13:70:13 | After 2 [no-match] | Patterns.cs:70:13:70:13 | After 2 [no-match] | | Patterns.cs:74:26:74:27 | Entry | Patterns.cs:74:26:74:27 | Entry | | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:74:26:74:27 | Entry | | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:76:16:82:9 | After ... switch { ... } | -| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:78:13:78:24 | After ... => ... [match] | -| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | -| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:79:13:79:24 | After ... => ... [match] | -| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | -| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:80:13:80:20 | After ... => ... [match] | -| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | -| Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:78:13:78:24 | After ... => ... [match] | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | -| Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:79:13:79:24 | After ... => ... [match] | -| Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | -| Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:80:13:80:20 | After ... => ... [match] | -| Patterns.cs:80:13:80:20 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | +| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:78:13:78:15 | After > ... [match] | +| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:78:13:78:15 | After > ... [no-match] | +| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:79:13:79:15 | After < ... [match] | +| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:79:13:79:15 | After < ... [no-match] | +| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:80:13:80:13 | After 1 [match] | +| Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:80:13:80:13 | After 1 [no-match] | +| Patterns.cs:78:13:78:15 | After > ... [match] | Patterns.cs:78:13:78:15 | After > ... [match] | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:78:13:78:15 | After > ... [no-match] | +| Patterns.cs:79:13:79:15 | After < ... [match] | Patterns.cs:79:13:79:15 | After < ... [match] | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:79:13:79:15 | After < ... [no-match] | +| Patterns.cs:80:13:80:13 | After 1 [match] | Patterns.cs:80:13:80:13 | After 1 [match] | +| Patterns.cs:80:13:80:13 | After 1 [no-match] | Patterns.cs:80:13:80:13 | After 1 [no-match] | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:26:85:27 | Entry | | Patterns.cs:85:39:85:53 | After ... is ... [false] | Patterns.cs:85:39:85:53 | After ... is ... [false] | | Patterns.cs:85:39:85:53 | [MatchTrue] ... is ... | Patterns.cs:85:39:85:53 | [MatchTrue] ... is ... | @@ -22682,38 +22881,39 @@ postBlockDominance | Switch.cs:10:10:10:11 | Exit | Switch.cs:10:10:10:11 | Exit | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:10:10:10:11 | Entry | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:10:10:10:11 | Normal Exit | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:14:13:14:21 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:14:13:14:21 | After case ...: [no-match] | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:16:13:16:19 | After case ...: [no-match] | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:18:13:18:22 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:18:13:18:22 | After case ...: [no-match] | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:20:13:20:23 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:20:13:20:23 | After case ...: [no-match] | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:14:18:14:20 | After "a" [match] | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:14:18:14:20 | After "a" [no-match] | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:16:18:16:18 | After 0 [no-match] | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:18:18:18:21 | After null [match] | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:18:18:18:21 | After null [no-match] | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:20:18:20:22 | After Int32 i [match] | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:20:18:20:22 | After Int32 i [no-match] | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:21:21:21:29 | After ... == ... [true] | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:24:13:24:56 | After case ...: [match] | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:24:13:24:56 | After case ...: [no-match] | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:24:18:24:25 | After String s [no-match] | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:24:32:24:43 | After ... > ... [false] | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:24:32:24:43 | After ... > ... [true] | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:24:32:24:55 | After ... && ... [false] | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:24:48:24:55 | After ... != ... [false] | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:24:48:24:55 | After ... != ... [true] | -| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:27:13:27:39 | After case ...: [no-match] | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:27:18:27:25 | After Double d [no-match] | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:30:13:30:20 | After default: [match] | -| Switch.cs:14:13:14:21 | After case ...: [match] | Switch.cs:14:13:14:21 | After case ...: [match] | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:14:13:14:21 | After case ...: [no-match] | +| Switch.cs:14:18:14:20 | After "a" [match] | Switch.cs:14:18:14:20 | After "a" [match] | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:14:18:14:20 | After "a" [no-match] | | Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:16:13:16:19 | After case ...: [match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:14:13:14:21 | After case ...: [no-match] | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:16:13:16:19 | After case ...: [no-match] | -| Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:18:13:18:22 | After case ...: [match] | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:18:13:18:22 | After case ...: [no-match] | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:20:13:20:23 | After case ...: [match] | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | +| Switch.cs:16:18:16:18 | After 0 [match] | Switch.cs:16:18:16:18 | After 0 [match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:14:18:14:20 | After "a" [no-match] | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:16:18:16:18 | After 0 [no-match] | +| Switch.cs:18:18:18:21 | After null [match] | Switch.cs:18:18:18:21 | After null [match] | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:18:18:18:21 | After null [no-match] | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:20:18:20:22 | After Int32 i [match] | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:20:18:20:22 | After Int32 i [no-match] | | Switch.cs:21:21:21:29 | After ... == ... [false] | Switch.cs:21:21:21:29 | After ... == ... [false] | -| Switch.cs:21:21:21:29 | After ... == ... [true] | Switch.cs:20:13:20:23 | After case ...: [match] | +| Switch.cs:21:21:21:29 | After ... == ... [true] | Switch.cs:20:18:20:22 | After Int32 i [match] | | Switch.cs:21:21:21:29 | After ... == ... [true] | Switch.cs:21:21:21:29 | After ... == ... [true] | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:13:24:56 | After case ...: [match] | -| Switch.cs:24:13:24:56 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:18:24:25 | After String s [match] | +| Switch.cs:24:18:24:25 | After String s [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | | Switch.cs:24:32:24:43 | After ... > ... [false] | Switch.cs:24:32:24:43 | After ... > ... [false] | | Switch.cs:24:32:24:43 | After ... > ... [true] | Switch.cs:24:32:24:43 | After ... > ... [true] | | Switch.cs:24:32:24:55 | After ... && ... [false] | Switch.cs:24:32:24:43 | After ... > ... [false] | @@ -22721,136 +22921,136 @@ postBlockDominance | Switch.cs:24:32:24:55 | After ... && ... [false] | Switch.cs:24:48:24:55 | After ... != ... [false] | | Switch.cs:24:48:24:55 | After ... != ... [false] | Switch.cs:24:48:24:55 | After ... != ... [false] | | Switch.cs:24:48:24:55 | After ... != ... [true] | Switch.cs:24:48:24:55 | After ... != ... [true] | -| Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:27:13:27:39 | After case ...: [match] | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:24:13:24:56 | After case ...: [no-match] | +| Switch.cs:27:13:27:39 | case ...: | Switch.cs:24:18:24:25 | After String s [no-match] | | Switch.cs:27:13:27:39 | case ...: | Switch.cs:24:32:24:43 | After ... > ... [false] | | Switch.cs:27:13:27:39 | case ...: | Switch.cs:24:32:24:55 | After ... && ... [false] | | Switch.cs:27:13:27:39 | case ...: | Switch.cs:24:48:24:55 | After ... != ... [false] | | Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | case ...: | -| Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:18:13:18:22 | After case ...: [match] | -| Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | +| Switch.cs:27:18:27:25 | After Double d [match] | Switch.cs:27:18:27:25 | After Double d [match] | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:24:18:24:25 | After String s [no-match] | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:24:32:24:43 | After ... > ... [false] | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:24:32:24:55 | After ... && ... [false] | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:24:48:24:55 | After ... != ... [false] | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:27:18:27:25 | After Double d [no-match] | +| Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:18:18:18:21 | After null [match] | +| Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:24:18:24:25 | After String s [no-match] | | Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:24:32:24:43 | After ... > ... [false] | | Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:24:32:24:55 | After ... && ... [false] | | Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:24:48:24:55 | After ... != ... [false] | -| Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | | Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:27:13:27:39 | case ...: | +| Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:27:18:27:25 | After Double d [no-match] | | Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:30:13:30:20 | After default: [match] | | Switch.cs:35:10:35:11 | Entry | Switch.cs:35:10:35:11 | Entry | | Switch.cs:44:10:44:11 | Entry | Switch.cs:44:10:44:11 | Entry | | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:44:10:44:11 | Entry | | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:46:9:52:9 | After switch (...) {...} | -| Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:48:13:48:23 | After case ...: [match] | -| Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:48:13:48:23 | After case ...: [no-match] | -| Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:50:13:50:39 | After case ...: [match] | -| Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:50:13:50:39 | After case ...: [no-match] | +| Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:48:18:48:20 | After access to type Int32 [match] | +| Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | +| Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:50:18:50:21 | After access to type Boolean [match] | +| Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:50:30:50:38 | After ... != ... [false] | | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:50:30:50:38 | After ... != ... [true] | -| Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:48:13:48:23 | After case ...: [match] | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:48:13:48:23 | After case ...: [no-match] | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:13:50:39 | After case ...: [match] | -| Switch.cs:50:13:50:39 | After case ...: [no-match] | Switch.cs:50:13:50:39 | After case ...: [no-match] | +| Switch.cs:48:18:48:20 | After access to type Int32 [match] | Switch.cs:48:18:48:20 | After access to type Int32 [match] | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:50:18:50:21 | After access to type Boolean [match] | +| Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | | Switch.cs:50:30:50:38 | After ... != ... [false] | Switch.cs:50:30:50:38 | After ... != ... [false] | | Switch.cs:50:30:50:38 | After ... != ... [true] | Switch.cs:50:30:50:38 | After ... != ... [true] | | Switch.cs:55:10:55:11 | Entry | Switch.cs:55:10:55:11 | Entry | | Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:55:10:55:11 | Entry | | Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:57:9:63:9 | After switch (...) {...} | -| Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:59:13:59:19 | After case ...: [match] | -| Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:59:13:59:19 | After case ...: [no-match] | -| Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:61:13:61:19 | After case ...: [match] | -| Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:61:13:61:19 | After case ...: [no-match] | -| Switch.cs:59:13:59:19 | After case ...: [match] | Switch.cs:59:13:59:19 | After case ...: [match] | -| Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:59:13:59:19 | After case ...: [no-match] | -| Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:61:13:61:19 | After case ...: [match] | -| Switch.cs:61:13:61:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | After case ...: [no-match] | +| Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:59:18:59:18 | After 2 [match] | +| Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:59:18:59:18 | After 2 [no-match] | +| Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:61:18:61:18 | After 3 [match] | +| Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:61:18:61:18 | After 3 [no-match] | +| Switch.cs:59:18:59:18 | After 2 [match] | Switch.cs:59:18:59:18 | After 2 [match] | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:59:18:59:18 | After 2 [no-match] | +| Switch.cs:61:18:61:18 | After 3 [match] | Switch.cs:61:18:61:18 | After 3 [match] | +| Switch.cs:61:18:61:18 | After 3 [no-match] | Switch.cs:61:18:61:18 | After 3 [no-match] | | Switch.cs:66:10:66:11 | Entry | Switch.cs:66:10:66:11 | Entry | | Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:66:10:66:11 | Entry | | Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:68:9:74:9 | After switch (...) {...} | -| Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:70:13:70:23 | After case ...: [match] | -| Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:70:13:70:23 | After case ...: [no-match] | -| Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:72:13:72:20 | After case ...: [match] | -| Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:72:13:72:20 | After case ...: [no-match] | -| Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:70:13:70:23 | After case ...: [match] | -| Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:70:13:70:23 | After case ...: [no-match] | -| Switch.cs:72:13:72:20 | After case ...: [match] | Switch.cs:72:13:72:20 | After case ...: [match] | -| Switch.cs:72:13:72:20 | After case ...: [no-match] | Switch.cs:72:13:72:20 | After case ...: [no-match] | +| Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:70:18:70:20 | After access to type Int32 [match] | +| Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | +| Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:72:18:72:19 | After "" [match] | +| Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:72:18:72:19 | After "" [no-match] | +| Switch.cs:70:18:70:20 | After access to type Int32 [match] | Switch.cs:70:18:70:20 | After access to type Int32 [match] | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | +| Switch.cs:72:18:72:19 | After "" [match] | Switch.cs:72:18:72:19 | After "" [match] | +| Switch.cs:72:18:72:19 | After "" [no-match] | Switch.cs:72:18:72:19 | After "" [no-match] | | Switch.cs:77:10:77:11 | Entry | Switch.cs:77:10:77:11 | Entry | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:77:10:77:11 | Entry | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:77:10:77:11 | Normal Exit | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:79:9:87:9 | After switch (...) {...} | -| Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:81:13:81:19 | After case ...: [match] | -| Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:81:13:81:19 | After case ...: [no-match] | -| Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:83:13:83:19 | After case ...: [match] | -| Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:83:13:83:19 | After case ...: [no-match] | +| Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:81:18:81:18 | After 1 [match] | +| Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:81:18:81:18 | After 1 [no-match] | +| Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:83:18:83:18 | After 2 [match] | +| Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:83:18:83:18 | After 2 [no-match] | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:84:21:84:25 | After ... > ... [false] | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:84:21:84:25 | After ... > ... [true] | | Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:79:9:87:9 | After switch (...) {...} | -| Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:83:13:83:19 | After case ...: [no-match] | +| Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:83:18:83:18 | After 2 [no-match] | | Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:84:21:84:25 | After ... > ... [true] | -| Switch.cs:81:13:81:19 | After case ...: [match] | Switch.cs:81:13:81:19 | After case ...: [match] | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:81:13:81:19 | After case ...: [no-match] | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:83:13:83:19 | After case ...: [match] | -| Switch.cs:83:13:83:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | After case ...: [no-match] | +| Switch.cs:81:18:81:18 | After 1 [match] | Switch.cs:81:18:81:18 | After 1 [match] | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:81:18:81:18 | After 1 [no-match] | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:83:18:83:18 | After 2 [match] | +| Switch.cs:83:18:83:18 | After 2 [no-match] | Switch.cs:83:18:83:18 | After 2 [no-match] | | Switch.cs:84:21:84:25 | After ... > ... [false] | Switch.cs:84:21:84:25 | After ... > ... [false] | | Switch.cs:84:21:84:25 | After ... > ... [true] | Switch.cs:84:21:84:25 | After ... > ... [true] | | Switch.cs:91:10:91:11 | Entry | Switch.cs:91:10:91:11 | Entry | | Switch.cs:91:10:91:11 | Normal Exit | Switch.cs:91:10:91:11 | Entry | | Switch.cs:91:10:91:11 | Normal Exit | Switch.cs:91:10:91:11 | Normal Exit | -| Switch.cs:91:10:91:11 | Normal Exit | Switch.cs:95:13:95:23 | After case ...: [match] | -| Switch.cs:91:10:91:11 | Normal Exit | Switch.cs:95:13:95:23 | After case ...: [no-match] | -| Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:95:13:95:23 | After case ...: [match] | -| Switch.cs:95:13:95:23 | After case ...: [no-match] | Switch.cs:95:13:95:23 | After case ...: [no-match] | +| Switch.cs:91:10:91:11 | Normal Exit | Switch.cs:95:18:95:20 | After access to type Int32 [match] | +| Switch.cs:91:10:91:11 | Normal Exit | Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | +| Switch.cs:95:18:95:20 | After access to type Int32 [match] | Switch.cs:95:18:95:20 | After access to type Int32 [match] | +| Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | | Switch.cs:101:9:101:10 | Entry | Switch.cs:101:9:101:10 | Entry | | Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:101:9:101:10 | Entry | | Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:101:9:101:10 | Normal Exit | | Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | | Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:103:17:103:17 | After access to parameter s [null] | | Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:103:17:103:25 | After access to property Length | -| Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:105:13:105:19 | After case ...: [match] | -| Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:105:13:105:19 | After case ...: [no-match] | -| Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:106:13:106:19 | After case ...: [match] | -| Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:106:13:106:19 | After case ...: [no-match] | +| Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:105:18:105:18 | After 0 [match] | +| Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:105:18:105:18 | After 0 [no-match] | +| Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:106:18:106:18 | After 1 [match] | +| Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:106:18:106:18 | After 1 [no-match] | | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | | Switch.cs:103:17:103:17 | After access to parameter s [null] | Switch.cs:103:17:103:17 | After access to parameter s [null] | | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:101:9:101:10 | Entry | | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:103:17:103:17 | After access to parameter s [null] | | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:103:17:103:25 | After access to property Length | -| Switch.cs:105:13:105:19 | After case ...: [match] | Switch.cs:105:13:105:19 | After case ...: [match] | -| Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:105:13:105:19 | After case ...: [no-match] | -| Switch.cs:106:13:106:19 | After case ...: [match] | Switch.cs:106:13:106:19 | After case ...: [match] | -| Switch.cs:106:13:106:19 | After case ...: [no-match] | Switch.cs:106:13:106:19 | After case ...: [no-match] | +| Switch.cs:105:18:105:18 | After 0 [match] | Switch.cs:105:18:105:18 | After 0 [match] | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:105:18:105:18 | After 0 [no-match] | +| Switch.cs:106:18:106:18 | After 1 [match] | Switch.cs:106:18:106:18 | After 1 [match] | +| Switch.cs:106:18:106:18 | After 1 [no-match] | Switch.cs:106:18:106:18 | After 1 [no-match] | | Switch.cs:111:17:111:21 | Entry | Switch.cs:111:17:111:21 | Entry | | Switch.cs:113:9:113:11 | Entry | Switch.cs:113:9:113:11 | Entry | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:113:9:113:11 | Entry | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:113:9:113:11 | Normal Exit | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:115:9:119:9 | After switch (...) {...} | -| Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:117:13:117:35 | After case ...: [match] | -| Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:117:13:117:35 | After case ...: [no-match] | +| Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:117:18:117:18 | After 3 [match] | +| Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:117:18:117:18 | After 3 [no-match] | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:117:25:117:34 | After ... == ... [false] | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:117:25:117:34 | After ... == ... [true] | -| Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:118:13:118:34 | After case ...: [match] | -| Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:118:13:118:34 | After case ...: [no-match] | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:118:13:118:34 | case ...: | +| Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:118:18:118:18 | After 2 [match] | +| Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:118:18:118:18 | After 2 [no-match] | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:118:25:118:33 | After ... == ... [false] | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:118:25:118:33 | After ... == ... [true] | | Switch.cs:115:9:119:9 | After switch (...) {...} | Switch.cs:115:9:119:9 | After switch (...) {...} | -| Switch.cs:115:9:119:9 | After switch (...) {...} | Switch.cs:118:13:118:34 | After case ...: [no-match] | +| Switch.cs:115:9:119:9 | After switch (...) {...} | Switch.cs:118:18:118:18 | After 2 [no-match] | | Switch.cs:115:9:119:9 | After switch (...) {...} | Switch.cs:118:25:118:33 | After ... == ... [false] | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:13:117:35 | After case ...: [match] | -| Switch.cs:117:13:117:35 | After case ...: [no-match] | Switch.cs:117:13:117:35 | After case ...: [no-match] | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:117:18:117:18 | After 3 [match] | +| Switch.cs:117:18:117:18 | After 3 [no-match] | Switch.cs:117:18:117:18 | After 3 [no-match] | | Switch.cs:117:25:117:34 | After ... == ... [false] | Switch.cs:117:25:117:34 | After ... == ... [false] | | Switch.cs:117:25:117:34 | After ... == ... [true] | Switch.cs:117:25:117:34 | After ... == ... [true] | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:13:118:34 | After case ...: [match] | -| Switch.cs:118:13:118:34 | After case ...: [no-match] | Switch.cs:118:13:118:34 | After case ...: [no-match] | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:117:13:117:35 | After case ...: [no-match] | +| Switch.cs:118:13:118:34 | case ...: | Switch.cs:117:18:117:18 | After 3 [no-match] | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:117:25:117:34 | After ... == ... [false] | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | case ...: | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:118:18:118:18 | After 2 [match] | +| Switch.cs:118:18:118:18 | After 2 [no-match] | Switch.cs:118:18:118:18 | After 2 [no-match] | | Switch.cs:118:25:118:33 | After ... == ... [false] | Switch.cs:118:25:118:33 | After ... == ... [false] | | Switch.cs:118:25:118:33 | After ... == ... [true] | Switch.cs:118:25:118:33 | After ... == ... [true] | | Switch.cs:123:10:123:12 | Entry | Switch.cs:123:10:123:12 | Entry | @@ -22858,62 +23058,62 @@ postBlockDominance | Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:123:10:123:12 | Normal Exit | | Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | | Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | -| Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:125:24:125:34 | After ... => ... [match] | -| Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:125:24:125:34 | After ... => ... [no-match] | +| Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:125:24:125:29 | After Boolean b [match] | +| Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:125:24:125:29 | After Boolean b [no-match] | | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | -| Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:125:24:125:34 | After ... => ... [match] | -| Switch.cs:125:24:125:34 | After ... => ... [no-match] | Switch.cs:125:24:125:34 | After ... => ... [no-match] | +| Switch.cs:125:24:125:29 | After Boolean b [match] | Switch.cs:125:24:125:29 | After Boolean b [match] | +| Switch.cs:125:24:125:29 | After Boolean b [no-match] | Switch.cs:125:24:125:29 | After Boolean b [no-match] | | Switch.cs:129:12:129:14 | Entry | Switch.cs:129:12:129:14 | Entry | | Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:129:12:129:14 | Entry | | Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:131:16:131:66 | After call to method ToString | | Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | | Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | -| Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:131:28:131:40 | After ... => ... [match] | -| Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:131:28:131:40 | After ... => ... [no-match] | +| Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:131:28:131:35 | After String s [match] | +| Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:131:28:131:35 | After String s [no-match] | | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | -| Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:131:28:131:40 | After ... => ... [match] | -| Switch.cs:131:28:131:40 | After ... => ... [no-match] | Switch.cs:131:28:131:40 | After ... => ... [no-match] | +| Switch.cs:131:28:131:35 | After String s [match] | Switch.cs:131:28:131:35 | After String s [match] | +| Switch.cs:131:28:131:35 | After String s [no-match] | Switch.cs:131:28:131:35 | After String s [no-match] | | Switch.cs:134:9:134:11 | Entry | Switch.cs:134:9:134:11 | Entry | | Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:134:9:134:11 | Entry | | Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:134:9:134:11 | Normal Exit | -| Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:139:13:139:19 | After case ...: [match] | -| Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:139:13:139:19 | After case ...: [no-match] | -| Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:140:13:140:19 | After case ...: [match] | -| Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:140:13:140:19 | After case ...: [no-match] | -| Switch.cs:139:13:139:19 | After case ...: [match] | Switch.cs:139:13:139:19 | After case ...: [match] | -| Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:139:13:139:19 | After case ...: [no-match] | -| Switch.cs:140:13:140:19 | After case ...: [match] | Switch.cs:140:13:140:19 | After case ...: [match] | -| Switch.cs:140:13:140:19 | After case ...: [no-match] | Switch.cs:140:13:140:19 | After case ...: [no-match] | +| Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:139:18:139:18 | After 1 [match] | +| Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:139:18:139:18 | After 1 [no-match] | +| Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:140:18:140:18 | After 2 [match] | +| Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:140:18:140:18 | After 2 [no-match] | +| Switch.cs:139:18:139:18 | After 1 [match] | Switch.cs:139:18:139:18 | After 1 [match] | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:139:18:139:18 | After 1 [no-match] | +| Switch.cs:140:18:140:18 | After 2 [match] | Switch.cs:140:18:140:18 | After 2 [match] | +| Switch.cs:140:18:140:18 | After 2 [no-match] | Switch.cs:140:18:140:18 | After 2 [no-match] | | Switch.cs:144:9:144:11 | Entry | Switch.cs:144:9:144:11 | Entry | | Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:144:9:144:11 | Entry | | Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:144:9:144:11 | Normal Exit | -| Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:148:13:148:19 | After case ...: [match] | -| Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:148:13:148:19 | After case ...: [no-match] | -| Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:150:13:150:19 | After case ...: [match] | -| Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:150:13:150:19 | After case ...: [no-match] | -| Switch.cs:148:13:148:19 | After case ...: [match] | Switch.cs:148:13:148:19 | After case ...: [match] | -| Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:148:13:148:19 | After case ...: [no-match] | -| Switch.cs:150:13:150:19 | After case ...: [match] | Switch.cs:150:13:150:19 | After case ...: [match] | -| Switch.cs:150:13:150:19 | After case ...: [no-match] | Switch.cs:150:13:150:19 | After case ...: [no-match] | +| Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:148:18:148:18 | After 1 [match] | +| Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:148:18:148:18 | After 1 [no-match] | +| Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:150:18:150:18 | After 2 [match] | +| Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:150:18:150:18 | After 2 [no-match] | +| Switch.cs:148:18:148:18 | After 1 [match] | Switch.cs:148:18:148:18 | After 1 [match] | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:148:18:148:18 | After 1 [no-match] | +| Switch.cs:150:18:150:18 | After 2 [match] | Switch.cs:150:18:150:18 | After 2 [match] | +| Switch.cs:150:18:150:18 | After 2 [no-match] | Switch.cs:150:18:150:18 | After 2 [no-match] | | Switch.cs:154:10:154:12 | Entry | Switch.cs:154:10:154:12 | Entry | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:154:10:154:12 | Entry | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:17:156:54 | After ... switch { ... } | -| Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:28:156:38 | After ... => ... [match] | -| Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:28:156:38 | After ... => ... [no-match] | -| Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:41:156:52 | After ... => ... [match] | -| Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:41:156:52 | After ... => ... [no-match] | -| Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:156:28:156:38 | After ... => ... [match] | -| Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:28:156:38 | After ... => ... [no-match] | -| Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:156:41:156:52 | After ... => ... [match] | -| Switch.cs:156:41:156:52 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | After ... => ... [no-match] | +| Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:28:156:31 | After true [match] | +| Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:28:156:31 | After true [no-match] | +| Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:41:156:45 | After false [match] | +| Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:41:156:45 | After false [no-match] | +| Switch.cs:156:28:156:31 | After true [match] | Switch.cs:156:28:156:31 | After true [match] | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:156:28:156:31 | After true [no-match] | +| Switch.cs:156:41:156:45 | After false [match] | Switch.cs:156:41:156:45 | After false [match] | +| Switch.cs:156:41:156:45 | After false [no-match] | Switch.cs:156:41:156:45 | After false [no-match] | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:154:10:154:12 | Entry | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:156:17:156:54 | After ... switch { ... } | -| Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:156:28:156:38 | After ... => ... [match] | -| Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:156:28:156:38 | After ... => ... [no-match] | -| Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:156:41:156:52 | After ... => ... [match] | -| Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:156:41:156:52 | After ... => ... [no-match] | +| Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:156:28:156:31 | After true [match] | +| Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:156:28:156:31 | After true [no-match] | +| Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:156:41:156:45 | After false [match] | +| Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:156:41:156:45 | After false [no-match] | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:157:9:160:49 | After if (...) ... | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:157:13:157:13 | After access to parameter b [false] | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:157:13:157:13 | After access to parameter b [true] | @@ -22922,22 +23122,22 @@ postBlockDominance | Switch.cs:163:10:163:12 | Entry | Switch.cs:163:10:163:12 | Entry | | Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:163:10:163:12 | Entry | | Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:165:9:177:9 | After switch (...) {...} | -| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:167:13:167:19 | After case ...: [match] | -| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:167:13:167:19 | After case ...: [no-match] | -| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:168:13:168:19 | After case ...: [match] | -| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:168:13:168:19 | After case ...: [no-match] | +| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:167:18:167:18 | After 1 [match] | +| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:167:18:167:18 | After 1 [no-match] | +| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:168:18:168:18 | After 2 [match] | +| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:168:18:168:18 | After 2 [no-match] | | Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:169:17:169:51 | ...; | -| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:171:13:171:19 | After case ...: [match] | -| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:171:13:171:19 | After case ...: [no-match] | -| Switch.cs:167:13:167:19 | After case ...: [match] | Switch.cs:167:13:167:19 | After case ...: [match] | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:167:13:167:19 | After case ...: [no-match] | -| Switch.cs:168:13:168:19 | After case ...: [match] | Switch.cs:168:13:168:19 | After case ...: [match] | -| Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:168:13:168:19 | After case ...: [no-match] | -| Switch.cs:169:17:169:51 | ...; | Switch.cs:167:13:167:19 | After case ...: [match] | -| Switch.cs:169:17:169:51 | ...; | Switch.cs:168:13:168:19 | After case ...: [match] | +| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:171:18:171:18 | After 3 [match] | +| Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:171:18:171:18 | After 3 [no-match] | +| Switch.cs:167:18:167:18 | After 1 [match] | Switch.cs:167:18:167:18 | After 1 [match] | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:167:18:167:18 | After 1 [no-match] | +| Switch.cs:168:18:168:18 | After 2 [match] | Switch.cs:168:18:168:18 | After 2 [match] | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:168:18:168:18 | After 2 [no-match] | +| Switch.cs:169:17:169:51 | ...; | Switch.cs:167:18:167:18 | After 1 [match] | +| Switch.cs:169:17:169:51 | ...; | Switch.cs:168:18:168:18 | After 2 [match] | | Switch.cs:169:17:169:51 | ...; | Switch.cs:169:17:169:51 | ...; | -| Switch.cs:171:13:171:19 | After case ...: [match] | Switch.cs:171:13:171:19 | After case ...: [match] | -| Switch.cs:171:13:171:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | After case ...: [no-match] | +| Switch.cs:171:18:171:18 | After 3 [match] | Switch.cs:171:18:171:18 | After 3 [match] | +| Switch.cs:171:18:171:18 | After 3 [no-match] | Switch.cs:171:18:171:18 | After 3 [no-match] | | TypeAccesses.cs:1:7:1:18 | Entry | TypeAccesses.cs:1:7:1:18 | Entry | | TypeAccesses.cs:3:10:3:10 | Entry | TypeAccesses.cs:3:10:3:10 | Entry | | TypeAccesses.cs:7:9:7:25 | After if (...) ... | TypeAccesses.cs:3:10:3:10 | Entry | @@ -23090,47 +23290,49 @@ postBlockDominance | cflow.cs:37:17:37:22 | Exit | cflow.cs:37:17:37:22 | Exit | | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:37:17:37:22 | Entry | | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:39:9:50:9 | After switch (...) {...} | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:41:13:41:19 | After case ...: [no-match] | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:44:13:44:19 | After case ...: [no-match] | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:47:13:47:19 | After case ...: [match] | -| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:47:13:47:19 | After case ...: [no-match] | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:41:18:41:18 | After 1 [no-match] | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:44:18:44:18 | After 2 [no-match] | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:47:18:47:18 | After 3 [no-match] | | cflow.cs:41:13:41:19 | After case ...: [match] | cflow.cs:41:13:41:19 | After case ...: [match] | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Entry | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:41:13:41:19 | After case ...: [no-match] | +| cflow.cs:41:18:41:18 | After 1 [match] | cflow.cs:41:18:41:18 | After 1 [match] | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:37:17:37:22 | Entry | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:41:18:41:18 | After 1 [no-match] | | cflow.cs:44:13:44:19 | After case ...: [match] | cflow.cs:44:13:44:19 | After case ...: [match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Entry | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:41:13:41:19 | After case ...: [no-match] | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:44:13:44:19 | After case ...: [no-match] | -| cflow.cs:47:13:47:19 | After case ...: [match] | cflow.cs:47:13:47:19 | After case ...: [match] | -| cflow.cs:47:13:47:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | +| cflow.cs:44:18:44:18 | After 2 [match] | cflow.cs:44:18:44:18 | After 2 [match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:37:17:37:22 | Entry | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:41:18:41:18 | After 1 [no-match] | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:44:18:44:18 | After 2 [no-match] | +| cflow.cs:47:18:47:18 | After 3 [match] | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:47:18:47:18 | After 3 [no-match] | cflow.cs:47:18:47:18 | After 3 [no-match] | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:37:17:37:22 | Entry | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:39:9:50:9 | After switch (...) {...} | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:41:13:41:19 | After case ...: [no-match] | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:44:13:44:19 | After case ...: [no-match] | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:47:13:47:19 | After case ...: [match] | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:47:13:47:19 | After case ...: [no-match] | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:41:18:41:18 | After 1 [no-match] | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:44:18:44:18 | After 2 [no-match] | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:47:18:47:18 | After 3 [no-match] | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:51:9:59:9 | After switch (...) {...} | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:53:13:53:20 | After case ...: [match] | -| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:53:13:53:20 | After case ...: [no-match] | -| cflow.cs:53:13:53:20 | After case ...: [match] | cflow.cs:53:13:53:20 | After case ...: [match] | -| cflow.cs:53:13:53:20 | After case ...: [no-match] | cflow.cs:53:13:53:20 | After case ...: [no-match] | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:53:18:53:19 | After 42 [no-match] | +| cflow.cs:53:18:53:19 | After 42 [match] | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:53:18:53:19 | After 42 [no-match] | cflow.cs:53:18:53:19 | After 42 [no-match] | | cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:37:17:37:22 | Entry | | cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:39:9:50:9 | After switch (...) {...} | -| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:41:13:41:19 | After case ...: [no-match] | -| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:44:13:44:19 | After case ...: [no-match] | -| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:47:13:47:19 | After case ...: [match] | -| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:47:13:47:19 | After case ...: [no-match] | +| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:41:18:41:18 | After 1 [no-match] | +| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:44:18:44:18 | After 2 [no-match] | +| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:47:18:47:18 | After 3 [match] | +| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:47:18:47:18 | After 3 [no-match] | | cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:51:9:59:9 | After switch (...) {...} | -| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:53:13:53:20 | After case ...: [match] | -| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:53:13:53:20 | After case ...: [no-match] | +| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:53:18:53:19 | After 42 [match] | +| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:53:18:53:19 | After 42 [no-match] | | cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:60:9:66:9 | After switch (...) {...} | -| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:62:13:62:19 | After case ...: [match] | -| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:62:13:62:19 | After case ...: [no-match] | +| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:62:18:62:18 | After 0 [no-match] | | cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:63:23:63:33 | After ... == ... [true] | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:62:13:62:19 | After case ...: [match] | -| cflow.cs:62:13:62:19 | After case ...: [no-match] | cflow.cs:62:13:62:19 | After case ...: [no-match] | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:62:18:62:18 | After 0 [match] | +| cflow.cs:62:18:62:18 | After 0 [no-match] | cflow.cs:62:18:62:18 | After 0 [no-match] | | cflow.cs:63:23:63:33 | After ... == ... [false] | cflow.cs:63:23:63:33 | After ... == ... [false] | -| cflow.cs:63:23:63:33 | After ... == ... [true] | cflow.cs:62:13:62:19 | After case ...: [match] | +| cflow.cs:63:23:63:33 | After ... == ... [true] | cflow.cs:62:18:62:18 | After 0 [match] | | cflow.cs:63:23:63:33 | After ... == ... [true] | cflow.cs:63:23:63:33 | After ... == ... [true] | | cflow.cs:70:18:70:18 | Entry | cflow.cs:70:18:70:18 | Entry | | cflow.cs:70:18:70:18 | Normal Exit | cflow.cs:70:18:70:18 | Entry | @@ -23463,14 +23665,14 @@ postBlockDominance | cflow.cs:242:5:242:9 | Label: | cflow.cs:240:10:240:13 | Entry | | cflow.cs:242:5:242:9 | Label: | cflow.cs:242:5:242:9 | Label: | | cflow.cs:242:5:242:9 | Label: | cflow.cs:244:13:244:28 | After ... > ... [true] | -| cflow.cs:242:5:242:9 | Label: | cflow.cs:253:13:253:19 | After case ...: [match] | +| cflow.cs:242:5:242:9 | Label: | cflow.cs:253:18:253:18 | After 2 [match] | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:240:10:240:13 | Entry | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:242:5:242:9 | Label: | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:242:12:242:41 | After if (...) ... | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:242:19:242:35 | After ... == ... [false] | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:242:19:242:35 | After ... == ... [true] | | cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:244:13:244:28 | After ... > ... [true] | -| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:13:253:19 | After case ...: [match] | +| cflow.cs:242:12:242:41 | After if (...) ... | cflow.cs:253:18:253:18 | After 2 [match] | | cflow.cs:242:19:242:35 | After ... == ... [false] | cflow.cs:242:19:242:35 | After ... == ... [false] | | cflow.cs:242:19:242:35 | After ... == ... [true] | cflow.cs:242:19:242:35 | After ... == ... [true] | | cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:240:10:240:13 | Entry | @@ -23480,7 +23682,7 @@ postBlockDominance | cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:242:19:242:35 | After ... == ... [true] | | cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:244:13:244:28 | After ... > ... [false] | | cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:244:13:244:28 | After ... > ... [true] | -| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:13:253:19 | After case ...: [match] | +| cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:253:18:253:18 | After 2 [match] | | cflow.cs:244:13:244:28 | After ... > ... [true] | cflow.cs:244:13:244:28 | After ... > ... [true] | | cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:240:10:240:13 | Entry | | cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:242:5:242:9 | Label: | @@ -23490,21 +23692,21 @@ postBlockDominance | cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:244:13:244:28 | After ... > ... [false] | | cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:244:13:244:28 | After ... > ... [true] | | cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:246:9:258:9 | After switch (...) {...} | -| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:248:13:248:19 | After case ...: [no-match] | -| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:250:13:250:19 | After case ...: [match] | -| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:253:13:253:19 | After case ...: [no-match] | +| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:248:18:248:18 | After 0 [no-match] | +| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:250:18:250:18 | After 1 [no-match] | +| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:253:18:253:18 | After 2 [no-match] | | cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:255:13:255:20 | After default: [match] | -| cflow.cs:248:13:248:19 | After case ...: [match] | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:248:13:248:19 | After case ...: [no-match] | -| cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:250:13:250:19 | After case ...: [match] | -| cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:250:13:250:19 | After case ...: [no-match] | -| cflow.cs:253:13:253:19 | After case ...: [match] | cflow.cs:253:13:253:19 | After case ...: [match] | -| cflow.cs:253:13:253:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | After case ...: [no-match] | -| cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:248:13:248:19 | After case ...: [match] | -| cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:253:13:253:19 | After case ...: [no-match] | +| cflow.cs:248:18:248:18 | After 0 [match] | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:248:18:248:18 | After 0 [no-match] | +| cflow.cs:250:18:250:18 | After 1 [match] | cflow.cs:250:18:250:18 | After 1 [match] | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:250:18:250:18 | After 1 [no-match] | +| cflow.cs:253:18:253:18 | After 2 [match] | cflow.cs:253:18:253:18 | After 2 [match] | +| cflow.cs:253:18:253:18 | After 2 [no-match] | cflow.cs:253:18:253:18 | After 2 [no-match] | +| cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:248:18:248:18 | After 0 [match] | +| cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:253:18:253:18 | After 2 [no-match] | | cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:255:13:255:20 | After default: [match] | | cflow.cs:261:49:261:53 | Entry | cflow.cs:261:49:261:53 | Entry | | cflow.cs:261:49:261:53 | Exceptional Exit | cflow.cs:261:49:261:53 | Exceptional Exit | diff --git a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected index b0824d758a0..2a3a0a7020f 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected @@ -5616,11 +5616,15 @@ nodeEnclosing | Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:22:18:22:22 | After "xyz" [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:23:17:23:22 | Before break; | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:23:17:23:22 | break; | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:24:13:24:36 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:24:30:24:31 | access to local variable i2 | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:5:10:5:11 | M1 | @@ -5646,6 +5650,8 @@ nodeEnclosing | Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:27:18:27:23 | After Int32 i3 [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:28:17:28:46 | After call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:28:17:28:46 | Before call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | @@ -5665,6 +5671,8 @@ nodeEnclosing | Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:30:18:30:26 | After String s2 [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:31:17:31:49 | After call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:31:17:31:49 | Before call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | @@ -5684,6 +5692,8 @@ nodeEnclosing | Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:33:13:33:24 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:33:18:33:23 | After Object v2 [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:33:18:33:23 | After Object v2 [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:34:17:34:22 | Before break; | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:34:17:34:22 | break; | Patterns.cs:5:10:5:11 | M1 | @@ -5772,7 +5782,8 @@ nodeEnclosing | Patterns.cs:58:16:58:16 | access to parameter i | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:56:26:56:27 | M5 | -| Patterns.cs:60:13:60:17 | After not ... | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:13:60:17 | After not ... [match] | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:13:60:17 | After not ... [no-match] | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:60:13:60:17 | Before not ... | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:60:13:60:17 | not ... | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:56:26:56:27 | M5 | @@ -5780,6 +5791,7 @@ nodeEnclosing | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:60:17:60:17 | 1 | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:61:13:61:13 | After _ [match] | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:61:13:61:13 | _ | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:61:13:61:24 | After ... => ... [match] | Patterns.cs:56:26:56:27 | M5 | @@ -5793,7 +5805,8 @@ nodeEnclosing | Patterns.cs:67:16:67:16 | 2 | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:67:16:71:9 | ... switch { ... } | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:65:26:65:27 | M6 | -| Patterns.cs:69:13:69:17 | After not ... | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:69:13:69:17 | After not ... [match] | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:69:13:69:17 | Before not ... | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:69:13:69:17 | not ... | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:65:26:65:27 | M6 | @@ -5802,6 +5815,8 @@ nodeEnclosing | Patterns.cs:69:17:69:17 | 2 | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:69:22:69:33 | "impossible" | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:70:13:70:13 | 2 | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:70:13:70:13 | After 2 [match] | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:70:13:70:13 | After 2 [no-match] | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | Patterns.cs:65:26:65:27 | M6 | @@ -5817,7 +5832,8 @@ nodeEnclosing | Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:78:13:78:15 | > ... | Patterns.cs:74:26:74:27 | M7 | -| Patterns.cs:78:13:78:15 | After > ... | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:78:13:78:15 | After > ... [match] | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:78:13:78:15 | Before > ... | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:74:26:74:27 | M7 | @@ -5825,7 +5841,8 @@ nodeEnclosing | Patterns.cs:78:15:78:15 | 1 | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:79:13:79:15 | < ... | Patterns.cs:74:26:74:27 | M7 | -| Patterns.cs:79:13:79:15 | After < ... | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:13:79:15 | After < ... [match] | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:79:13:79:15 | Before < ... | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:74:26:74:27 | M7 | @@ -5833,10 +5850,13 @@ nodeEnclosing | Patterns.cs:79:15:79:15 | 0 | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:80:13:80:13 | 1 | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:80:13:80:13 | After 1 [match] | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:80:13:80:13 | After 1 [no-match] | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:80:18:80:20 | "1" | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:81:13:81:13 | After _ [match] | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:81:13:81:13 | _ | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:81:13:81:20 | After ... => ... [match] | Patterns.cs:74:26:74:27 | M7 | @@ -6191,12 +6211,16 @@ nodeEnclosing | Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:14:13:14:21 | case ...: | Switch.cs:10:10:10:11 | M2 | | Switch.cs:14:18:14:20 | "a" | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:14:18:14:20 | After "a" [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:15:17:15:23 | Before return ...; | Switch.cs:10:10:10:11 | M2 | | Switch.cs:15:17:15:23 | return ...; | Switch.cs:10:10:10:11 | M2 | | Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:16:13:16:19 | case ...: | Switch.cs:10:10:10:11 | M2 | | Switch.cs:16:18:16:18 | 0 | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:16:18:16:18 | After 0 [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:17:17:17:38 | Before throw ...; | Switch.cs:10:10:10:11 | M2 | | Switch.cs:17:17:17:38 | throw ...; | Switch.cs:10:10:10:11 | M2 | | Switch.cs:17:23:17:37 | After object creation of type Exception | Switch.cs:10:10:10:11 | M2 | @@ -6205,12 +6229,16 @@ nodeEnclosing | Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:18:13:18:22 | case ...: | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:18:18:18:21 | After null [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:18:18:18:21 | null | Switch.cs:10:10:10:11 | M2 | | Switch.cs:19:17:19:29 | Before goto default; | Switch.cs:10:10:10:11 | M2 | | Switch.cs:19:17:19:29 | goto default; | Switch.cs:10:10:10:11 | M2 | | Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:20:13:20:23 | case ...: | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:20:18:20:22 | Int32 i | Switch.cs:10:10:10:11 | M2 | | Switch.cs:21:17:22:27 | After if (...) ... | Switch.cs:10:10:10:11 | M2 | | Switch.cs:21:17:22:27 | if (...) ... | Switch.cs:10:10:10:11 | M2 | @@ -6228,6 +6256,8 @@ nodeEnclosing | Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:13:24:56 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:13:24:56 | case ...: | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:24:18:24:25 | After String s [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:18:24:25 | String s | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:32:24:32 | access to local variable s | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:32:24:39 | After access to property Length | Switch.cs:10:10:10:11 | M2 | @@ -6258,6 +6288,8 @@ nodeEnclosing | Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:27:13:27:39 | case ...: | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:27:18:27:25 | After Double d [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:27:18:27:25 | Double d | Switch.cs:10:10:10:11 | M2 | | Switch.cs:27:32:27:38 | Before call to method Throw | Switch.cs:10:10:10:11 | M2 | | Switch.cs:27:32:27:38 | call to method Throw | Switch.cs:10:10:10:11 | M2 | @@ -6287,12 +6319,16 @@ nodeEnclosing | Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:44:10:44:11 | M4 | | Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:44:10:44:11 | M4 | | Switch.cs:48:13:48:23 | case ...: | Switch.cs:44:10:44:11 | M4 | +| Switch.cs:48:18:48:20 | After access to type Int32 [match] | Switch.cs:44:10:44:11 | M4 | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:44:10:44:11 | M4 | | Switch.cs:48:18:48:20 | access to type Int32 | Switch.cs:44:10:44:11 | M4 | | Switch.cs:49:17:49:22 | Before break; | Switch.cs:44:10:44:11 | M4 | | Switch.cs:49:17:49:22 | break; | Switch.cs:44:10:44:11 | M4 | | Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:44:10:44:11 | M4 | | Switch.cs:50:13:50:39 | After case ...: [no-match] | Switch.cs:44:10:44:11 | M4 | | Switch.cs:50:13:50:39 | case ...: | Switch.cs:44:10:44:11 | M4 | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:44:10:44:11 | M4 | +| Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | Switch.cs:44:10:44:11 | M4 | | Switch.cs:50:18:50:21 | access to type Boolean | Switch.cs:44:10:44:11 | M4 | | Switch.cs:50:30:50:30 | access to parameter o | Switch.cs:44:10:44:11 | M4 | | Switch.cs:50:30:50:38 | ... != ... | Switch.cs:44:10:44:11 | M4 | @@ -6318,12 +6354,16 @@ nodeEnclosing | Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:55:10:55:11 | M5 | | Switch.cs:59:13:59:19 | case ...: | Switch.cs:55:10:55:11 | M5 | | Switch.cs:59:18:59:18 | 2 | Switch.cs:55:10:55:11 | M5 | +| Switch.cs:59:18:59:18 | After 2 [match] | Switch.cs:55:10:55:11 | M5 | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:55:10:55:11 | M5 | | Switch.cs:60:17:60:22 | Before break; | Switch.cs:55:10:55:11 | M5 | | Switch.cs:60:17:60:22 | break; | Switch.cs:55:10:55:11 | M5 | | Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:55:10:55:11 | M5 | | Switch.cs:61:13:61:19 | After case ...: [no-match] | Switch.cs:55:10:55:11 | M5 | | Switch.cs:61:13:61:19 | case ...: | Switch.cs:55:10:55:11 | M5 | | Switch.cs:61:18:61:18 | 3 | Switch.cs:55:10:55:11 | M5 | +| Switch.cs:61:18:61:18 | After 3 [match] | Switch.cs:55:10:55:11 | M5 | +| Switch.cs:61:18:61:18 | After 3 [no-match] | Switch.cs:55:10:55:11 | M5 | | Switch.cs:62:17:62:22 | Before break; | Switch.cs:55:10:55:11 | M5 | | Switch.cs:62:17:62:22 | break; | Switch.cs:55:10:55:11 | M5 | | Switch.cs:66:10:66:11 | Entry | Switch.cs:66:10:66:11 | M6 | @@ -6341,6 +6381,8 @@ nodeEnclosing | Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:66:10:66:11 | M6 | | Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:66:10:66:11 | M6 | | Switch.cs:70:13:70:23 | case ...: | Switch.cs:66:10:66:11 | M6 | +| Switch.cs:70:18:70:20 | After access to type Int32 [match] | Switch.cs:66:10:66:11 | M6 | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:66:10:66:11 | M6 | | Switch.cs:70:18:70:20 | access to type Int32 | Switch.cs:66:10:66:11 | M6 | | Switch.cs:71:17:71:22 | Before break; | Switch.cs:66:10:66:11 | M6 | | Switch.cs:71:17:71:22 | break; | Switch.cs:66:10:66:11 | M6 | @@ -6348,6 +6390,8 @@ nodeEnclosing | Switch.cs:72:13:72:20 | After case ...: [no-match] | Switch.cs:66:10:66:11 | M6 | | Switch.cs:72:13:72:20 | case ...: | Switch.cs:66:10:66:11 | M6 | | Switch.cs:72:18:72:19 | "" | Switch.cs:66:10:66:11 | M6 | +| Switch.cs:72:18:72:19 | After "" [match] | Switch.cs:66:10:66:11 | M6 | +| Switch.cs:72:18:72:19 | After "" [no-match] | Switch.cs:66:10:66:11 | M6 | | Switch.cs:73:17:73:22 | Before break; | Switch.cs:66:10:66:11 | M6 | | Switch.cs:73:17:73:22 | break; | Switch.cs:66:10:66:11 | M6 | | Switch.cs:77:10:77:11 | Entry | Switch.cs:77:10:77:11 | M7 | @@ -6363,6 +6407,8 @@ nodeEnclosing | Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:77:10:77:11 | M7 | | Switch.cs:81:13:81:19 | case ...: | Switch.cs:77:10:77:11 | M7 | | Switch.cs:81:18:81:18 | 1 | Switch.cs:77:10:77:11 | M7 | +| Switch.cs:81:18:81:18 | After 1 [match] | Switch.cs:77:10:77:11 | M7 | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:77:10:77:11 | M7 | | Switch.cs:82:17:82:28 | Before return ...; | Switch.cs:77:10:77:11 | M7 | | Switch.cs:82:17:82:28 | return ...; | Switch.cs:77:10:77:11 | M7 | | Switch.cs:82:24:82:27 | true | Switch.cs:77:10:77:11 | M7 | @@ -6370,6 +6416,8 @@ nodeEnclosing | Switch.cs:83:13:83:19 | After case ...: [no-match] | Switch.cs:77:10:77:11 | M7 | | Switch.cs:83:13:83:19 | case ...: | Switch.cs:77:10:77:11 | M7 | | Switch.cs:83:18:83:18 | 2 | Switch.cs:77:10:77:11 | M7 | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:77:10:77:11 | M7 | +| Switch.cs:83:18:83:18 | After 2 [no-match] | Switch.cs:77:10:77:11 | M7 | | Switch.cs:84:17:85:26 | After if (...) ... | Switch.cs:77:10:77:11 | M7 | | Switch.cs:84:17:85:26 | if (...) ... | Switch.cs:77:10:77:11 | M7 | | Switch.cs:84:21:84:21 | access to parameter j | Switch.cs:77:10:77:11 | M7 | @@ -6397,6 +6445,8 @@ nodeEnclosing | Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:91:10:91:11 | M8 | | Switch.cs:95:13:95:23 | After case ...: [no-match] | Switch.cs:91:10:91:11 | M8 | | Switch.cs:95:13:95:23 | case ...: | Switch.cs:91:10:91:11 | M8 | +| Switch.cs:95:18:95:20 | After access to type Int32 [match] | Switch.cs:91:10:91:11 | M8 | +| Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | Switch.cs:91:10:91:11 | M8 | | Switch.cs:95:18:95:20 | access to type Int32 | Switch.cs:91:10:91:11 | M8 | | Switch.cs:96:17:96:28 | Before return ...; | Switch.cs:91:10:91:11 | M8 | | Switch.cs:96:17:96:28 | return ...; | Switch.cs:91:10:91:11 | M8 | @@ -6421,6 +6471,8 @@ nodeEnclosing | Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:101:9:101:10 | M9 | | Switch.cs:105:13:105:19 | case ...: | Switch.cs:101:9:101:10 | M9 | | Switch.cs:105:18:105:18 | 0 | Switch.cs:101:9:101:10 | M9 | +| Switch.cs:105:18:105:18 | After 0 [match] | Switch.cs:101:9:101:10 | M9 | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:101:9:101:10 | M9 | | Switch.cs:105:21:105:29 | Before return ...; | Switch.cs:101:9:101:10 | M9 | | Switch.cs:105:21:105:29 | return ...; | Switch.cs:101:9:101:10 | M9 | | Switch.cs:105:28:105:28 | 0 | Switch.cs:101:9:101:10 | M9 | @@ -6428,6 +6480,8 @@ nodeEnclosing | Switch.cs:106:13:106:19 | After case ...: [no-match] | Switch.cs:101:9:101:10 | M9 | | Switch.cs:106:13:106:19 | case ...: | Switch.cs:101:9:101:10 | M9 | | Switch.cs:106:18:106:18 | 1 | Switch.cs:101:9:101:10 | M9 | +| Switch.cs:106:18:106:18 | After 1 [match] | Switch.cs:101:9:101:10 | M9 | +| Switch.cs:106:18:106:18 | After 1 [no-match] | Switch.cs:101:9:101:10 | M9 | | Switch.cs:106:21:106:29 | Before return ...; | Switch.cs:101:9:101:10 | M9 | | Switch.cs:106:21:106:29 | return ...; | Switch.cs:101:9:101:10 | M9 | | Switch.cs:106:28:106:28 | 1 | Switch.cs:101:9:101:10 | M9 | @@ -6460,6 +6514,8 @@ nodeEnclosing | Switch.cs:117:13:117:35 | After case ...: [no-match] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:117:13:117:35 | case ...: | Switch.cs:113:9:113:11 | M10 | | Switch.cs:117:18:117:18 | 3 | Switch.cs:113:9:113:11 | M10 | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:113:9:113:11 | M10 | +| Switch.cs:117:18:117:18 | After 3 [no-match] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:113:9:113:11 | M10 | | Switch.cs:117:25:117:34 | ... == ... | Switch.cs:113:9:113:11 | M10 | | Switch.cs:117:25:117:34 | After ... == ... [false] | Switch.cs:113:9:113:11 | M10 | @@ -6473,6 +6529,8 @@ nodeEnclosing | Switch.cs:118:13:118:34 | After case ...: [no-match] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:113:9:113:11 | M10 | | Switch.cs:118:18:118:18 | 2 | Switch.cs:113:9:113:11 | M10 | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:113:9:113:11 | M10 | +| Switch.cs:118:18:118:18 | After 2 [no-match] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:113:9:113:11 | M10 | | Switch.cs:118:25:118:33 | ... == ... | Switch.cs:113:9:113:11 | M10 | | Switch.cs:118:25:118:33 | After ... == ... [false] | Switch.cs:113:9:113:11 | M10 | @@ -6500,11 +6558,14 @@ nodeEnclosing | Switch.cs:125:13:125:48 | ... switch { ... } | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | Switch.cs:123:10:123:12 | M11 | +| Switch.cs:125:24:125:29 | After Boolean b [match] | Switch.cs:123:10:123:12 | M11 | +| Switch.cs:125:24:125:29 | After Boolean b [no-match] | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:24:125:29 | Boolean b | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:24:125:34 | ... => ... | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:24:125:34 | After ... => ... [no-match] | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:123:10:123:12 | M11 | +| Switch.cs:125:37:125:37 | After _ [match] | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:37:125:37 | _ | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:37:125:46 | ... => ... | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:37:125:46 | After ... => ... [match] | Switch.cs:123:10:123:12 | M11 | @@ -6525,11 +6586,14 @@ nodeEnclosing | Switch.cs:131:17:131:53 | ... switch { ... } | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | Switch.cs:129:12:129:14 | M12 | +| Switch.cs:131:28:131:35 | After String s [match] | Switch.cs:129:12:129:14 | M12 | +| Switch.cs:131:28:131:35 | After String s [no-match] | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:28:131:35 | String s | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:28:131:40 | ... => ... | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:28:131:40 | After ... => ... [no-match] | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:129:12:129:14 | M12 | +| Switch.cs:131:43:131:43 | After _ [match] | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:43:131:43 | _ | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:43:131:51 | ... => ... | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:43:131:51 | After ... => ... [match] | Switch.cs:129:12:129:14 | M12 | @@ -6553,6 +6617,8 @@ nodeEnclosing | Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:134:9:134:11 | M13 | | Switch.cs:139:13:139:19 | case ...: | Switch.cs:134:9:134:11 | M13 | | Switch.cs:139:18:139:18 | 1 | Switch.cs:134:9:134:11 | M13 | +| Switch.cs:139:18:139:18 | After 1 [match] | Switch.cs:134:9:134:11 | M13 | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:134:9:134:11 | M13 | | Switch.cs:139:21:139:29 | Before return ...; | Switch.cs:134:9:134:11 | M13 | | Switch.cs:139:21:139:29 | return ...; | Switch.cs:134:9:134:11 | M13 | | Switch.cs:139:28:139:28 | 1 | Switch.cs:134:9:134:11 | M13 | @@ -6560,6 +6626,8 @@ nodeEnclosing | Switch.cs:140:13:140:19 | After case ...: [no-match] | Switch.cs:134:9:134:11 | M13 | | Switch.cs:140:13:140:19 | case ...: | Switch.cs:134:9:134:11 | M13 | | Switch.cs:140:18:140:18 | 2 | Switch.cs:134:9:134:11 | M13 | +| Switch.cs:140:18:140:18 | After 2 [match] | Switch.cs:134:9:134:11 | M13 | +| Switch.cs:140:18:140:18 | After 2 [no-match] | Switch.cs:134:9:134:11 | M13 | | Switch.cs:140:21:140:29 | Before return ...; | Switch.cs:134:9:134:11 | M13 | | Switch.cs:140:21:140:29 | return ...; | Switch.cs:134:9:134:11 | M13 | | Switch.cs:140:28:140:28 | 2 | Switch.cs:134:9:134:11 | M13 | @@ -6574,6 +6642,8 @@ nodeEnclosing | Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:144:9:144:11 | M14 | | Switch.cs:148:13:148:19 | case ...: | Switch.cs:144:9:144:11 | M14 | | Switch.cs:148:18:148:18 | 1 | Switch.cs:144:9:144:11 | M14 | +| Switch.cs:148:18:148:18 | After 1 [match] | Switch.cs:144:9:144:11 | M14 | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:144:9:144:11 | M14 | | Switch.cs:148:21:148:29 | Before return ...; | Switch.cs:144:9:144:11 | M14 | | Switch.cs:148:21:148:29 | return ...; | Switch.cs:144:9:144:11 | M14 | | Switch.cs:148:28:148:28 | 1 | Switch.cs:144:9:144:11 | M14 | @@ -6589,6 +6659,8 @@ nodeEnclosing | Switch.cs:150:13:150:19 | After case ...: [no-match] | Switch.cs:144:9:144:11 | M14 | | Switch.cs:150:13:150:19 | case ...: | Switch.cs:144:9:144:11 | M14 | | Switch.cs:150:18:150:18 | 2 | Switch.cs:144:9:144:11 | M14 | +| Switch.cs:150:18:150:18 | After 2 [match] | Switch.cs:144:9:144:11 | M14 | +| Switch.cs:150:18:150:18 | After 2 [no-match] | Switch.cs:144:9:144:11 | M14 | | Switch.cs:150:21:150:29 | Before return ...; | Switch.cs:144:9:144:11 | M14 | | Switch.cs:150:21:150:29 | return ...; | Switch.cs:144:9:144:11 | M14 | | Switch.cs:150:28:150:28 | 2 | Switch.cs:144:9:144:11 | M14 | @@ -6607,11 +6679,15 @@ nodeEnclosing | Switch.cs:156:17:156:17 | access to parameter b | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:154:10:154:12 | M15 | +| Switch.cs:156:28:156:31 | After true [match] | Switch.cs:154:10:154:12 | M15 | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:28:156:31 | true | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:28:156:38 | ... => ... | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:36:156:38 | "a" | Switch.cs:154:10:154:12 | M15 | +| Switch.cs:156:41:156:45 | After false [match] | Switch.cs:154:10:154:12 | M15 | +| Switch.cs:156:41:156:45 | After false [no-match] | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:41:156:45 | false | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:41:156:52 | ... => ... | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:154:10:154:12 | M15 | @@ -6661,10 +6737,14 @@ nodeEnclosing | Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:163:10:163:12 | M16 | | Switch.cs:167:13:167:19 | case ...: | Switch.cs:163:10:163:12 | M16 | | Switch.cs:167:18:167:18 | 1 | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:167:18:167:18 | After 1 [match] | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:163:10:163:12 | M16 | | Switch.cs:168:13:168:19 | After case ...: [match] | Switch.cs:163:10:163:12 | M16 | | Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:163:10:163:12 | M16 | | Switch.cs:168:13:168:19 | case ...: | Switch.cs:163:10:163:12 | M16 | | Switch.cs:168:18:168:18 | 2 | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:168:18:168:18 | After 2 [match] | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:163:10:163:12 | M16 | | Switch.cs:169:17:169:50 | After call to method WriteLine | Switch.cs:163:10:163:12 | M16 | | Switch.cs:169:17:169:50 | Before call to method WriteLine | Switch.cs:163:10:163:12 | M16 | | Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:163:10:163:12 | M16 | @@ -6677,6 +6757,8 @@ nodeEnclosing | Switch.cs:171:13:171:19 | After case ...: [no-match] | Switch.cs:163:10:163:12 | M16 | | Switch.cs:171:13:171:19 | case ...: | Switch.cs:163:10:163:12 | M16 | | Switch.cs:171:18:171:18 | 3 | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:171:18:171:18 | After 3 [match] | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:171:18:171:18 | After 3 [no-match] | Switch.cs:163:10:163:12 | M16 | | Switch.cs:172:17:172:45 | After call to method WriteLine | Switch.cs:163:10:163:12 | M16 | | Switch.cs:172:17:172:45 | Before call to method WriteLine | Switch.cs:163:10:163:12 | M16 | | Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:163:10:163:12 | M16 | @@ -7067,6 +7149,8 @@ nodeEnclosing | cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:41:13:41:19 | case ...: | cflow.cs:37:17:37:22 | Switch | | cflow.cs:41:18:41:18 | 1 | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:41:18:41:18 | After 1 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:42:17:42:38 | After call to method WriteLine | cflow.cs:37:17:37:22 | Switch | | cflow.cs:42:17:42:38 | Before call to method WriteLine | cflow.cs:37:17:37:22 | Switch | | cflow.cs:42:17:42:38 | call to method WriteLine | cflow.cs:37:17:37:22 | Switch | @@ -7080,6 +7164,8 @@ nodeEnclosing | cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:44:13:44:19 | case ...: | cflow.cs:37:17:37:22 | Switch | | cflow.cs:44:18:44:18 | 2 | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:44:18:44:18 | After 2 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:45:17:45:38 | After call to method WriteLine | cflow.cs:37:17:37:22 | Switch | | cflow.cs:45:17:45:38 | Before call to method WriteLine | cflow.cs:37:17:37:22 | Switch | | cflow.cs:45:17:45:38 | call to method WriteLine | cflow.cs:37:17:37:22 | Switch | @@ -7093,6 +7179,8 @@ nodeEnclosing | cflow.cs:47:13:47:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:47:13:47:19 | case ...: | cflow.cs:37:17:37:22 | Switch | | cflow.cs:47:18:47:18 | 3 | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:47:18:47:18 | After 3 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:47:18:47:18 | After 3 [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:48:17:48:38 | After call to method WriteLine | cflow.cs:37:17:37:22 | Switch | | cflow.cs:48:17:48:38 | Before call to method WriteLine | cflow.cs:37:17:37:22 | Switch | | cflow.cs:48:17:48:38 | call to method WriteLine | cflow.cs:37:17:37:22 | Switch | @@ -7108,6 +7196,8 @@ nodeEnclosing | cflow.cs:53:13:53:20 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:53:13:53:20 | case ...: | cflow.cs:37:17:37:22 | Switch | | cflow.cs:53:18:53:19 | 42 | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:53:18:53:19 | After 42 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:53:18:53:19 | After 42 [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:54:17:54:47 | After call to method WriteLine | cflow.cs:37:17:37:22 | Switch | | cflow.cs:54:17:54:47 | Before call to method WriteLine | cflow.cs:37:17:37:22 | Switch | | cflow.cs:54:17:54:47 | call to method WriteLine | cflow.cs:37:17:37:22 | Switch | @@ -7139,6 +7229,8 @@ nodeEnclosing | cflow.cs:62:13:62:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:62:13:62:19 | case ...: | cflow.cs:37:17:37:22 | Switch | | cflow.cs:62:18:62:18 | 0 | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:62:18:62:18 | After 0 [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:63:17:64:55 | After if (...) ... | cflow.cs:37:17:37:22 | Switch | | cflow.cs:63:17:64:55 | if (...) ... | cflow.cs:37:17:37:22 | Switch | | cflow.cs:63:21:63:34 | !... | cflow.cs:37:17:37:22 | Switch | @@ -8075,12 +8167,16 @@ nodeEnclosing | cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:248:13:248:19 | case ...: | cflow.cs:240:10:240:13 | Goto | | cflow.cs:248:18:248:18 | 0 | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:248:18:248:18 | After 0 [match] | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:249:17:249:29 | Before goto default; | cflow.cs:240:10:240:13 | Goto | | cflow.cs:249:17:249:29 | goto default; | cflow.cs:240:10:240:13 | Goto | | cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:250:13:250:19 | case ...: | cflow.cs:240:10:240:13 | Goto | | cflow.cs:250:18:250:18 | 1 | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:250:18:250:18 | After 1 [match] | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:251:17:251:36 | After call to method WriteLine | cflow.cs:240:10:240:13 | Goto | | cflow.cs:251:17:251:36 | Before call to method WriteLine | cflow.cs:240:10:240:13 | Goto | | cflow.cs:251:17:251:36 | call to method WriteLine | cflow.cs:240:10:240:13 | Goto | @@ -8093,6 +8189,8 @@ nodeEnclosing | cflow.cs:253:13:253:19 | After case ...: [no-match] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:253:13:253:19 | case ...: | cflow.cs:240:10:240:13 | Goto | | cflow.cs:253:18:253:18 | 2 | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:253:18:253:18 | After 2 [match] | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:253:18:253:18 | After 2 [no-match] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:254:17:254:27 | Before goto ...; | cflow.cs:240:10:240:13 | Goto | | cflow.cs:254:17:254:27 | goto ...; | cflow.cs:240:10:240:13 | Goto | | cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:240:10:240:13 | Goto | @@ -9204,19 +9302,19 @@ blockEnclosing | Patterns.cs:16:18:16:28 | After ... is ... [false] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:16:18:16:28 | [MatchTrue] ... is ... | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:22:13:22:23 | After case ...: [match] | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:24:13:24:36 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:22:18:22:22 | After "xyz" [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:24:30:24:35 | After ... > ... [false] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:24:30:24:35 | After ... > ... [true] | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:5:10:5:11 | M1 | -| Patterns.cs:33:13:33:24 | After case ...: [no-match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:27:18:27:23 | After Int32 i3 [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:30:18:30:26 | After String s2 [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:33:18:33:23 | After Object v2 [match] | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:33:18:33:23 | After Object v2 [no-match] | Patterns.cs:5:10:5:11 | M1 | | Patterns.cs:47:24:47:25 | Entry | Patterns.cs:47:24:47:25 | M2 | | Patterns.cs:48:9:48:20 | After ... is ... | Patterns.cs:47:24:47:25 | M2 | | Patterns.cs:48:9:48:20 | [MatchTrue] ... is ... | Patterns.cs:47:24:47:25 | M2 | @@ -9233,22 +9331,22 @@ blockEnclosing | Patterns.cs:54:9:54:37 | [MatchTrue] ... is ... | Patterns.cs:53:24:53:25 | M4 | | Patterns.cs:56:26:56:27 | Entry | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:56:26:56:27 | M5 | -| Patterns.cs:60:13:60:28 | After ... => ... [match] | Patterns.cs:56:26:56:27 | M5 | -| Patterns.cs:60:13:60:28 | After ... => ... [no-match] | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:13:60:17 | After not ... [match] | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:13:60:17 | After not ... [no-match] | Patterns.cs:56:26:56:27 | M5 | | Patterns.cs:65:26:65:27 | Entry | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:65:26:65:27 | M6 | -| Patterns.cs:69:13:69:33 | After ... => ... [match] | Patterns.cs:65:26:65:27 | M6 | -| Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:65:26:65:27 | M6 | -| Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:65:26:65:27 | M6 | -| Patterns.cs:70:13:70:27 | After ... => ... [no-match] | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:69:13:69:17 | After not ... [match] | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:70:13:70:13 | After 2 [match] | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:70:13:70:13 | After 2 [no-match] | Patterns.cs:65:26:65:27 | M6 | | Patterns.cs:74:26:74:27 | Entry | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:74:26:74:27 | M7 | -| Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:74:26:74:27 | M7 | -| Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:74:26:74:27 | M7 | -| Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:74:26:74:27 | M7 | -| Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:74:26:74:27 | M7 | -| Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:74:26:74:27 | M7 | -| Patterns.cs:80:13:80:20 | After ... => ... [no-match] | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:78:13:78:15 | After > ... [match] | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:13:79:15 | After < ... [match] | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:80:13:80:13 | After 1 [match] | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:80:13:80:13 | After 1 [no-match] | Patterns.cs:74:26:74:27 | M7 | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:26:85:27 | M8 | | Patterns.cs:85:39:85:53 | After ... is ... [false] | Patterns.cs:85:26:85:27 | M8 | | Patterns.cs:85:39:85:53 | [MatchTrue] ... is ... | Patterns.cs:85:26:85:27 | M8 | @@ -9281,125 +9379,126 @@ blockEnclosing | Switch.cs:10:10:10:11 | Exceptional Exit | Switch.cs:10:10:10:11 | M2 | | Switch.cs:10:10:10:11 | Exit | Switch.cs:10:10:10:11 | M2 | | Switch.cs:10:10:10:11 | Normal Exit | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:14:13:14:21 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:14:18:14:20 | After "a" [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:16:18:16:18 | After 0 [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:18:18:18:21 | After null [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:21:21:21:29 | After ... == ... [false] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:21:21:21:29 | After ... == ... [true] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:24:13:24:56 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:24:18:24:25 | After String s [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:32:24:43 | After ... > ... [false] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:32:24:43 | After ... > ... [true] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:32:24:55 | After ... && ... [false] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:48:24:55 | After ... != ... [false] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:24:48:24:55 | After ... != ... [true] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:10:10:10:11 | M2 | -| Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:27:13:27:39 | case ...: | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:27:18:27:25 | After Double d [match] | Switch.cs:10:10:10:11 | M2 | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:30:13:30:20 | After default: [match] | Switch.cs:10:10:10:11 | M2 | | Switch.cs:35:10:35:11 | Entry | Switch.cs:35:10:35:11 | M3 | | Switch.cs:44:10:44:11 | Entry | Switch.cs:44:10:44:11 | M4 | | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:44:10:44:11 | M4 | -| Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:44:10:44:11 | M4 | -| Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:44:10:44:11 | M4 | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:44:10:44:11 | M4 | -| Switch.cs:50:13:50:39 | After case ...: [no-match] | Switch.cs:44:10:44:11 | M4 | +| Switch.cs:48:18:48:20 | After access to type Int32 [match] | Switch.cs:44:10:44:11 | M4 | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:44:10:44:11 | M4 | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:44:10:44:11 | M4 | +| Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | Switch.cs:44:10:44:11 | M4 | | Switch.cs:50:30:50:38 | After ... != ... [false] | Switch.cs:44:10:44:11 | M4 | | Switch.cs:50:30:50:38 | After ... != ... [true] | Switch.cs:44:10:44:11 | M4 | | Switch.cs:55:10:55:11 | Entry | Switch.cs:55:10:55:11 | M5 | | Switch.cs:57:9:63:9 | After switch (...) {...} | Switch.cs:55:10:55:11 | M5 | -| Switch.cs:59:13:59:19 | After case ...: [match] | Switch.cs:55:10:55:11 | M5 | -| Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:55:10:55:11 | M5 | -| Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:55:10:55:11 | M5 | -| Switch.cs:61:13:61:19 | After case ...: [no-match] | Switch.cs:55:10:55:11 | M5 | +| Switch.cs:59:18:59:18 | After 2 [match] | Switch.cs:55:10:55:11 | M5 | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:55:10:55:11 | M5 | +| Switch.cs:61:18:61:18 | After 3 [match] | Switch.cs:55:10:55:11 | M5 | +| Switch.cs:61:18:61:18 | After 3 [no-match] | Switch.cs:55:10:55:11 | M5 | | Switch.cs:66:10:66:11 | Entry | Switch.cs:66:10:66:11 | M6 | | Switch.cs:68:9:74:9 | After switch (...) {...} | Switch.cs:66:10:66:11 | M6 | -| Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:66:10:66:11 | M6 | -| Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:66:10:66:11 | M6 | -| Switch.cs:72:13:72:20 | After case ...: [match] | Switch.cs:66:10:66:11 | M6 | -| Switch.cs:72:13:72:20 | After case ...: [no-match] | Switch.cs:66:10:66:11 | M6 | +| Switch.cs:70:18:70:20 | After access to type Int32 [match] | Switch.cs:66:10:66:11 | M6 | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:66:10:66:11 | M6 | +| Switch.cs:72:18:72:19 | After "" [match] | Switch.cs:66:10:66:11 | M6 | +| Switch.cs:72:18:72:19 | After "" [no-match] | Switch.cs:66:10:66:11 | M6 | | Switch.cs:77:10:77:11 | Entry | Switch.cs:77:10:77:11 | M7 | | Switch.cs:77:10:77:11 | Normal Exit | Switch.cs:77:10:77:11 | M7 | | Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:77:10:77:11 | M7 | -| Switch.cs:81:13:81:19 | After case ...: [match] | Switch.cs:77:10:77:11 | M7 | -| Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:77:10:77:11 | M7 | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:77:10:77:11 | M7 | -| Switch.cs:83:13:83:19 | After case ...: [no-match] | Switch.cs:77:10:77:11 | M7 | +| Switch.cs:81:18:81:18 | After 1 [match] | Switch.cs:77:10:77:11 | M7 | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:77:10:77:11 | M7 | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:77:10:77:11 | M7 | +| Switch.cs:83:18:83:18 | After 2 [no-match] | Switch.cs:77:10:77:11 | M7 | | Switch.cs:84:21:84:25 | After ... > ... [false] | Switch.cs:77:10:77:11 | M7 | | Switch.cs:84:21:84:25 | After ... > ... [true] | Switch.cs:77:10:77:11 | M7 | | Switch.cs:91:10:91:11 | Entry | Switch.cs:91:10:91:11 | M8 | | Switch.cs:91:10:91:11 | Normal Exit | Switch.cs:91:10:91:11 | M8 | -| Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:91:10:91:11 | M8 | -| Switch.cs:95:13:95:23 | After case ...: [no-match] | Switch.cs:91:10:91:11 | M8 | +| Switch.cs:95:18:95:20 | After access to type Int32 [match] | Switch.cs:91:10:91:11 | M8 | +| Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | Switch.cs:91:10:91:11 | M8 | | Switch.cs:101:9:101:10 | Entry | Switch.cs:101:9:101:10 | M9 | | Switch.cs:101:9:101:10 | Normal Exit | Switch.cs:101:9:101:10 | M9 | | Switch.cs:103:17:103:17 | After access to parameter s [non-null] | Switch.cs:101:9:101:10 | M9 | | Switch.cs:103:17:103:17 | After access to parameter s [null] | Switch.cs:101:9:101:10 | M9 | | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:101:9:101:10 | M9 | -| Switch.cs:105:13:105:19 | After case ...: [match] | Switch.cs:101:9:101:10 | M9 | -| Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:101:9:101:10 | M9 | -| Switch.cs:106:13:106:19 | After case ...: [match] | Switch.cs:101:9:101:10 | M9 | -| Switch.cs:106:13:106:19 | After case ...: [no-match] | Switch.cs:101:9:101:10 | M9 | +| Switch.cs:105:18:105:18 | After 0 [match] | Switch.cs:101:9:101:10 | M9 | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:101:9:101:10 | M9 | +| Switch.cs:106:18:106:18 | After 1 [match] | Switch.cs:101:9:101:10 | M9 | +| Switch.cs:106:18:106:18 | After 1 [no-match] | Switch.cs:101:9:101:10 | M9 | | Switch.cs:111:17:111:21 | Entry | Switch.cs:111:17:111:21 | Throw | | Switch.cs:113:9:113:11 | Entry | Switch.cs:113:9:113:11 | M10 | | Switch.cs:113:9:113:11 | Normal Exit | Switch.cs:113:9:113:11 | M10 | | Switch.cs:115:9:119:9 | After switch (...) {...} | Switch.cs:113:9:113:11 | M10 | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:113:9:113:11 | M10 | -| Switch.cs:117:13:117:35 | After case ...: [no-match] | Switch.cs:113:9:113:11 | M10 | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:113:9:113:11 | M10 | +| Switch.cs:117:18:117:18 | After 3 [no-match] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:117:25:117:34 | After ... == ... [false] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:117:25:117:34 | After ... == ... [true] | Switch.cs:113:9:113:11 | M10 | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:113:9:113:11 | M10 | -| Switch.cs:118:13:118:34 | After case ...: [no-match] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:118:13:118:34 | case ...: | Switch.cs:113:9:113:11 | M10 | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:113:9:113:11 | M10 | +| Switch.cs:118:18:118:18 | After 2 [no-match] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:118:25:118:33 | After ... == ... [false] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:118:25:118:33 | After ... == ... [true] | Switch.cs:113:9:113:11 | M10 | | Switch.cs:123:10:123:12 | Entry | Switch.cs:123:10:123:12 | M11 | | Switch.cs:123:10:123:12 | Normal Exit | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | Switch.cs:123:10:123:12 | M11 | | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | Switch.cs:123:10:123:12 | M11 | -| Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:123:10:123:12 | M11 | -| Switch.cs:125:24:125:34 | After ... => ... [no-match] | Switch.cs:123:10:123:12 | M11 | +| Switch.cs:125:24:125:29 | After Boolean b [match] | Switch.cs:123:10:123:12 | M11 | +| Switch.cs:125:24:125:29 | After Boolean b [no-match] | Switch.cs:123:10:123:12 | M11 | | Switch.cs:129:12:129:14 | Entry | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:16:131:66 | After call to method ToString | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | Switch.cs:129:12:129:14 | M12 | | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | Switch.cs:129:12:129:14 | M12 | -| Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:129:12:129:14 | M12 | -| Switch.cs:131:28:131:40 | After ... => ... [no-match] | Switch.cs:129:12:129:14 | M12 | +| Switch.cs:131:28:131:35 | After String s [match] | Switch.cs:129:12:129:14 | M12 | +| Switch.cs:131:28:131:35 | After String s [no-match] | Switch.cs:129:12:129:14 | M12 | | Switch.cs:134:9:134:11 | Entry | Switch.cs:134:9:134:11 | M13 | | Switch.cs:134:9:134:11 | Normal Exit | Switch.cs:134:9:134:11 | M13 | -| Switch.cs:139:13:139:19 | After case ...: [match] | Switch.cs:134:9:134:11 | M13 | -| Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:134:9:134:11 | M13 | -| Switch.cs:140:13:140:19 | After case ...: [match] | Switch.cs:134:9:134:11 | M13 | -| Switch.cs:140:13:140:19 | After case ...: [no-match] | Switch.cs:134:9:134:11 | M13 | +| Switch.cs:139:18:139:18 | After 1 [match] | Switch.cs:134:9:134:11 | M13 | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:134:9:134:11 | M13 | +| Switch.cs:140:18:140:18 | After 2 [match] | Switch.cs:134:9:134:11 | M13 | +| Switch.cs:140:18:140:18 | After 2 [no-match] | Switch.cs:134:9:134:11 | M13 | | Switch.cs:144:9:144:11 | Entry | Switch.cs:144:9:144:11 | M14 | | Switch.cs:144:9:144:11 | Normal Exit | Switch.cs:144:9:144:11 | M14 | -| Switch.cs:148:13:148:19 | After case ...: [match] | Switch.cs:144:9:144:11 | M14 | -| Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:144:9:144:11 | M14 | -| Switch.cs:150:13:150:19 | After case ...: [match] | Switch.cs:144:9:144:11 | M14 | -| Switch.cs:150:13:150:19 | After case ...: [no-match] | Switch.cs:144:9:144:11 | M14 | +| Switch.cs:148:18:148:18 | After 1 [match] | Switch.cs:144:9:144:11 | M14 | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:144:9:144:11 | M14 | +| Switch.cs:150:18:150:18 | After 2 [match] | Switch.cs:144:9:144:11 | M14 | +| Switch.cs:150:18:150:18 | After 2 [no-match] | Switch.cs:144:9:144:11 | M14 | | Switch.cs:154:10:154:12 | Entry | Switch.cs:154:10:154:12 | M15 | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:154:10:154:12 | M15 | -| Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:154:10:154:12 | M15 | -| Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:154:10:154:12 | M15 | -| Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:154:10:154:12 | M15 | -| Switch.cs:156:41:156:52 | After ... => ... [no-match] | Switch.cs:154:10:154:12 | M15 | +| Switch.cs:156:28:156:31 | After true [match] | Switch.cs:154:10:154:12 | M15 | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:154:10:154:12 | M15 | +| Switch.cs:156:41:156:45 | After false [match] | Switch.cs:154:10:154:12 | M15 | +| Switch.cs:156:41:156:45 | After false [no-match] | Switch.cs:154:10:154:12 | M15 | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:154:10:154:12 | M15 | | Switch.cs:157:13:157:13 | After access to parameter b [false] | Switch.cs:154:10:154:12 | M15 | | Switch.cs:157:13:157:13 | After access to parameter b [true] | Switch.cs:154:10:154:12 | M15 | | Switch.cs:163:10:163:12 | Entry | Switch.cs:163:10:163:12 | M16 | | Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:163:10:163:12 | M16 | -| Switch.cs:167:13:167:19 | After case ...: [match] | Switch.cs:163:10:163:12 | M16 | -| Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:163:10:163:12 | M16 | -| Switch.cs:168:13:168:19 | After case ...: [match] | Switch.cs:163:10:163:12 | M16 | -| Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:167:18:167:18 | After 1 [match] | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:168:18:168:18 | After 2 [match] | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:163:10:163:12 | M16 | | Switch.cs:169:17:169:51 | ...; | Switch.cs:163:10:163:12 | M16 | -| Switch.cs:171:13:171:19 | After case ...: [match] | Switch.cs:163:10:163:12 | M16 | -| Switch.cs:171:13:171:19 | After case ...: [no-match] | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:171:18:171:18 | After 3 [match] | Switch.cs:163:10:163:12 | M16 | +| Switch.cs:171:18:171:18 | After 3 [no-match] | Switch.cs:163:10:163:12 | M16 | | TypeAccesses.cs:1:7:1:18 | Entry | TypeAccesses.cs:1:7:1:18 | TypeAccesses | | TypeAccesses.cs:3:10:3:10 | Entry | TypeAccesses.cs:3:10:3:10 | M | | TypeAccesses.cs:7:9:7:25 | After if (...) ... | TypeAccesses.cs:3:10:3:10 | M | @@ -9443,17 +9542,19 @@ blockEnclosing | cflow.cs:37:17:37:22 | Exit | cflow.cs:37:17:37:22 | Switch | | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:37:17:37:22 | Switch | | cflow.cs:41:13:41:19 | After case ...: [match] | cflow.cs:37:17:37:22 | Switch | -| cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:41:18:41:18 | After 1 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:44:13:44:19 | After case ...: [match] | cflow.cs:37:17:37:22 | Switch | -| cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | -| cflow.cs:47:13:47:19 | After case ...: [match] | cflow.cs:37:17:37:22 | Switch | -| cflow.cs:47:13:47:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:44:18:44:18 | After 2 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:47:18:47:18 | After 3 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:47:18:47:18 | After 3 [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:37:17:37:22 | Switch | -| cflow.cs:53:13:53:20 | After case ...: [match] | cflow.cs:37:17:37:22 | Switch | -| cflow.cs:53:13:53:20 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:53:18:53:19 | After 42 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:53:18:53:19 | After 42 [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:60:9:66:9 | After switch (...) {...} | cflow.cs:37:17:37:22 | Switch | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:37:17:37:22 | Switch | -| cflow.cs:62:13:62:19 | After case ...: [no-match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:37:17:37:22 | Switch | +| cflow.cs:62:18:62:18 | After 0 [no-match] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:63:23:63:33 | After ... == ... [false] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:63:23:63:33 | After ... == ... [true] | cflow.cs:37:17:37:22 | Switch | | cflow.cs:70:18:70:18 | Entry | cflow.cs:70:18:70:18 | M | @@ -9578,12 +9679,12 @@ blockEnclosing | cflow.cs:244:13:244:28 | After ... > ... [false] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:244:13:244:28 | After ... > ... [true] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:246:9:258:9 | After switch (...) {...} | cflow.cs:240:10:240:13 | Goto | -| cflow.cs:248:13:248:19 | After case ...: [match] | cflow.cs:240:10:240:13 | Goto | -| cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:240:10:240:13 | Goto | -| cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:240:10:240:13 | Goto | -| cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:240:10:240:13 | Goto | -| cflow.cs:253:13:253:19 | After case ...: [match] | cflow.cs:240:10:240:13 | Goto | -| cflow.cs:253:13:253:19 | After case ...: [no-match] | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:248:18:248:18 | After 0 [match] | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:250:18:250:18 | After 1 [match] | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:253:18:253:18 | After 2 [match] | cflow.cs:240:10:240:13 | Goto | +| cflow.cs:253:18:253:18 | After 2 [no-match] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:240:10:240:13 | Goto | | cflow.cs:261:49:261:53 | Entry | cflow.cs:261:49:261:53 | Yield | | cflow.cs:261:49:261:53 | Exceptional Exit | cflow.cs:261:49:261:53 | Yield | diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected index f9619e825cc..da56986ea09 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected @@ -5714,18 +5714,22 @@ | Patterns.cs:20:9:38:9 | After switch (...) {...} | Patterns.cs:40:9:42:9 | switch (...) {...} | | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:20:17:20:17 | access to local variable o | | | Patterns.cs:20:17:20:17 | access to local variable o | Patterns.cs:22:13:22:23 | case ...: | | -| Patterns.cs:22:13:22:23 | After case ...: [match] | Patterns.cs:22:18:22:22 | "xyz" | | +| Patterns.cs:22:13:22:23 | After case ...: [match] | Patterns.cs:23:17:23:22 | Before break; | | | Patterns.cs:22:13:22:23 | After case ...: [no-match] | Patterns.cs:24:13:24:36 | case ...: | | -| Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:22:13:22:23 | After case ...: [match] | match | -| Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:22:13:22:23 | After case ...: [no-match] | no-match | -| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:23:17:23:22 | Before break; | | +| Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:22:18:22:22 | "xyz" | | +| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:22:18:22:22 | After "xyz" [match] | match | +| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:22:18:22:22 | After "xyz" [no-match] | no-match | +| Patterns.cs:22:18:22:22 | After "xyz" [match] | Patterns.cs:22:13:22:23 | After case ...: [match] | match | +| Patterns.cs:22:18:22:22 | After "xyz" [no-match] | Patterns.cs:22:13:22:23 | After case ...: [no-match] | no-match | | Patterns.cs:23:17:23:22 | Before break; | Patterns.cs:23:17:23:22 | break; | | | Patterns.cs:23:17:23:22 | break; | Patterns.cs:20:9:38:9 | After switch (...) {...} | break | -| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:18:24:23 | Int32 i2 | | +| Patterns.cs:24:13:24:36 | After case ...: [match] | Patterns.cs:24:30:24:35 | Before ... > ... | | | Patterns.cs:24:13:24:36 | After case ...: [no-match] | Patterns.cs:27:13:27:24 | case ...: | | -| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:24:13:24:36 | After case ...: [match] | match | -| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:24:13:24:36 | After case ...: [no-match] | no-match | -| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:24:30:24:35 | Before ... > ... | | +| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:24:18:24:23 | Int32 i2 | | +| Patterns.cs:24:18:24:23 | After Int32 i2 [match] | Patterns.cs:24:13:24:36 | After case ...: [match] | match | +| Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | Patterns.cs:24:13:24:36 | After case ...: [no-match] | no-match | +| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:24:18:24:23 | After Int32 i2 [match] | match | +| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:24:18:24:23 | After Int32 i2 [no-match] | no-match | | Patterns.cs:24:30:24:31 | access to local variable i2 | Patterns.cs:24:35:24:35 | 0 | | | Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:24:30:24:35 | After ... > ... [false] | false | | Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:24:30:24:35 | After ... > ... [true] | true | @@ -5748,11 +5752,13 @@ | Patterns.cs:25:47:25:48 | access to local variable i2 | Patterns.cs:25:46:25:49 | {...} | | | Patterns.cs:26:17:26:22 | Before break; | Patterns.cs:26:17:26:22 | break; | | | Patterns.cs:26:17:26:22 | break; | Patterns.cs:20:9:38:9 | After switch (...) {...} | break | -| Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:27:18:27:23 | Int32 i3 | | +| Patterns.cs:27:13:27:24 | After case ...: [match] | Patterns.cs:28:17:28:47 | ...; | | | Patterns.cs:27:13:27:24 | After case ...: [no-match] | Patterns.cs:30:13:30:27 | case ...: | | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | After case ...: [match] | match | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:13:27:24 | After case ...: [no-match] | no-match | -| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:28:17:28:47 | ...; | | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:27:18:27:23 | Int32 i3 | | +| Patterns.cs:27:18:27:23 | After Int32 i3 [match] | Patterns.cs:27:13:27:24 | After case ...: [match] | match | +| Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | Patterns.cs:27:13:27:24 | After case ...: [no-match] | no-match | +| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:27:18:27:23 | After Int32 i3 [match] | match | +| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:27:18:27:23 | After Int32 i3 [no-match] | no-match | | Patterns.cs:28:17:28:46 | After call to method WriteLine | Patterns.cs:28:17:28:47 | After ...; | | | Patterns.cs:28:17:28:46 | Before call to method WriteLine | Patterns.cs:28:35:28:45 | Before $"..." | | | Patterns.cs:28:17:28:46 | call to method WriteLine | Patterns.cs:28:17:28:46 | After call to method WriteLine | | @@ -5768,11 +5774,13 @@ | Patterns.cs:28:42:28:43 | access to local variable i3 | Patterns.cs:28:41:28:44 | {...} | | | Patterns.cs:29:17:29:22 | Before break; | Patterns.cs:29:17:29:22 | break; | | | Patterns.cs:29:17:29:22 | break; | Patterns.cs:20:9:38:9 | After switch (...) {...} | break | -| Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:30:18:30:26 | String s2 | | +| Patterns.cs:30:13:30:27 | After case ...: [match] | Patterns.cs:31:17:31:50 | ...; | | | Patterns.cs:30:13:30:27 | After case ...: [no-match] | Patterns.cs:33:13:33:24 | case ...: | | -| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:30:13:30:27 | After case ...: [match] | match | -| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:30:13:30:27 | After case ...: [no-match] | no-match | -| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:31:17:31:50 | ...; | | +| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:30:18:30:26 | String s2 | | +| Patterns.cs:30:18:30:26 | After String s2 [match] | Patterns.cs:30:13:30:27 | After case ...: [match] | match | +| Patterns.cs:30:18:30:26 | After String s2 [no-match] | Patterns.cs:30:13:30:27 | After case ...: [no-match] | no-match | +| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:30:18:30:26 | After String s2 [match] | match | +| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:30:18:30:26 | After String s2 [no-match] | no-match | | Patterns.cs:31:17:31:49 | After call to method WriteLine | Patterns.cs:31:17:31:50 | After ...; | | | Patterns.cs:31:17:31:49 | Before call to method WriteLine | Patterns.cs:31:35:31:48 | Before $"..." | | | Patterns.cs:31:17:31:49 | call to method WriteLine | Patterns.cs:31:17:31:49 | After call to method WriteLine | | @@ -5788,11 +5796,13 @@ | Patterns.cs:31:45:31:46 | access to local variable s2 | Patterns.cs:31:44:31:47 | {...} | | | Patterns.cs:32:17:32:22 | Before break; | Patterns.cs:32:17:32:22 | break; | | | Patterns.cs:32:17:32:22 | break; | Patterns.cs:20:9:38:9 | After switch (...) {...} | break | -| Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:33:18:33:23 | Object v2 | | +| Patterns.cs:33:13:33:24 | After case ...: [match] | Patterns.cs:34:17:34:22 | Before break; | | | Patterns.cs:33:13:33:24 | After case ...: [no-match] | Patterns.cs:35:13:35:20 | default: | | -| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:33:13:33:24 | After case ...: [match] | match | -| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:33:13:33:24 | After case ...: [no-match] | no-match | -| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:34:17:34:22 | Before break; | | +| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:33:18:33:23 | Object v2 | | +| Patterns.cs:33:18:33:23 | After Object v2 [match] | Patterns.cs:33:13:33:24 | After case ...: [match] | match | +| Patterns.cs:33:18:33:23 | After Object v2 [no-match] | Patterns.cs:33:13:33:24 | After case ...: [no-match] | no-match | +| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:33:18:33:23 | After Object v2 [match] | match | +| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:33:18:33:23 | After Object v2 [no-match] | no-match | | Patterns.cs:34:17:34:22 | Before break; | Patterns.cs:34:17:34:22 | break; | | | Patterns.cs:34:17:34:22 | break; | Patterns.cs:20:9:38:9 | After switch (...) {...} | break | | Patterns.cs:35:13:35:20 | After default: [match] | Patterns.cs:36:17:36:52 | ...; | | @@ -5881,18 +5891,20 @@ | Patterns.cs:58:16:58:16 | access to parameter i | Patterns.cs:60:13:60:28 | ... => ... | | | Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:58:16:58:16 | access to parameter i | | | Patterns.cs:58:16:62:9 | After ... switch { ... } | Patterns.cs:58:9:62:10 | return ...; | | -| Patterns.cs:60:13:60:17 | After not ... | Patterns.cs:60:22:60:28 | "not 1" | | +| Patterns.cs:60:13:60:17 | After not ... [match] | Patterns.cs:60:13:60:28 | After ... => ... [match] | match | +| Patterns.cs:60:13:60:17 | After not ... [no-match] | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | no-match | | Patterns.cs:60:13:60:17 | Before not ... | Patterns.cs:60:17:60:17 | 1 | | -| Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:13:60:17 | After not ... | | -| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:60:13:60:28 | After ... => ... [match] | match | -| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | no-match | -| Patterns.cs:60:13:60:28 | After ... => ... [match] | Patterns.cs:60:13:60:17 | Before not ... | | +| Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:13:60:17 | After not ... [match] | match | +| Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:13:60:17 | After not ... [no-match] | no-match | +| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:60:13:60:17 | Before not ... | | +| Patterns.cs:60:13:60:28 | After ... => ... [match] | Patterns.cs:60:22:60:28 | "not 1" | | | Patterns.cs:60:13:60:28 | After ... => ... [no-match] | Patterns.cs:61:13:61:24 | ... => ... | | | Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:13:60:17 | not ... | | | Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:58:16:62:9 | After ... switch { ... } | | -| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:18:61:24 | "other" | | -| Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:61:13:61:24 | After ... => ... [match] | match | -| Patterns.cs:61:13:61:24 | After ... => ... [match] | Patterns.cs:61:13:61:13 | _ | | +| Patterns.cs:61:13:61:13 | After _ [match] | Patterns.cs:61:13:61:24 | After ... => ... [match] | match | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:13:61:13 | After _ [match] | match | +| Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:61:13:61:13 | _ | | +| Patterns.cs:61:13:61:24 | After ... => ... [match] | Patterns.cs:61:18:61:24 | "other" | | | Patterns.cs:61:18:61:24 | "other" | Patterns.cs:58:16:62:9 | After ... switch { ... } | | | Patterns.cs:65:26:65:27 | Entry | Patterns.cs:66:5:72:5 | {...} | | | Patterns.cs:65:26:65:27 | Normal Exit | Patterns.cs:65:26:65:27 | Exit | | @@ -5902,19 +5914,22 @@ | Patterns.cs:67:16:67:16 | 2 | Patterns.cs:69:13:69:33 | ... => ... | | | Patterns.cs:67:16:71:9 | ... switch { ... } | Patterns.cs:67:16:67:16 | 2 | | | Patterns.cs:67:16:71:9 | After ... switch { ... } | Patterns.cs:67:9:71:10 | return ...; | | -| Patterns.cs:69:13:69:17 | After not ... | Patterns.cs:69:22:69:33 | "impossible" | | +| Patterns.cs:69:13:69:17 | After not ... [match] | Patterns.cs:69:13:69:33 | After ... => ... [match] | match | +| Patterns.cs:69:13:69:17 | After not ... [no-match] | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | no-match | | Patterns.cs:69:13:69:17 | Before not ... | Patterns.cs:69:17:69:17 | 2 | | -| Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:13:69:17 | After not ... | | -| Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:69:13:69:33 | After ... => ... [match] | match | -| Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | no-match | -| Patterns.cs:69:13:69:33 | After ... => ... [match] | Patterns.cs:69:13:69:17 | Before not ... | | +| Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:13:69:17 | After not ... [match] | match | +| Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:13:69:17 | After not ... [no-match] | no-match | +| Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:69:13:69:17 | Before not ... | | +| Patterns.cs:69:13:69:33 | After ... => ... [match] | Patterns.cs:69:22:69:33 | "impossible" | | | Patterns.cs:69:13:69:33 | After ... => ... [no-match] | Patterns.cs:70:13:70:27 | ... => ... | | | Patterns.cs:69:17:69:17 | 2 | Patterns.cs:69:13:69:17 | not ... | | | Patterns.cs:69:22:69:33 | "impossible" | Patterns.cs:67:16:71:9 | After ... switch { ... } | | -| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:18:70:27 | "possible" | | -| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:70:13:70:27 | After ... => ... [match] | match | -| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | no-match | -| Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:70:13:70:13 | 2 | | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:13 | After 2 [match] | match | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:13 | After 2 [no-match] | no-match | +| Patterns.cs:70:13:70:13 | After 2 [match] | Patterns.cs:70:13:70:27 | After ... => ... [match] | match | +| Patterns.cs:70:13:70:13 | After 2 [no-match] | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | no-match | +| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:70:13:70:13 | 2 | | +| Patterns.cs:70:13:70:27 | After ... => ... [match] | Patterns.cs:70:18:70:27 | "possible" | | | Patterns.cs:70:13:70:27 | After ... => ... [no-match] | Patterns.cs:67:16:71:9 | After ... switch { ... } | | | Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:67:16:71:9 | After ... switch { ... } | | | Patterns.cs:74:26:74:27 | Entry | Patterns.cs:74:33:74:33 | i | | @@ -5926,33 +5941,38 @@ | Patterns.cs:76:16:76:16 | access to parameter i | Patterns.cs:78:13:78:24 | ... => ... | | | Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:76:16:76:16 | access to parameter i | | | Patterns.cs:76:16:82:9 | After ... switch { ... } | Patterns.cs:76:9:82:10 | return ...; | | -| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:13:78:15 | After > ... | | -| Patterns.cs:78:13:78:15 | After > ... | Patterns.cs:78:20:78:24 | "> 1" | | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:13:78:15 | After > ... [match] | match | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:13:78:15 | After > ... [no-match] | no-match | +| Patterns.cs:78:13:78:15 | After > ... [match] | Patterns.cs:78:13:78:24 | After ... => ... [match] | match | +| Patterns.cs:78:13:78:15 | After > ... [no-match] | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | no-match | | Patterns.cs:78:13:78:15 | Before > ... | Patterns.cs:78:15:78:15 | 1 | | -| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:78:13:78:24 | After ... => ... [match] | match | -| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | no-match | -| Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:78:13:78:15 | Before > ... | | +| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:78:13:78:15 | Before > ... | | +| Patterns.cs:78:13:78:24 | After ... => ... [match] | Patterns.cs:78:20:78:24 | "> 1" | | | Patterns.cs:78:13:78:24 | After ... => ... [no-match] | Patterns.cs:79:13:79:24 | ... => ... | | | Patterns.cs:78:15:78:15 | 1 | Patterns.cs:78:13:78:15 | > ... | | | Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:76:16:82:9 | After ... switch { ... } | | -| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:13:79:15 | After < ... | | -| Patterns.cs:79:13:79:15 | After < ... | Patterns.cs:79:20:79:24 | "< 0" | | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:13:79:15 | After < ... [match] | match | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:13:79:15 | After < ... [no-match] | no-match | +| Patterns.cs:79:13:79:15 | After < ... [match] | Patterns.cs:79:13:79:24 | After ... => ... [match] | match | +| Patterns.cs:79:13:79:15 | After < ... [no-match] | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | no-match | | Patterns.cs:79:13:79:15 | Before < ... | Patterns.cs:79:15:79:15 | 0 | | -| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:79:13:79:24 | After ... => ... [match] | match | -| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | no-match | -| Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:79:13:79:15 | Before < ... | | +| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:79:13:79:15 | Before < ... | | +| Patterns.cs:79:13:79:24 | After ... => ... [match] | Patterns.cs:79:20:79:24 | "< 0" | | | Patterns.cs:79:13:79:24 | After ... => ... [no-match] | Patterns.cs:80:13:80:20 | ... => ... | | | Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:13:79:15 | < ... | | | Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:76:16:82:9 | After ... switch { ... } | | -| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:18:80:20 | "1" | | -| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:13:80:20 | After ... => ... [match] | match | -| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | no-match | -| Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:80:13:80:13 | 1 | | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | After 1 [match] | match | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | After 1 [no-match] | no-match | +| Patterns.cs:80:13:80:13 | After 1 [match] | Patterns.cs:80:13:80:20 | After ... => ... [match] | match | +| Patterns.cs:80:13:80:13 | After 1 [no-match] | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | no-match | +| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:13:80:13 | 1 | | +| Patterns.cs:80:13:80:20 | After ... => ... [match] | Patterns.cs:80:18:80:20 | "1" | | | Patterns.cs:80:13:80:20 | After ... => ... [no-match] | Patterns.cs:81:13:81:20 | ... => ... | | | Patterns.cs:80:18:80:20 | "1" | Patterns.cs:76:16:82:9 | After ... switch { ... } | | -| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" | | -| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:13:81:20 | After ... => ... [match] | match | -| Patterns.cs:81:13:81:20 | After ... => ... [match] | Patterns.cs:81:13:81:13 | _ | | +| Patterns.cs:81:13:81:13 | After _ [match] | Patterns.cs:81:13:81:20 | After ... => ... [match] | match | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | After _ [match] | match | +| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:13:81:13 | _ | | +| Patterns.cs:81:13:81:20 | After ... => ... [match] | Patterns.cs:81:18:81:20 | "0" | | | Patterns.cs:81:18:81:20 | "0" | Patterns.cs:76:16:82:9 | After ... switch { ... } | | | Patterns.cs:85:26:85:27 | Entry | Patterns.cs:85:33:85:33 | i | | | Patterns.cs:85:26:85:27 | Normal Exit | Patterns.cs:85:26:85:27 | Exit | | @@ -6291,35 +6311,43 @@ | Switch.cs:11:5:33:5 | {...} | Switch.cs:12:9:32:9 | switch (...) {...} | | | Switch.cs:12:9:32:9 | switch (...) {...} | Switch.cs:12:17:12:17 | access to parameter o | | | Switch.cs:12:17:12:17 | access to parameter o | Switch.cs:14:13:14:21 | case ...: | | -| Switch.cs:14:13:14:21 | After case ...: [match] | Switch.cs:14:18:14:20 | "a" | | +| Switch.cs:14:13:14:21 | After case ...: [match] | Switch.cs:15:17:15:23 | Before return ...; | | | Switch.cs:14:13:14:21 | After case ...: [no-match] | Switch.cs:16:13:16:19 | case ...: | | -| Switch.cs:14:13:14:21 | case ...: | Switch.cs:14:13:14:21 | After case ...: [match] | match | -| Switch.cs:14:13:14:21 | case ...: | Switch.cs:14:13:14:21 | After case ...: [no-match] | no-match | -| Switch.cs:14:18:14:20 | "a" | Switch.cs:15:17:15:23 | Before return ...; | | +| Switch.cs:14:13:14:21 | case ...: | Switch.cs:14:18:14:20 | "a" | | +| Switch.cs:14:18:14:20 | "a" | Switch.cs:14:18:14:20 | After "a" [match] | match | +| Switch.cs:14:18:14:20 | "a" | Switch.cs:14:18:14:20 | After "a" [no-match] | no-match | +| Switch.cs:14:18:14:20 | After "a" [match] | Switch.cs:14:13:14:21 | After case ...: [match] | match | +| Switch.cs:14:18:14:20 | After "a" [no-match] | Switch.cs:14:13:14:21 | After case ...: [no-match] | no-match | | Switch.cs:15:17:15:23 | Before return ...; | Switch.cs:15:17:15:23 | return ...; | | | Switch.cs:15:17:15:23 | return ...; | Switch.cs:10:10:10:11 | Normal Exit | return | -| Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:16:18:16:18 | 0 | | +| Switch.cs:16:13:16:19 | After case ...: [match] | Switch.cs:17:17:17:38 | Before throw ...; | | | Switch.cs:16:13:16:19 | After case ...: [no-match] | Switch.cs:18:13:18:22 | case ...: | | -| Switch.cs:16:13:16:19 | case ...: | Switch.cs:16:13:16:19 | After case ...: [match] | match | -| Switch.cs:16:13:16:19 | case ...: | Switch.cs:16:13:16:19 | After case ...: [no-match] | no-match | -| Switch.cs:16:18:16:18 | 0 | Switch.cs:17:17:17:38 | Before throw ...; | | +| Switch.cs:16:13:16:19 | case ...: | Switch.cs:16:18:16:18 | 0 | | +| Switch.cs:16:18:16:18 | 0 | Switch.cs:16:18:16:18 | After 0 [match] | match | +| Switch.cs:16:18:16:18 | 0 | Switch.cs:16:18:16:18 | After 0 [no-match] | no-match | +| Switch.cs:16:18:16:18 | After 0 [match] | Switch.cs:16:13:16:19 | After case ...: [match] | match | +| Switch.cs:16:18:16:18 | After 0 [no-match] | Switch.cs:16:13:16:19 | After case ...: [no-match] | no-match | | Switch.cs:17:17:17:38 | Before throw ...; | Switch.cs:17:23:17:37 | Before object creation of type Exception | | | Switch.cs:17:17:17:38 | throw ...; | Switch.cs:10:10:10:11 | Exceptional Exit | exception | | Switch.cs:17:23:17:37 | After object creation of type Exception | Switch.cs:17:17:17:38 | throw ...; | | | Switch.cs:17:23:17:37 | Before object creation of type Exception | Switch.cs:17:23:17:37 | object creation of type Exception | | | Switch.cs:17:23:17:37 | object creation of type Exception | Switch.cs:17:23:17:37 | After object creation of type Exception | | -| Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:18:18:18:21 | null | | +| Switch.cs:18:13:18:22 | After case ...: [match] | Switch.cs:19:17:19:29 | Before goto default; | | | Switch.cs:18:13:18:22 | After case ...: [no-match] | Switch.cs:20:13:20:23 | case ...: | | -| Switch.cs:18:13:18:22 | case ...: | Switch.cs:18:13:18:22 | After case ...: [match] | match | -| Switch.cs:18:13:18:22 | case ...: | Switch.cs:18:13:18:22 | After case ...: [no-match] | no-match | -| Switch.cs:18:18:18:21 | null | Switch.cs:19:17:19:29 | Before goto default; | | +| Switch.cs:18:13:18:22 | case ...: | Switch.cs:18:18:18:21 | null | | +| Switch.cs:18:18:18:21 | After null [match] | Switch.cs:18:13:18:22 | After case ...: [match] | match | +| Switch.cs:18:18:18:21 | After null [no-match] | Switch.cs:18:13:18:22 | After case ...: [no-match] | no-match | +| Switch.cs:18:18:18:21 | null | Switch.cs:18:18:18:21 | After null [match] | match | +| Switch.cs:18:18:18:21 | null | Switch.cs:18:18:18:21 | After null [no-match] | no-match | | Switch.cs:19:17:19:29 | Before goto default; | Switch.cs:19:17:19:29 | goto default; | | | Switch.cs:19:17:19:29 | goto default; | Switch.cs:30:13:30:20 | After default: [match] | goto | -| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:20:18:20:22 | Int32 i | | +| Switch.cs:20:13:20:23 | After case ...: [match] | Switch.cs:21:17:22:27 | if (...) ... | | | Switch.cs:20:13:20:23 | After case ...: [no-match] | Switch.cs:24:13:24:56 | case ...: | | -| Switch.cs:20:13:20:23 | case ...: | Switch.cs:20:13:20:23 | After case ...: [match] | match | -| Switch.cs:20:13:20:23 | case ...: | Switch.cs:20:13:20:23 | After case ...: [no-match] | no-match | -| Switch.cs:20:18:20:22 | Int32 i | Switch.cs:21:17:22:27 | if (...) ... | | +| Switch.cs:20:13:20:23 | case ...: | Switch.cs:20:18:20:22 | Int32 i | | +| Switch.cs:20:18:20:22 | After Int32 i [match] | Switch.cs:20:13:20:23 | After case ...: [match] | match | +| Switch.cs:20:18:20:22 | After Int32 i [no-match] | Switch.cs:20:13:20:23 | After case ...: [no-match] | no-match | +| Switch.cs:20:18:20:22 | Int32 i | Switch.cs:20:18:20:22 | After Int32 i [match] | match | +| Switch.cs:20:18:20:22 | Int32 i | Switch.cs:20:18:20:22 | After Int32 i [no-match] | no-match | | Switch.cs:21:17:22:27 | After if (...) ... | Switch.cs:23:17:23:28 | Before goto case ...; | | | Switch.cs:21:17:22:27 | if (...) ... | Switch.cs:21:21:21:29 | Before ... == ... | | | Switch.cs:21:21:21:21 | access to parameter o | Switch.cs:21:26:21:29 | null | | @@ -6334,11 +6362,13 @@ | Switch.cs:23:17:23:28 | Before goto case ...; | Switch.cs:23:27:23:27 | 0 | | | Switch.cs:23:17:23:28 | goto case ...; | Switch.cs:16:13:16:19 | After case ...: [match] | goto | | Switch.cs:23:27:23:27 | 0 | Switch.cs:23:17:23:28 | goto case ...; | | -| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:18:24:25 | String s | | +| Switch.cs:24:13:24:56 | After case ...: [match] | Switch.cs:24:32:24:55 | ... && ... | | | Switch.cs:24:13:24:56 | After case ...: [no-match] | Switch.cs:27:13:27:39 | case ...: | | -| Switch.cs:24:13:24:56 | case ...: | Switch.cs:24:13:24:56 | After case ...: [match] | match | -| Switch.cs:24:13:24:56 | case ...: | Switch.cs:24:13:24:56 | After case ...: [no-match] | no-match | -| Switch.cs:24:18:24:25 | String s | Switch.cs:24:32:24:55 | ... && ... | | +| Switch.cs:24:13:24:56 | case ...: | Switch.cs:24:18:24:25 | String s | | +| Switch.cs:24:18:24:25 | After String s [match] | Switch.cs:24:13:24:56 | After case ...: [match] | match | +| Switch.cs:24:18:24:25 | After String s [no-match] | Switch.cs:24:13:24:56 | After case ...: [no-match] | no-match | +| Switch.cs:24:18:24:25 | String s | Switch.cs:24:18:24:25 | After String s [match] | match | +| Switch.cs:24:18:24:25 | String s | Switch.cs:24:18:24:25 | After String s [no-match] | no-match | | Switch.cs:24:32:24:32 | access to local variable s | Switch.cs:24:32:24:39 | access to property Length | | | Switch.cs:24:32:24:39 | After access to property Length | Switch.cs:24:43:24:43 | 0 | | | Switch.cs:24:32:24:39 | Before access to property Length | Switch.cs:24:32:24:32 | access to local variable s | | @@ -6367,11 +6397,13 @@ | Switch.cs:25:35:25:35 | access to local variable s | Switch.cs:25:17:25:36 | call to method WriteLine | | | Switch.cs:26:17:26:23 | Before return ...; | Switch.cs:26:17:26:23 | return ...; | | | Switch.cs:26:17:26:23 | return ...; | Switch.cs:10:10:10:11 | Normal Exit | return | -| Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:27:18:27:25 | Double d | | +| Switch.cs:27:13:27:39 | After case ...: [match] | Switch.cs:27:32:27:38 | Before call to method Throw | | | Switch.cs:27:13:27:39 | After case ...: [no-match] | Switch.cs:30:13:30:20 | default: | | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | After case ...: [match] | match | -| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:13:27:39 | After case ...: [no-match] | no-match | -| Switch.cs:27:18:27:25 | Double d | Switch.cs:27:32:27:38 | Before call to method Throw | | +| Switch.cs:27:13:27:39 | case ...: | Switch.cs:27:18:27:25 | Double d | | +| Switch.cs:27:18:27:25 | After Double d [match] | Switch.cs:27:13:27:39 | After case ...: [match] | match | +| Switch.cs:27:18:27:25 | After Double d [no-match] | Switch.cs:27:13:27:39 | After case ...: [no-match] | no-match | +| Switch.cs:27:18:27:25 | Double d | Switch.cs:27:18:27:25 | After Double d [match] | match | +| Switch.cs:27:18:27:25 | Double d | Switch.cs:27:18:27:25 | After Double d [no-match] | no-match | | Switch.cs:27:32:27:38 | Before call to method Throw | Switch.cs:27:32:27:38 | call to method Throw | | | Switch.cs:27:32:27:38 | call to method Throw | Switch.cs:10:10:10:11 | Exceptional Exit | exception | | Switch.cs:28:13:28:17 | Label: | Switch.cs:29:17:29:23 | Before return ...; | | @@ -6395,18 +6427,22 @@ | Switch.cs:46:9:52:9 | After switch (...) {...} | Switch.cs:45:5:53:5 | After {...} | | | Switch.cs:46:9:52:9 | switch (...) {...} | Switch.cs:46:17:46:17 | access to parameter o | | | Switch.cs:46:17:46:17 | access to parameter o | Switch.cs:48:13:48:23 | case ...: | | -| Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:48:18:48:20 | access to type Int32 | | +| Switch.cs:48:13:48:23 | After case ...: [match] | Switch.cs:49:17:49:22 | Before break; | | | Switch.cs:48:13:48:23 | After case ...: [no-match] | Switch.cs:50:13:50:39 | case ...: | | -| Switch.cs:48:13:48:23 | case ...: | Switch.cs:48:13:48:23 | After case ...: [match] | match | -| Switch.cs:48:13:48:23 | case ...: | Switch.cs:48:13:48:23 | After case ...: [no-match] | no-match | -| Switch.cs:48:18:48:20 | access to type Int32 | Switch.cs:49:17:49:22 | Before break; | | +| Switch.cs:48:13:48:23 | case ...: | Switch.cs:48:18:48:20 | access to type Int32 | | +| Switch.cs:48:18:48:20 | After access to type Int32 [match] | Switch.cs:48:13:48:23 | After case ...: [match] | match | +| Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | Switch.cs:48:13:48:23 | After case ...: [no-match] | no-match | +| Switch.cs:48:18:48:20 | access to type Int32 | Switch.cs:48:18:48:20 | After access to type Int32 [match] | match | +| Switch.cs:48:18:48:20 | access to type Int32 | Switch.cs:48:18:48:20 | After access to type Int32 [no-match] | no-match | | Switch.cs:49:17:49:22 | Before break; | Switch.cs:49:17:49:22 | break; | | | Switch.cs:49:17:49:22 | break; | Switch.cs:46:9:52:9 | After switch (...) {...} | break | -| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:18:50:21 | access to type Boolean | | +| Switch.cs:50:13:50:39 | After case ...: [match] | Switch.cs:50:30:50:38 | Before ... != ... | | | Switch.cs:50:13:50:39 | After case ...: [no-match] | Switch.cs:46:9:52:9 | After switch (...) {...} | | -| Switch.cs:50:13:50:39 | case ...: | Switch.cs:50:13:50:39 | After case ...: [match] | match | -| Switch.cs:50:13:50:39 | case ...: | Switch.cs:50:13:50:39 | After case ...: [no-match] | no-match | -| Switch.cs:50:18:50:21 | access to type Boolean | Switch.cs:50:30:50:38 | Before ... != ... | | +| Switch.cs:50:13:50:39 | case ...: | Switch.cs:50:18:50:21 | access to type Boolean | | +| Switch.cs:50:18:50:21 | After access to type Boolean [match] | Switch.cs:50:13:50:39 | After case ...: [match] | match | +| Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | Switch.cs:50:13:50:39 | After case ...: [no-match] | no-match | +| Switch.cs:50:18:50:21 | access to type Boolean | Switch.cs:50:18:50:21 | After access to type Boolean [match] | match | +| Switch.cs:50:18:50:21 | access to type Boolean | Switch.cs:50:18:50:21 | After access to type Boolean [no-match] | no-match | | Switch.cs:50:30:50:30 | access to parameter o | Switch.cs:50:35:50:38 | null | | | Switch.cs:50:30:50:38 | ... != ... | Switch.cs:50:30:50:38 | After ... != ... [false] | false | | Switch.cs:50:30:50:38 | ... != ... | Switch.cs:50:30:50:38 | After ... != ... [true] | true | @@ -6427,18 +6463,22 @@ | Switch.cs:57:17:57:21 | After ... + ... | Switch.cs:59:13:59:19 | case ...: | | | Switch.cs:57:17:57:21 | Before ... + ... | Switch.cs:57:17:57:17 | 1 | | | Switch.cs:57:21:57:21 | 2 | Switch.cs:57:17:57:21 | ... + ... | | -| Switch.cs:59:13:59:19 | After case ...: [match] | Switch.cs:59:18:59:18 | 2 | | +| Switch.cs:59:13:59:19 | After case ...: [match] | Switch.cs:60:17:60:22 | Before break; | | | Switch.cs:59:13:59:19 | After case ...: [no-match] | Switch.cs:61:13:61:19 | case ...: | | -| Switch.cs:59:13:59:19 | case ...: | Switch.cs:59:13:59:19 | After case ...: [match] | match | -| Switch.cs:59:13:59:19 | case ...: | Switch.cs:59:13:59:19 | After case ...: [no-match] | no-match | -| Switch.cs:59:18:59:18 | 2 | Switch.cs:60:17:60:22 | Before break; | | +| Switch.cs:59:13:59:19 | case ...: | Switch.cs:59:18:59:18 | 2 | | +| Switch.cs:59:18:59:18 | 2 | Switch.cs:59:18:59:18 | After 2 [match] | match | +| Switch.cs:59:18:59:18 | 2 | Switch.cs:59:18:59:18 | After 2 [no-match] | no-match | +| Switch.cs:59:18:59:18 | After 2 [match] | Switch.cs:59:13:59:19 | After case ...: [match] | match | +| Switch.cs:59:18:59:18 | After 2 [no-match] | Switch.cs:59:13:59:19 | After case ...: [no-match] | no-match | | Switch.cs:60:17:60:22 | Before break; | Switch.cs:60:17:60:22 | break; | | | Switch.cs:60:17:60:22 | break; | Switch.cs:57:9:63:9 | After switch (...) {...} | break | -| Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:61:18:61:18 | 3 | | +| Switch.cs:61:13:61:19 | After case ...: [match] | Switch.cs:62:17:62:22 | Before break; | | | Switch.cs:61:13:61:19 | After case ...: [no-match] | Switch.cs:57:9:63:9 | After switch (...) {...} | | -| Switch.cs:61:13:61:19 | case ...: | Switch.cs:61:13:61:19 | After case ...: [match] | match | -| Switch.cs:61:13:61:19 | case ...: | Switch.cs:61:13:61:19 | After case ...: [no-match] | no-match | -| Switch.cs:61:18:61:18 | 3 | Switch.cs:62:17:62:22 | Before break; | | +| Switch.cs:61:13:61:19 | case ...: | Switch.cs:61:18:61:18 | 3 | | +| Switch.cs:61:18:61:18 | 3 | Switch.cs:61:18:61:18 | After 3 [match] | match | +| Switch.cs:61:18:61:18 | 3 | Switch.cs:61:18:61:18 | After 3 [no-match] | no-match | +| Switch.cs:61:18:61:18 | After 3 [match] | Switch.cs:61:13:61:19 | After case ...: [match] | match | +| Switch.cs:61:18:61:18 | After 3 [no-match] | Switch.cs:61:13:61:19 | After case ...: [no-match] | no-match | | Switch.cs:62:17:62:22 | Before break; | Switch.cs:62:17:62:22 | break; | | | Switch.cs:62:17:62:22 | break; | Switch.cs:57:9:63:9 | After switch (...) {...} | break | | Switch.cs:66:10:66:11 | Entry | Switch.cs:66:20:66:20 | s | | @@ -6452,18 +6492,22 @@ | Switch.cs:68:17:68:25 | After (...) ... | Switch.cs:70:13:70:23 | case ...: | | | Switch.cs:68:17:68:25 | Before (...) ... | Switch.cs:68:25:68:25 | access to parameter s | | | Switch.cs:68:25:68:25 | access to parameter s | Switch.cs:68:17:68:25 | (...) ... | | -| Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:70:18:70:20 | access to type Int32 | | +| Switch.cs:70:13:70:23 | After case ...: [match] | Switch.cs:71:17:71:22 | Before break; | | | Switch.cs:70:13:70:23 | After case ...: [no-match] | Switch.cs:72:13:72:20 | case ...: | | -| Switch.cs:70:13:70:23 | case ...: | Switch.cs:70:13:70:23 | After case ...: [match] | match | -| Switch.cs:70:13:70:23 | case ...: | Switch.cs:70:13:70:23 | After case ...: [no-match] | no-match | -| Switch.cs:70:18:70:20 | access to type Int32 | Switch.cs:71:17:71:22 | Before break; | | +| Switch.cs:70:13:70:23 | case ...: | Switch.cs:70:18:70:20 | access to type Int32 | | +| Switch.cs:70:18:70:20 | After access to type Int32 [match] | Switch.cs:70:13:70:23 | After case ...: [match] | match | +| Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | Switch.cs:70:13:70:23 | After case ...: [no-match] | no-match | +| Switch.cs:70:18:70:20 | access to type Int32 | Switch.cs:70:18:70:20 | After access to type Int32 [match] | match | +| Switch.cs:70:18:70:20 | access to type Int32 | Switch.cs:70:18:70:20 | After access to type Int32 [no-match] | no-match | | Switch.cs:71:17:71:22 | Before break; | Switch.cs:71:17:71:22 | break; | | | Switch.cs:71:17:71:22 | break; | Switch.cs:68:9:74:9 | After switch (...) {...} | break | -| Switch.cs:72:13:72:20 | After case ...: [match] | Switch.cs:72:18:72:19 | "" | | +| Switch.cs:72:13:72:20 | After case ...: [match] | Switch.cs:73:17:73:22 | Before break; | | | Switch.cs:72:13:72:20 | After case ...: [no-match] | Switch.cs:68:9:74:9 | After switch (...) {...} | | -| Switch.cs:72:13:72:20 | case ...: | Switch.cs:72:13:72:20 | After case ...: [match] | match | -| Switch.cs:72:13:72:20 | case ...: | Switch.cs:72:13:72:20 | After case ...: [no-match] | no-match | -| Switch.cs:72:18:72:19 | "" | Switch.cs:73:17:73:22 | Before break; | | +| Switch.cs:72:13:72:20 | case ...: | Switch.cs:72:18:72:19 | "" | | +| Switch.cs:72:18:72:19 | "" | Switch.cs:72:18:72:19 | After "" [match] | match | +| Switch.cs:72:18:72:19 | "" | Switch.cs:72:18:72:19 | After "" [no-match] | no-match | +| Switch.cs:72:18:72:19 | After "" [match] | Switch.cs:72:13:72:20 | After case ...: [match] | match | +| Switch.cs:72:18:72:19 | After "" [no-match] | Switch.cs:72:13:72:20 | After case ...: [no-match] | no-match | | Switch.cs:73:17:73:22 | Before break; | Switch.cs:73:17:73:22 | break; | | | Switch.cs:73:17:73:22 | break; | Switch.cs:68:9:74:9 | After switch (...) {...} | break | | Switch.cs:77:10:77:11 | Entry | Switch.cs:77:17:77:17 | i | | @@ -6474,19 +6518,23 @@ | Switch.cs:79:9:87:9 | After switch (...) {...} | Switch.cs:88:9:88:21 | Before return ...; | | | Switch.cs:79:9:87:9 | switch (...) {...} | Switch.cs:79:17:79:17 | access to parameter i | | | Switch.cs:79:17:79:17 | access to parameter i | Switch.cs:81:13:81:19 | case ...: | | -| Switch.cs:81:13:81:19 | After case ...: [match] | Switch.cs:81:18:81:18 | 1 | | +| Switch.cs:81:13:81:19 | After case ...: [match] | Switch.cs:82:17:82:28 | Before return ...; | | | Switch.cs:81:13:81:19 | After case ...: [no-match] | Switch.cs:83:13:83:19 | case ...: | | -| Switch.cs:81:13:81:19 | case ...: | Switch.cs:81:13:81:19 | After case ...: [match] | match | -| Switch.cs:81:13:81:19 | case ...: | Switch.cs:81:13:81:19 | After case ...: [no-match] | no-match | -| Switch.cs:81:18:81:18 | 1 | Switch.cs:82:17:82:28 | Before return ...; | | +| Switch.cs:81:13:81:19 | case ...: | Switch.cs:81:18:81:18 | 1 | | +| Switch.cs:81:18:81:18 | 1 | Switch.cs:81:18:81:18 | After 1 [match] | match | +| Switch.cs:81:18:81:18 | 1 | Switch.cs:81:18:81:18 | After 1 [no-match] | no-match | +| Switch.cs:81:18:81:18 | After 1 [match] | Switch.cs:81:13:81:19 | After case ...: [match] | match | +| Switch.cs:81:18:81:18 | After 1 [no-match] | Switch.cs:81:13:81:19 | After case ...: [no-match] | no-match | | Switch.cs:82:17:82:28 | Before return ...; | Switch.cs:82:24:82:27 | true | | | Switch.cs:82:17:82:28 | return ...; | Switch.cs:77:10:77:11 | Normal Exit | return | | Switch.cs:82:24:82:27 | true | Switch.cs:82:17:82:28 | return ...; | | -| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:83:18:83:18 | 2 | | +| Switch.cs:83:13:83:19 | After case ...: [match] | Switch.cs:84:17:85:26 | if (...) ... | | | Switch.cs:83:13:83:19 | After case ...: [no-match] | Switch.cs:79:9:87:9 | After switch (...) {...} | | -| Switch.cs:83:13:83:19 | case ...: | Switch.cs:83:13:83:19 | After case ...: [match] | match | -| Switch.cs:83:13:83:19 | case ...: | Switch.cs:83:13:83:19 | After case ...: [no-match] | no-match | -| Switch.cs:83:18:83:18 | 2 | Switch.cs:84:17:85:26 | if (...) ... | | +| Switch.cs:83:13:83:19 | case ...: | Switch.cs:83:18:83:18 | 2 | | +| Switch.cs:83:18:83:18 | 2 | Switch.cs:83:18:83:18 | After 2 [match] | match | +| Switch.cs:83:18:83:18 | 2 | Switch.cs:83:18:83:18 | After 2 [no-match] | no-match | +| Switch.cs:83:18:83:18 | After 2 [match] | Switch.cs:83:13:83:19 | After case ...: [match] | match | +| Switch.cs:83:18:83:18 | After 2 [no-match] | Switch.cs:83:13:83:19 | After case ...: [no-match] | no-match | | Switch.cs:84:17:85:26 | After if (...) ... | Switch.cs:86:17:86:28 | Before return ...; | | | Switch.cs:84:17:85:26 | if (...) ... | Switch.cs:84:21:84:25 | Before ... > ... | | | Switch.cs:84:21:84:21 | access to parameter j | Switch.cs:84:25:84:25 | 2 | | @@ -6511,11 +6559,13 @@ | Switch.cs:93:9:97:9 | After switch (...) {...} | Switch.cs:98:9:98:21 | Before return ...; | | | Switch.cs:93:9:97:9 | switch (...) {...} | Switch.cs:93:17:93:17 | access to parameter o | | | Switch.cs:93:17:93:17 | access to parameter o | Switch.cs:95:13:95:23 | case ...: | | -| Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:95:18:95:20 | access to type Int32 | | +| Switch.cs:95:13:95:23 | After case ...: [match] | Switch.cs:96:17:96:28 | Before return ...; | | | Switch.cs:95:13:95:23 | After case ...: [no-match] | Switch.cs:93:9:97:9 | After switch (...) {...} | | -| Switch.cs:95:13:95:23 | case ...: | Switch.cs:95:13:95:23 | After case ...: [match] | match | -| Switch.cs:95:13:95:23 | case ...: | Switch.cs:95:13:95:23 | After case ...: [no-match] | no-match | -| Switch.cs:95:18:95:20 | access to type Int32 | Switch.cs:96:17:96:28 | Before return ...; | | +| Switch.cs:95:13:95:23 | case ...: | Switch.cs:95:18:95:20 | access to type Int32 | | +| Switch.cs:95:18:95:20 | After access to type Int32 [match] | Switch.cs:95:13:95:23 | After case ...: [match] | match | +| Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | Switch.cs:95:13:95:23 | After case ...: [no-match] | no-match | +| Switch.cs:95:18:95:20 | access to type Int32 | Switch.cs:95:18:95:20 | After access to type Int32 [match] | match | +| Switch.cs:95:18:95:20 | access to type Int32 | Switch.cs:95:18:95:20 | After access to type Int32 [no-match] | no-match | | Switch.cs:96:17:96:28 | Before return ...; | Switch.cs:96:24:96:27 | true | | | Switch.cs:96:17:96:28 | return ...; | Switch.cs:91:10:91:11 | Normal Exit | return | | Switch.cs:96:24:96:27 | true | Switch.cs:96:17:96:28 | return ...; | | @@ -6535,19 +6585,23 @@ | Switch.cs:103:17:103:25 | After access to property Length | Switch.cs:105:13:105:19 | case ...: | | | Switch.cs:103:17:103:25 | Before access to property Length | Switch.cs:103:17:103:17 | access to parameter s | | | Switch.cs:103:17:103:25 | access to property Length | Switch.cs:103:17:103:25 | After access to property Length | | -| Switch.cs:105:13:105:19 | After case ...: [match] | Switch.cs:105:18:105:18 | 0 | | +| Switch.cs:105:13:105:19 | After case ...: [match] | Switch.cs:105:21:105:29 | Before return ...; | | | Switch.cs:105:13:105:19 | After case ...: [no-match] | Switch.cs:106:13:106:19 | case ...: | | -| Switch.cs:105:13:105:19 | case ...: | Switch.cs:105:13:105:19 | After case ...: [match] | match | -| Switch.cs:105:13:105:19 | case ...: | Switch.cs:105:13:105:19 | After case ...: [no-match] | no-match | -| Switch.cs:105:18:105:18 | 0 | Switch.cs:105:21:105:29 | Before return ...; | | +| Switch.cs:105:13:105:19 | case ...: | Switch.cs:105:18:105:18 | 0 | | +| Switch.cs:105:18:105:18 | 0 | Switch.cs:105:18:105:18 | After 0 [match] | match | +| Switch.cs:105:18:105:18 | 0 | Switch.cs:105:18:105:18 | After 0 [no-match] | no-match | +| Switch.cs:105:18:105:18 | After 0 [match] | Switch.cs:105:13:105:19 | After case ...: [match] | match | +| Switch.cs:105:18:105:18 | After 0 [no-match] | Switch.cs:105:13:105:19 | After case ...: [no-match] | no-match | | Switch.cs:105:21:105:29 | Before return ...; | Switch.cs:105:28:105:28 | 0 | | | Switch.cs:105:21:105:29 | return ...; | Switch.cs:101:9:101:10 | Normal Exit | return | | Switch.cs:105:28:105:28 | 0 | Switch.cs:105:21:105:29 | return ...; | | -| Switch.cs:106:13:106:19 | After case ...: [match] | Switch.cs:106:18:106:18 | 1 | | +| Switch.cs:106:13:106:19 | After case ...: [match] | Switch.cs:106:21:106:29 | Before return ...; | | | Switch.cs:106:13:106:19 | After case ...: [no-match] | Switch.cs:103:9:107:9 | After switch (...) {...} | | -| Switch.cs:106:13:106:19 | case ...: | Switch.cs:106:13:106:19 | After case ...: [match] | match | -| Switch.cs:106:13:106:19 | case ...: | Switch.cs:106:13:106:19 | After case ...: [no-match] | no-match | -| Switch.cs:106:18:106:18 | 1 | Switch.cs:106:21:106:29 | Before return ...; | | +| Switch.cs:106:13:106:19 | case ...: | Switch.cs:106:18:106:18 | 1 | | +| Switch.cs:106:18:106:18 | 1 | Switch.cs:106:18:106:18 | After 1 [match] | match | +| Switch.cs:106:18:106:18 | 1 | Switch.cs:106:18:106:18 | After 1 [no-match] | no-match | +| Switch.cs:106:18:106:18 | After 1 [match] | Switch.cs:106:13:106:19 | After case ...: [match] | match | +| Switch.cs:106:18:106:18 | After 1 [no-match] | Switch.cs:106:13:106:19 | After case ...: [no-match] | no-match | | Switch.cs:106:21:106:29 | Before return ...; | Switch.cs:106:28:106:28 | 1 | | | Switch.cs:106:21:106:29 | return ...; | Switch.cs:101:9:101:10 | Normal Exit | return | | Switch.cs:106:28:106:28 | 1 | Switch.cs:106:21:106:29 | return ...; | | @@ -6574,11 +6628,13 @@ | Switch.cs:115:17:115:24 | After access to property Length | Switch.cs:117:13:117:35 | case ...: | | | Switch.cs:115:17:115:24 | Before access to property Length | Switch.cs:115:17:115:17 | access to parameter s | | | Switch.cs:115:17:115:24 | access to property Length | Switch.cs:115:17:115:24 | After access to property Length | | -| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:18:117:18 | 3 | | +| Switch.cs:117:13:117:35 | After case ...: [match] | Switch.cs:117:25:117:34 | Before ... == ... | | | Switch.cs:117:13:117:35 | After case ...: [no-match] | Switch.cs:118:13:118:34 | case ...: | | -| Switch.cs:117:13:117:35 | case ...: | Switch.cs:117:13:117:35 | After case ...: [match] | match | -| Switch.cs:117:13:117:35 | case ...: | Switch.cs:117:13:117:35 | After case ...: [no-match] | no-match | -| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:25:117:34 | Before ... == ... | | +| Switch.cs:117:13:117:35 | case ...: | Switch.cs:117:18:117:18 | 3 | | +| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:18:117:18 | After 3 [match] | match | +| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:18:117:18 | After 3 [no-match] | no-match | +| Switch.cs:117:18:117:18 | After 3 [match] | Switch.cs:117:13:117:35 | After case ...: [match] | match | +| Switch.cs:117:18:117:18 | After 3 [no-match] | Switch.cs:117:13:117:35 | After case ...: [no-match] | no-match | | Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:30:117:34 | "foo" | | | Switch.cs:117:25:117:34 | ... == ... | Switch.cs:117:25:117:34 | After ... == ... [false] | false | | Switch.cs:117:25:117:34 | ... == ... | Switch.cs:117:25:117:34 | After ... == ... [true] | true | @@ -6589,11 +6645,13 @@ | Switch.cs:117:37:117:45 | Before return ...; | Switch.cs:117:44:117:44 | 1 | | | Switch.cs:117:37:117:45 | return ...; | Switch.cs:113:9:113:11 | Normal Exit | return | | Switch.cs:117:44:117:44 | 1 | Switch.cs:117:37:117:45 | return ...; | | -| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:18:118:18 | 2 | | +| Switch.cs:118:13:118:34 | After case ...: [match] | Switch.cs:118:25:118:33 | Before ... == ... | | | Switch.cs:118:13:118:34 | After case ...: [no-match] | Switch.cs:115:9:119:9 | After switch (...) {...} | | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | After case ...: [match] | match | -| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:13:118:34 | After case ...: [no-match] | no-match | -| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:25:118:33 | Before ... == ... | | +| Switch.cs:118:13:118:34 | case ...: | Switch.cs:118:18:118:18 | 2 | | +| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:18:118:18 | After 2 [match] | match | +| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:18:118:18 | After 2 [no-match] | no-match | +| Switch.cs:118:18:118:18 | After 2 [match] | Switch.cs:118:13:118:34 | After case ...: [match] | match | +| Switch.cs:118:18:118:18 | After 2 [no-match] | Switch.cs:118:13:118:34 | After case ...: [no-match] | no-match | | Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:30:118:33 | "fu" | | | Switch.cs:118:25:118:33 | ... == ... | Switch.cs:118:25:118:33 | After ... == ... [false] | false | | Switch.cs:118:25:118:33 | ... == ... | Switch.cs:118:25:118:33 | After ... == ... [true] | true | @@ -6621,16 +6679,19 @@ | Switch.cs:125:13:125:48 | ... switch { ... } | Switch.cs:125:13:125:13 | access to parameter o | | | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | Switch.cs:125:9:126:19 | After if (...) ... | | | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | Switch.cs:126:13:126:19 | Before return ...; | | -| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:34:125:34 | access to local variable b | | -| Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:24:125:34 | After ... => ... [match] | match | -| Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:24:125:34 | After ... => ... [no-match] | no-match | -| Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:125:24:125:29 | Boolean b | | +| Switch.cs:125:24:125:29 | After Boolean b [match] | Switch.cs:125:24:125:34 | After ... => ... [match] | match | +| Switch.cs:125:24:125:29 | After Boolean b [no-match] | Switch.cs:125:24:125:34 | After ... => ... [no-match] | no-match | +| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:24:125:29 | After Boolean b [match] | match | +| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:24:125:29 | After Boolean b [no-match] | no-match | +| Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:24:125:29 | Boolean b | | +| Switch.cs:125:24:125:34 | After ... => ... [match] | Switch.cs:125:34:125:34 | access to local variable b | | | Switch.cs:125:24:125:34 | After ... => ... [no-match] | Switch.cs:125:37:125:46 | ... => ... | | | Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | false | | Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | true | -| Switch.cs:125:37:125:37 | _ | Switch.cs:125:42:125:46 | false | | -| Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:37:125:46 | After ... => ... [match] | match | -| Switch.cs:125:37:125:46 | After ... => ... [match] | Switch.cs:125:37:125:37 | _ | | +| Switch.cs:125:37:125:37 | After _ [match] | Switch.cs:125:37:125:46 | After ... => ... [match] | match | +| Switch.cs:125:37:125:37 | _ | Switch.cs:125:37:125:37 | After _ [match] | match | +| Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:37:125:37 | _ | | +| Switch.cs:125:37:125:46 | After ... => ... [match] | Switch.cs:125:42:125:46 | false | | | Switch.cs:125:42:125:46 | false | Switch.cs:125:13:125:48 | After ... switch { ... } [false] | false | | Switch.cs:125:42:125:46 | false | Switch.cs:125:13:125:48 | After ... switch { ... } [true] | true | | Switch.cs:126:13:126:19 | Before return ...; | Switch.cs:126:13:126:19 | return ...; | | @@ -6648,16 +6709,19 @@ | Switch.cs:131:17:131:53 | ... switch { ... } | Switch.cs:131:17:131:17 | access to parameter o | | | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | Switch.cs:131:16:131:66 | call to method ToString | | | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | Switch.cs:131:16:131:66 | After call to method ToString | | -| Switch.cs:131:28:131:35 | String s | Switch.cs:131:40:131:40 | access to local variable s | | -| Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:28:131:40 | After ... => ... [match] | match | -| Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:28:131:40 | After ... => ... [no-match] | no-match | -| Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:131:28:131:35 | String s | | +| Switch.cs:131:28:131:35 | After String s [match] | Switch.cs:131:28:131:40 | After ... => ... [match] | match | +| Switch.cs:131:28:131:35 | After String s [no-match] | Switch.cs:131:28:131:40 | After ... => ... [no-match] | no-match | +| Switch.cs:131:28:131:35 | String s | Switch.cs:131:28:131:35 | After String s [match] | match | +| Switch.cs:131:28:131:35 | String s | Switch.cs:131:28:131:35 | After String s [no-match] | no-match | +| Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:28:131:35 | String s | | +| Switch.cs:131:28:131:40 | After ... => ... [match] | Switch.cs:131:40:131:40 | access to local variable s | | | Switch.cs:131:28:131:40 | After ... => ... [no-match] | Switch.cs:131:43:131:51 | ... => ... | | | Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | non-null | | Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | null | -| Switch.cs:131:43:131:43 | _ | Switch.cs:131:48:131:51 | null | | -| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:51 | After ... => ... [match] | match | -| Switch.cs:131:43:131:51 | After ... => ... [match] | Switch.cs:131:43:131:43 | _ | | +| Switch.cs:131:43:131:43 | After _ [match] | Switch.cs:131:43:131:51 | After ... => ... [match] | match | +| Switch.cs:131:43:131:43 | _ | Switch.cs:131:43:131:43 | After _ [match] | match | +| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:43 | _ | | +| Switch.cs:131:43:131:51 | After ... => ... [match] | Switch.cs:131:48:131:51 | null | | | Switch.cs:131:48:131:51 | null | Switch.cs:131:17:131:53 | After ... switch { ... } [non-null] | non-null | | Switch.cs:131:48:131:51 | null | Switch.cs:131:17:131:53 | After ... switch { ... } [null] | null | | Switch.cs:134:9:134:11 | Entry | Switch.cs:134:17:134:17 | i | | @@ -6674,19 +6738,23 @@ | Switch.cs:138:29:138:30 | After -... | Switch.cs:138:22:138:31 | return ...; | | | Switch.cs:138:29:138:30 | Before -... | Switch.cs:138:30:138:30 | 1 | | | Switch.cs:138:30:138:30 | 1 | Switch.cs:138:29:138:30 | -... | | -| Switch.cs:139:13:139:19 | After case ...: [match] | Switch.cs:139:18:139:18 | 1 | | +| Switch.cs:139:13:139:19 | After case ...: [match] | Switch.cs:139:21:139:29 | Before return ...; | | | Switch.cs:139:13:139:19 | After case ...: [no-match] | Switch.cs:140:13:140:19 | case ...: | | -| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:13:139:19 | After case ...: [match] | match | -| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:13:139:19 | After case ...: [no-match] | no-match | -| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:21:139:29 | Before return ...; | | +| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:18:139:18 | 1 | | +| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:18:139:18 | After 1 [match] | match | +| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:18:139:18 | After 1 [no-match] | no-match | +| Switch.cs:139:18:139:18 | After 1 [match] | Switch.cs:139:13:139:19 | After case ...: [match] | match | +| Switch.cs:139:18:139:18 | After 1 [no-match] | Switch.cs:139:13:139:19 | After case ...: [no-match] | no-match | | Switch.cs:139:21:139:29 | Before return ...; | Switch.cs:139:28:139:28 | 1 | | | Switch.cs:139:21:139:29 | return ...; | Switch.cs:134:9:134:11 | Normal Exit | return | | Switch.cs:139:28:139:28 | 1 | Switch.cs:139:21:139:29 | return ...; | | -| Switch.cs:140:13:140:19 | After case ...: [match] | Switch.cs:140:18:140:18 | 2 | | +| Switch.cs:140:13:140:19 | After case ...: [match] | Switch.cs:140:21:140:29 | Before return ...; | | | Switch.cs:140:13:140:19 | After case ...: [no-match] | Switch.cs:138:13:138:20 | default: | | -| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:13:140:19 | After case ...: [match] | match | -| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:13:140:19 | After case ...: [no-match] | no-match | -| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:21:140:29 | Before return ...; | | +| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:18:140:18 | 2 | | +| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:18:140:18 | After 2 [match] | match | +| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:18:140:18 | After 2 [no-match] | no-match | +| Switch.cs:140:18:140:18 | After 2 [match] | Switch.cs:140:13:140:19 | After case ...: [match] | match | +| Switch.cs:140:18:140:18 | After 2 [no-match] | Switch.cs:140:13:140:19 | After case ...: [no-match] | no-match | | Switch.cs:140:21:140:29 | Before return ...; | Switch.cs:140:28:140:28 | 2 | | | Switch.cs:140:21:140:29 | return ...; | Switch.cs:134:9:134:11 | Normal Exit | return | | Switch.cs:140:28:140:28 | 2 | Switch.cs:140:21:140:29 | return ...; | | @@ -6696,11 +6764,13 @@ | Switch.cs:145:5:152:5 | {...} | Switch.cs:146:9:151:9 | switch (...) {...} | | | Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:146:17:146:17 | access to parameter i | | | Switch.cs:146:17:146:17 | access to parameter i | Switch.cs:148:13:148:19 | case ...: | | -| Switch.cs:148:13:148:19 | After case ...: [match] | Switch.cs:148:18:148:18 | 1 | | +| Switch.cs:148:13:148:19 | After case ...: [match] | Switch.cs:148:21:148:29 | Before return ...; | | | Switch.cs:148:13:148:19 | After case ...: [no-match] | Switch.cs:150:13:150:19 | case ...: | | -| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:13:148:19 | After case ...: [match] | match | -| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:13:148:19 | After case ...: [no-match] | no-match | -| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:21:148:29 | Before return ...; | | +| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:18:148:18 | 1 | | +| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:18:148:18 | After 1 [match] | match | +| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:18:148:18 | After 1 [no-match] | no-match | +| Switch.cs:148:18:148:18 | After 1 [match] | Switch.cs:148:13:148:19 | After case ...: [match] | match | +| Switch.cs:148:18:148:18 | After 1 [no-match] | Switch.cs:148:13:148:19 | After case ...: [no-match] | no-match | | Switch.cs:148:21:148:29 | Before return ...; | Switch.cs:148:28:148:28 | 1 | | | Switch.cs:148:21:148:29 | return ...; | Switch.cs:144:9:144:11 | Normal Exit | return | | Switch.cs:148:28:148:28 | 1 | Switch.cs:148:21:148:29 | return ...; | | @@ -6712,11 +6782,13 @@ | Switch.cs:149:29:149:30 | After -... | Switch.cs:149:22:149:31 | return ...; | | | Switch.cs:149:29:149:30 | Before -... | Switch.cs:149:30:149:30 | 1 | | | Switch.cs:149:30:149:30 | 1 | Switch.cs:149:29:149:30 | -... | | -| Switch.cs:150:13:150:19 | After case ...: [match] | Switch.cs:150:18:150:18 | 2 | | +| Switch.cs:150:13:150:19 | After case ...: [match] | Switch.cs:150:21:150:29 | Before return ...; | | | Switch.cs:150:13:150:19 | After case ...: [no-match] | Switch.cs:149:13:149:20 | default: | | -| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:13:150:19 | After case ...: [match] | match | -| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:13:150:19 | After case ...: [no-match] | no-match | -| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:21:150:29 | Before return ...; | | +| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:18:150:18 | 2 | | +| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:18:150:18 | After 2 [match] | match | +| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:18:150:18 | After 2 [no-match] | no-match | +| Switch.cs:150:18:150:18 | After 2 [match] | Switch.cs:150:13:150:19 | After case ...: [match] | match | +| Switch.cs:150:18:150:18 | After 2 [no-match] | Switch.cs:150:13:150:19 | After case ...: [no-match] | no-match | | Switch.cs:150:21:150:29 | Before return ...; | Switch.cs:150:28:150:28 | 2 | | | Switch.cs:150:21:150:29 | return ...; | Switch.cs:144:9:144:11 | Normal Exit | return | | Switch.cs:150:28:150:28 | 2 | Switch.cs:150:21:150:29 | return ...; | | @@ -6734,16 +6806,20 @@ | Switch.cs:156:17:156:17 | access to parameter b | Switch.cs:156:28:156:38 | ... => ... | | | Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:156:17:156:17 | access to parameter b | | | Switch.cs:156:17:156:54 | After ... switch { ... } | Switch.cs:156:13:156:54 | String s = ... | | -| Switch.cs:156:28:156:31 | true | Switch.cs:156:36:156:38 | "a" | | -| Switch.cs:156:28:156:38 | ... => ... | Switch.cs:156:28:156:38 | After ... => ... [match] | match | -| Switch.cs:156:28:156:38 | ... => ... | Switch.cs:156:28:156:38 | After ... => ... [no-match] | no-match | -| Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:156:28:156:31 | true | | +| Switch.cs:156:28:156:31 | After true [match] | Switch.cs:156:28:156:38 | After ... => ... [match] | match | +| Switch.cs:156:28:156:31 | After true [no-match] | Switch.cs:156:28:156:38 | After ... => ... [no-match] | no-match | +| Switch.cs:156:28:156:31 | true | Switch.cs:156:28:156:31 | After true [match] | match | +| Switch.cs:156:28:156:31 | true | Switch.cs:156:28:156:31 | After true [no-match] | no-match | +| Switch.cs:156:28:156:38 | ... => ... | Switch.cs:156:28:156:31 | true | | +| Switch.cs:156:28:156:38 | After ... => ... [match] | Switch.cs:156:36:156:38 | "a" | | | Switch.cs:156:28:156:38 | After ... => ... [no-match] | Switch.cs:156:41:156:52 | ... => ... | | | Switch.cs:156:36:156:38 | "a" | Switch.cs:156:17:156:54 | After ... switch { ... } | | -| Switch.cs:156:41:156:45 | false | Switch.cs:156:50:156:52 | "b" | | -| Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:41:156:52 | After ... => ... [match] | match | -| Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:41:156:52 | After ... => ... [no-match] | no-match | -| Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:156:41:156:45 | false | | +| Switch.cs:156:41:156:45 | After false [match] | Switch.cs:156:41:156:52 | After ... => ... [match] | match | +| Switch.cs:156:41:156:45 | After false [no-match] | Switch.cs:156:41:156:52 | After ... => ... [no-match] | no-match | +| Switch.cs:156:41:156:45 | false | Switch.cs:156:41:156:45 | After false [match] | match | +| Switch.cs:156:41:156:45 | false | Switch.cs:156:41:156:45 | After false [no-match] | no-match | +| Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:41:156:45 | false | | +| Switch.cs:156:41:156:52 | After ... => ... [match] | Switch.cs:156:50:156:52 | "b" | | | Switch.cs:156:41:156:52 | After ... => ... [no-match] | Switch.cs:156:17:156:54 | After ... switch { ... } | | | Switch.cs:156:50:156:52 | "b" | Switch.cs:156:17:156:54 | After ... switch { ... } | | | Switch.cs:157:9:160:49 | After if (...) ... | Switch.cs:155:5:161:5 | After {...} | | @@ -6786,16 +6862,20 @@ | Switch.cs:165:9:177:9 | After switch (...) {...} | Switch.cs:164:5:178:5 | After {...} | | | Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:165:17:165:17 | access to parameter i | | | Switch.cs:165:17:165:17 | access to parameter i | Switch.cs:167:13:167:19 | case ...: | | -| Switch.cs:167:13:167:19 | After case ...: [match] | Switch.cs:167:18:167:18 | 1 | | +| Switch.cs:167:13:167:19 | After case ...: [match] | Switch.cs:169:17:169:51 | ...; | | | Switch.cs:167:13:167:19 | After case ...: [no-match] | Switch.cs:168:13:168:19 | case ...: | | -| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:13:167:19 | After case ...: [match] | match | -| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:13:167:19 | After case ...: [no-match] | no-match | -| Switch.cs:167:18:167:18 | 1 | Switch.cs:169:17:169:51 | ...; | | -| Switch.cs:168:13:168:19 | After case ...: [match] | Switch.cs:168:18:168:18 | 2 | | +| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:18:167:18 | 1 | | +| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:18:167:18 | After 1 [match] | match | +| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:18:167:18 | After 1 [no-match] | no-match | +| Switch.cs:167:18:167:18 | After 1 [match] | Switch.cs:167:13:167:19 | After case ...: [match] | match | +| Switch.cs:167:18:167:18 | After 1 [no-match] | Switch.cs:167:13:167:19 | After case ...: [no-match] | no-match | +| Switch.cs:168:13:168:19 | After case ...: [match] | Switch.cs:169:17:169:51 | ...; | | | Switch.cs:168:13:168:19 | After case ...: [no-match] | Switch.cs:171:13:171:19 | case ...: | | -| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:13:168:19 | After case ...: [match] | match | -| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:13:168:19 | After case ...: [no-match] | no-match | -| Switch.cs:168:18:168:18 | 2 | Switch.cs:169:17:169:51 | ...; | | +| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:18:168:18 | 2 | | +| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:18:168:18 | After 2 [match] | match | +| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:18:168:18 | After 2 [no-match] | no-match | +| Switch.cs:168:18:168:18 | After 2 [match] | Switch.cs:168:13:168:19 | After case ...: [match] | match | +| Switch.cs:168:18:168:18 | After 2 [no-match] | Switch.cs:168:13:168:19 | After case ...: [no-match] | no-match | | Switch.cs:169:17:169:50 | After call to method WriteLine | Switch.cs:169:17:169:51 | After ...; | | | Switch.cs:169:17:169:50 | Before call to method WriteLine | Switch.cs:169:42:169:49 | "1 or 2" | | | Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:169:17:169:50 | After call to method WriteLine | | @@ -6804,11 +6884,13 @@ | Switch.cs:169:42:169:49 | "1 or 2" | Switch.cs:169:17:169:50 | call to method WriteLine | | | Switch.cs:170:17:170:22 | Before break; | Switch.cs:170:17:170:22 | break; | | | Switch.cs:170:17:170:22 | break; | Switch.cs:165:9:177:9 | After switch (...) {...} | break | -| Switch.cs:171:13:171:19 | After case ...: [match] | Switch.cs:171:18:171:18 | 3 | | +| Switch.cs:171:13:171:19 | After case ...: [match] | Switch.cs:172:17:172:46 | ...; | | | Switch.cs:171:13:171:19 | After case ...: [no-match] | Switch.cs:174:13:174:20 | default: | | -| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:13:171:19 | After case ...: [match] | match | -| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:13:171:19 | After case ...: [no-match] | no-match | -| Switch.cs:171:18:171:18 | 3 | Switch.cs:172:17:172:46 | ...; | | +| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:18:171:18 | 3 | | +| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:18:171:18 | After 3 [match] | match | +| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:18:171:18 | After 3 [no-match] | no-match | +| Switch.cs:171:18:171:18 | After 3 [match] | Switch.cs:171:13:171:19 | After case ...: [match] | match | +| Switch.cs:171:18:171:18 | After 3 [no-match] | Switch.cs:171:13:171:19 | After case ...: [no-match] | no-match | | Switch.cs:172:17:172:45 | After call to method WriteLine | Switch.cs:172:17:172:46 | After ...; | | | Switch.cs:172:17:172:45 | Before call to method WriteLine | Switch.cs:172:42:172:44 | "3" | | | Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:172:17:172:45 | After call to method WriteLine | | @@ -7195,11 +7277,13 @@ | cflow.cs:39:9:50:9 | After switch (...) {...} | cflow.cs:51:9:59:9 | switch (...) {...} | | | cflow.cs:39:9:50:9 | switch (...) {...} | cflow.cs:39:17:39:17 | access to parameter a | | | cflow.cs:39:17:39:17 | access to parameter a | cflow.cs:41:13:41:19 | case ...: | | -| cflow.cs:41:13:41:19 | After case ...: [match] | cflow.cs:41:18:41:18 | 1 | | +| cflow.cs:41:13:41:19 | After case ...: [match] | cflow.cs:42:17:42:39 | ...; | | | cflow.cs:41:13:41:19 | After case ...: [no-match] | cflow.cs:44:13:44:19 | case ...: | | -| cflow.cs:41:13:41:19 | case ...: | cflow.cs:41:13:41:19 | After case ...: [match] | match | -| cflow.cs:41:13:41:19 | case ...: | cflow.cs:41:13:41:19 | After case ...: [no-match] | no-match | -| cflow.cs:41:18:41:18 | 1 | cflow.cs:42:17:42:39 | ...; | | +| cflow.cs:41:13:41:19 | case ...: | cflow.cs:41:18:41:18 | 1 | | +| cflow.cs:41:18:41:18 | 1 | cflow.cs:41:18:41:18 | After 1 [match] | match | +| cflow.cs:41:18:41:18 | 1 | cflow.cs:41:18:41:18 | After 1 [no-match] | no-match | +| cflow.cs:41:18:41:18 | After 1 [match] | cflow.cs:41:13:41:19 | After case ...: [match] | match | +| cflow.cs:41:18:41:18 | After 1 [no-match] | cflow.cs:41:13:41:19 | After case ...: [no-match] | no-match | | cflow.cs:42:17:42:38 | After call to method WriteLine | cflow.cs:42:17:42:39 | After ...; | | | cflow.cs:42:17:42:38 | Before call to method WriteLine | cflow.cs:42:35:42:37 | "1" | | | cflow.cs:42:17:42:38 | call to method WriteLine | cflow.cs:42:17:42:38 | After call to method WriteLine | | @@ -7209,11 +7293,13 @@ | cflow.cs:43:17:43:28 | Before goto case ...; | cflow.cs:43:27:43:27 | 2 | | | cflow.cs:43:17:43:28 | goto case ...; | cflow.cs:44:13:44:19 | After case ...: [match] | goto | | cflow.cs:43:27:43:27 | 2 | cflow.cs:43:17:43:28 | goto case ...; | | -| cflow.cs:44:13:44:19 | After case ...: [match] | cflow.cs:44:18:44:18 | 2 | | +| cflow.cs:44:13:44:19 | After case ...: [match] | cflow.cs:45:17:45:39 | ...; | | | cflow.cs:44:13:44:19 | After case ...: [no-match] | cflow.cs:47:13:47:19 | case ...: | | -| cflow.cs:44:13:44:19 | case ...: | cflow.cs:44:13:44:19 | After case ...: [match] | match | -| cflow.cs:44:13:44:19 | case ...: | cflow.cs:44:13:44:19 | After case ...: [no-match] | no-match | -| cflow.cs:44:18:44:18 | 2 | cflow.cs:45:17:45:39 | ...; | | +| cflow.cs:44:13:44:19 | case ...: | cflow.cs:44:18:44:18 | 2 | | +| cflow.cs:44:18:44:18 | 2 | cflow.cs:44:18:44:18 | After 2 [match] | match | +| cflow.cs:44:18:44:18 | 2 | cflow.cs:44:18:44:18 | After 2 [no-match] | no-match | +| cflow.cs:44:18:44:18 | After 2 [match] | cflow.cs:44:13:44:19 | After case ...: [match] | match | +| cflow.cs:44:18:44:18 | After 2 [no-match] | cflow.cs:44:13:44:19 | After case ...: [no-match] | no-match | | cflow.cs:45:17:45:38 | After call to method WriteLine | cflow.cs:45:17:45:39 | After ...; | | | cflow.cs:45:17:45:38 | Before call to method WriteLine | cflow.cs:45:35:45:37 | "2" | | | cflow.cs:45:17:45:38 | call to method WriteLine | cflow.cs:45:17:45:38 | After call to method WriteLine | | @@ -7223,11 +7309,13 @@ | cflow.cs:46:17:46:28 | Before goto case ...; | cflow.cs:46:27:46:27 | 1 | | | cflow.cs:46:17:46:28 | goto case ...; | cflow.cs:41:13:41:19 | After case ...: [match] | goto | | cflow.cs:46:27:46:27 | 1 | cflow.cs:46:17:46:28 | goto case ...; | | -| cflow.cs:47:13:47:19 | After case ...: [match] | cflow.cs:47:18:47:18 | 3 | | +| cflow.cs:47:13:47:19 | After case ...: [match] | cflow.cs:48:17:48:39 | ...; | | | cflow.cs:47:13:47:19 | After case ...: [no-match] | cflow.cs:39:9:50:9 | After switch (...) {...} | | -| cflow.cs:47:13:47:19 | case ...: | cflow.cs:47:13:47:19 | After case ...: [match] | match | -| cflow.cs:47:13:47:19 | case ...: | cflow.cs:47:13:47:19 | After case ...: [no-match] | no-match | -| cflow.cs:47:18:47:18 | 3 | cflow.cs:48:17:48:39 | ...; | | +| cflow.cs:47:13:47:19 | case ...: | cflow.cs:47:18:47:18 | 3 | | +| cflow.cs:47:18:47:18 | 3 | cflow.cs:47:18:47:18 | After 3 [match] | match | +| cflow.cs:47:18:47:18 | 3 | cflow.cs:47:18:47:18 | After 3 [no-match] | no-match | +| cflow.cs:47:18:47:18 | After 3 [match] | cflow.cs:47:13:47:19 | After case ...: [match] | match | +| cflow.cs:47:18:47:18 | After 3 [no-match] | cflow.cs:47:13:47:19 | After case ...: [no-match] | no-match | | cflow.cs:48:17:48:38 | After call to method WriteLine | cflow.cs:48:17:48:39 | After ...; | | | cflow.cs:48:17:48:38 | Before call to method WriteLine | cflow.cs:48:35:48:37 | "3" | | | cflow.cs:48:17:48:38 | call to method WriteLine | cflow.cs:48:17:48:38 | After call to method WriteLine | | @@ -7239,11 +7327,13 @@ | cflow.cs:51:9:59:9 | After switch (...) {...} | cflow.cs:60:9:66:9 | switch (...) {...} | | | cflow.cs:51:9:59:9 | switch (...) {...} | cflow.cs:51:17:51:17 | access to parameter a | | | cflow.cs:51:17:51:17 | access to parameter a | cflow.cs:53:13:53:20 | case ...: | | -| cflow.cs:53:13:53:20 | After case ...: [match] | cflow.cs:53:18:53:19 | 42 | | +| cflow.cs:53:13:53:20 | After case ...: [match] | cflow.cs:54:17:54:48 | ...; | | | cflow.cs:53:13:53:20 | After case ...: [no-match] | cflow.cs:56:13:56:20 | default: | | -| cflow.cs:53:13:53:20 | case ...: | cflow.cs:53:13:53:20 | After case ...: [match] | match | -| cflow.cs:53:13:53:20 | case ...: | cflow.cs:53:13:53:20 | After case ...: [no-match] | no-match | -| cflow.cs:53:18:53:19 | 42 | cflow.cs:54:17:54:48 | ...; | | +| cflow.cs:53:13:53:20 | case ...: | cflow.cs:53:18:53:19 | 42 | | +| cflow.cs:53:18:53:19 | 42 | cflow.cs:53:18:53:19 | After 42 [match] | match | +| cflow.cs:53:18:53:19 | 42 | cflow.cs:53:18:53:19 | After 42 [no-match] | no-match | +| cflow.cs:53:18:53:19 | After 42 [match] | cflow.cs:53:13:53:20 | After case ...: [match] | match | +| cflow.cs:53:18:53:19 | After 42 [no-match] | cflow.cs:53:13:53:20 | After case ...: [no-match] | no-match | | cflow.cs:54:17:54:47 | After call to method WriteLine | cflow.cs:54:17:54:48 | After ...; | | | cflow.cs:54:17:54:47 | Before call to method WriteLine | cflow.cs:54:35:54:46 | "The answer" | | | cflow.cs:54:17:54:47 | call to method WriteLine | cflow.cs:54:17:54:47 | After call to method WriteLine | | @@ -7271,11 +7361,13 @@ | cflow.cs:60:27:60:31 | Before access to field Field | cflow.cs:60:27:60:31 | this access | | | cflow.cs:60:27:60:31 | access to field Field | cflow.cs:60:27:60:31 | After access to field Field | | | cflow.cs:60:27:60:31 | this access | cflow.cs:60:27:60:31 | access to field Field | | -| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:62:18:62:18 | 0 | | +| cflow.cs:62:13:62:19 | After case ...: [match] | cflow.cs:63:17:64:55 | if (...) ... | | | cflow.cs:62:13:62:19 | After case ...: [no-match] | cflow.cs:60:9:66:9 | After switch (...) {...} | | -| cflow.cs:62:13:62:19 | case ...: | cflow.cs:62:13:62:19 | After case ...: [match] | match | -| cflow.cs:62:13:62:19 | case ...: | cflow.cs:62:13:62:19 | After case ...: [no-match] | no-match | -| cflow.cs:62:18:62:18 | 0 | cflow.cs:63:17:64:55 | if (...) ... | | +| cflow.cs:62:13:62:19 | case ...: | cflow.cs:62:18:62:18 | 0 | | +| cflow.cs:62:18:62:18 | 0 | cflow.cs:62:18:62:18 | After 0 [match] | match | +| cflow.cs:62:18:62:18 | 0 | cflow.cs:62:18:62:18 | After 0 [no-match] | no-match | +| cflow.cs:62:18:62:18 | After 0 [match] | cflow.cs:62:13:62:19 | After case ...: [match] | match | +| cflow.cs:62:18:62:18 | After 0 [no-match] | cflow.cs:62:13:62:19 | After case ...: [no-match] | no-match | | cflow.cs:63:17:64:55 | After if (...) ... | cflow.cs:65:17:65:22 | Before break; | | | cflow.cs:63:17:64:55 | if (...) ... | cflow.cs:63:21:63:34 | !... | | | cflow.cs:63:21:63:34 | !... | cflow.cs:63:23:63:33 | Before ... == ... | | @@ -8221,18 +8313,22 @@ | cflow.cs:246:17:246:32 | After ... + ... | cflow.cs:248:13:248:19 | case ...: | | | cflow.cs:246:17:246:32 | Before ... + ... | cflow.cs:246:17:246:28 | Before access to property Length | | | cflow.cs:246:32:246:32 | 3 | cflow.cs:246:17:246:32 | ... + ... | | -| cflow.cs:248:13:248:19 | After case ...: [match] | cflow.cs:248:18:248:18 | 0 | | +| cflow.cs:248:13:248:19 | After case ...: [match] | cflow.cs:249:17:249:29 | Before goto default; | | | cflow.cs:248:13:248:19 | After case ...: [no-match] | cflow.cs:250:13:250:19 | case ...: | | -| cflow.cs:248:13:248:19 | case ...: | cflow.cs:248:13:248:19 | After case ...: [match] | match | -| cflow.cs:248:13:248:19 | case ...: | cflow.cs:248:13:248:19 | After case ...: [no-match] | no-match | -| cflow.cs:248:18:248:18 | 0 | cflow.cs:249:17:249:29 | Before goto default; | | +| cflow.cs:248:13:248:19 | case ...: | cflow.cs:248:18:248:18 | 0 | | +| cflow.cs:248:18:248:18 | 0 | cflow.cs:248:18:248:18 | After 0 [match] | match | +| cflow.cs:248:18:248:18 | 0 | cflow.cs:248:18:248:18 | After 0 [no-match] | no-match | +| cflow.cs:248:18:248:18 | After 0 [match] | cflow.cs:248:13:248:19 | After case ...: [match] | match | +| cflow.cs:248:18:248:18 | After 0 [no-match] | cflow.cs:248:13:248:19 | After case ...: [no-match] | no-match | | cflow.cs:249:17:249:29 | Before goto default; | cflow.cs:249:17:249:29 | goto default; | | | cflow.cs:249:17:249:29 | goto default; | cflow.cs:255:13:255:20 | After default: [match] | goto | -| cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:250:18:250:18 | 1 | | +| cflow.cs:250:13:250:19 | After case ...: [match] | cflow.cs:251:17:251:37 | ...; | | | cflow.cs:250:13:250:19 | After case ...: [no-match] | cflow.cs:253:13:253:19 | case ...: | | -| cflow.cs:250:13:250:19 | case ...: | cflow.cs:250:13:250:19 | After case ...: [match] | match | -| cflow.cs:250:13:250:19 | case ...: | cflow.cs:250:13:250:19 | After case ...: [no-match] | no-match | -| cflow.cs:250:18:250:18 | 1 | cflow.cs:251:17:251:37 | ...; | | +| cflow.cs:250:13:250:19 | case ...: | cflow.cs:250:18:250:18 | 1 | | +| cflow.cs:250:18:250:18 | 1 | cflow.cs:250:18:250:18 | After 1 [match] | match | +| cflow.cs:250:18:250:18 | 1 | cflow.cs:250:18:250:18 | After 1 [no-match] | no-match | +| cflow.cs:250:18:250:18 | After 1 [match] | cflow.cs:250:13:250:19 | After case ...: [match] | match | +| cflow.cs:250:18:250:18 | After 1 [no-match] | cflow.cs:250:13:250:19 | After case ...: [no-match] | no-match | | cflow.cs:251:17:251:36 | After call to method WriteLine | cflow.cs:251:17:251:37 | After ...; | | | cflow.cs:251:17:251:36 | Before call to method WriteLine | cflow.cs:251:35:251:35 | 1 | | | cflow.cs:251:17:251:36 | call to method WriteLine | cflow.cs:251:17:251:36 | After call to method WriteLine | | @@ -8241,11 +8337,13 @@ | cflow.cs:251:35:251:35 | 1 | cflow.cs:251:17:251:36 | call to method WriteLine | | | cflow.cs:252:17:252:22 | Before break; | cflow.cs:252:17:252:22 | break; | | | cflow.cs:252:17:252:22 | break; | cflow.cs:246:9:258:9 | After switch (...) {...} | break | -| cflow.cs:253:13:253:19 | After case ...: [match] | cflow.cs:253:18:253:18 | 2 | | +| cflow.cs:253:13:253:19 | After case ...: [match] | cflow.cs:254:17:254:27 | Before goto ...; | | | cflow.cs:253:13:253:19 | After case ...: [no-match] | cflow.cs:255:13:255:20 | default: | | -| cflow.cs:253:13:253:19 | case ...: | cflow.cs:253:13:253:19 | After case ...: [match] | match | -| cflow.cs:253:13:253:19 | case ...: | cflow.cs:253:13:253:19 | After case ...: [no-match] | no-match | -| cflow.cs:253:18:253:18 | 2 | cflow.cs:254:17:254:27 | Before goto ...; | | +| cflow.cs:253:13:253:19 | case ...: | cflow.cs:253:18:253:18 | 2 | | +| cflow.cs:253:18:253:18 | 2 | cflow.cs:253:18:253:18 | After 2 [match] | match | +| cflow.cs:253:18:253:18 | 2 | cflow.cs:253:18:253:18 | After 2 [no-match] | no-match | +| cflow.cs:253:18:253:18 | After 2 [match] | cflow.cs:253:13:253:19 | After case ...: [match] | match | +| cflow.cs:253:18:253:18 | After 2 [no-match] | cflow.cs:253:13:253:19 | After case ...: [no-match] | no-match | | cflow.cs:254:17:254:27 | Before goto ...; | cflow.cs:254:17:254:27 | goto ...; | | | cflow.cs:254:17:254:27 | goto ...; | cflow.cs:242:5:242:9 | Label: | goto | | cflow.cs:255:13:255:20 | After default: [match] | cflow.cs:256:17:256:37 | ...; | | diff --git a/csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected b/csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected index b274d7905b2..37455092448 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected @@ -79,7 +79,6 @@ | Guards.cs:287:17:287:17 | access to parameter o | Guards.cs:278:13:279:28 | ... => ... | Guards.cs:279:17:279:17 | access to parameter o | false | | Guards.cs:287:17:287:17 | access to parameter o | Guards.cs:282:13:283:28 | ... => ... | Guards.cs:283:17:283:17 | access to parameter o | false | | Guards.cs:287:17:287:17 | access to parameter o | Guards.cs:284:13:285:28 | ... => ... | Guards.cs:285:17:285:17 | access to parameter o | false | -| Guards.cs:334:13:334:15 | access to constant B | Guards.cs:334:13:334:20 | ... => ... | Guards.cs:334:13:334:15 | access to constant B | true | | Guards.cs:342:27:342:27 | access to parameter b | Guards.cs:341:20:341:20 | access to parameter b | Guards.cs:341:20:341:20 | access to parameter b | false | | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:21 | ... != ... | Guards.cs:342:13:342:13 | access to local variable s | true | | Guards.cs:349:13:349:13 | access to parameter o | Guards.cs:348:13:348:25 | ... is ... | Guards.cs:348:13:348:13 | access to parameter o | true | diff --git a/csharp/ql/test/library-tests/controlflow/guards/GuardedControlFlowNode.expected b/csharp/ql/test/library-tests/controlflow/guards/GuardedControlFlowNode.expected index c038c49ba17..765b8670a18 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/GuardedControlFlowNode.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/GuardedControlFlowNode.expected @@ -202,7 +202,6 @@ | Guards.cs:287:17:287:28 | call to method ToString | Guards.cs:278:13:279:28 | ... => ... | Guards.cs:279:17:279:28 | call to method ToString | false | | Guards.cs:287:17:287:28 | call to method ToString | Guards.cs:282:13:283:28 | ... => ... | Guards.cs:283:17:283:28 | call to method ToString | false | | Guards.cs:287:17:287:28 | call to method ToString | Guards.cs:284:13:285:28 | ... => ... | Guards.cs:285:17:285:28 | call to method ToString | false | -| Guards.cs:334:13:334:15 | access to constant B | Guards.cs:334:13:334:20 | ... => ... | Guards.cs:334:13:334:15 | access to constant B | true | | Guards.cs:342:27:342:27 | access to parameter b | Guards.cs:341:20:341:20 | access to parameter b | Guards.cs:341:20:341:20 | access to parameter b | false | | Guards.cs:342:27:342:27 | access to parameter b | Guards.cs:341:20:341:32 | ... ? ... : ... | Guards.cs:341:20:341:20 | access to parameter b | not null | | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:13 | access to local variable s | Guards.cs:342:13:342:13 | access to local variable s | not null | diff --git a/csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected b/csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected index c038c49ba17..765b8670a18 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected @@ -202,7 +202,6 @@ | Guards.cs:287:17:287:28 | call to method ToString | Guards.cs:278:13:279:28 | ... => ... | Guards.cs:279:17:279:28 | call to method ToString | false | | Guards.cs:287:17:287:28 | call to method ToString | Guards.cs:282:13:283:28 | ... => ... | Guards.cs:283:17:283:28 | call to method ToString | false | | Guards.cs:287:17:287:28 | call to method ToString | Guards.cs:284:13:285:28 | ... => ... | Guards.cs:285:17:285:28 | call to method ToString | false | -| Guards.cs:334:13:334:15 | access to constant B | Guards.cs:334:13:334:20 | ... => ... | Guards.cs:334:13:334:15 | access to constant B | true | | Guards.cs:342:27:342:27 | access to parameter b | Guards.cs:341:20:341:20 | access to parameter b | Guards.cs:341:20:341:20 | access to parameter b | false | | Guards.cs:342:27:342:27 | access to parameter b | Guards.cs:341:20:341:32 | ... ? ... : ... | Guards.cs:341:20:341:20 | access to parameter b | not null | | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:13 | access to local variable s | Guards.cs:342:13:342:13 | access to local variable s | not null | diff --git a/csharp/ql/test/library-tests/csharp7/IsFlow.expected b/csharp/ql/test/library-tests/csharp7/IsFlow.expected index a1dafe05ce6..07d3079854d 100644 --- a/csharp/ql/test/library-tests/csharp7/IsFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/IsFlow.expected @@ -3,18 +3,22 @@ | CSharp7.cs:248:9:274:9 | After switch (...) {...} | CSharp7.cs:231:5:275:5 | After {...} | semmle.label | successor | | CSharp7.cs:248:9:274:9 | switch (...) {...} | CSharp7.cs:248:17:248:17 | access to local variable o | semmle.label | successor | | CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:250:13:250:23 | case ...: | semmle.label | successor | -| CSharp7.cs:250:13:250:23 | After case ...: [match] | CSharp7.cs:250:18:250:22 | "xyz" | semmle.label | successor | +| CSharp7.cs:250:13:250:23 | After case ...: [match] | CSharp7.cs:251:17:251:22 | Before break; | semmle.label | successor | | CSharp7.cs:250:13:250:23 | After case ...: [no-match] | CSharp7.cs:252:13:252:31 | case ...: | semmle.label | successor | -| CSharp7.cs:250:13:250:23 | case ...: | CSharp7.cs:250:13:250:23 | After case ...: [match] | semmle.label | match | -| CSharp7.cs:250:13:250:23 | case ...: | CSharp7.cs:250:13:250:23 | After case ...: [no-match] | semmle.label | no-match | -| CSharp7.cs:250:18:250:22 | "xyz" | CSharp7.cs:251:17:251:22 | Before break; | semmle.label | successor | +| CSharp7.cs:250:13:250:23 | case ...: | CSharp7.cs:250:18:250:22 | "xyz" | semmle.label | successor | +| CSharp7.cs:250:18:250:22 | "xyz" | CSharp7.cs:250:18:250:22 | After "xyz" [match] | semmle.label | match | +| CSharp7.cs:250:18:250:22 | "xyz" | CSharp7.cs:250:18:250:22 | After "xyz" [no-match] | semmle.label | no-match | +| CSharp7.cs:250:18:250:22 | After "xyz" [match] | CSharp7.cs:250:13:250:23 | After case ...: [match] | semmle.label | match | +| CSharp7.cs:250:18:250:22 | After "xyz" [no-match] | CSharp7.cs:250:13:250:23 | After case ...: [no-match] | semmle.label | no-match | | CSharp7.cs:251:17:251:22 | Before break; | CSharp7.cs:251:17:251:22 | break; | semmle.label | successor | | CSharp7.cs:251:17:251:22 | break; | CSharp7.cs:248:9:274:9 | After switch (...) {...} | semmle.label | break | -| CSharp7.cs:252:13:252:31 | After case ...: [match] | CSharp7.cs:252:18:252:19 | "" | semmle.label | successor | +| CSharp7.cs:252:13:252:31 | After case ...: [match] | CSharp7.cs:252:26:252:30 | Before ... < ... | semmle.label | successor | | CSharp7.cs:252:13:252:31 | After case ...: [no-match] | CSharp7.cs:254:13:254:41 | case ...: | semmle.label | successor | -| CSharp7.cs:252:13:252:31 | case ...: | CSharp7.cs:252:13:252:31 | After case ...: [match] | semmle.label | match | -| CSharp7.cs:252:13:252:31 | case ...: | CSharp7.cs:252:13:252:31 | After case ...: [no-match] | semmle.label | no-match | -| CSharp7.cs:252:18:252:19 | "" | CSharp7.cs:252:26:252:30 | Before ... < ... | semmle.label | successor | +| CSharp7.cs:252:13:252:31 | case ...: | CSharp7.cs:252:18:252:19 | "" | semmle.label | successor | +| CSharp7.cs:252:18:252:19 | "" | CSharp7.cs:252:18:252:19 | After "" [match] | semmle.label | match | +| CSharp7.cs:252:18:252:19 | "" | CSharp7.cs:252:18:252:19 | After "" [no-match] | semmle.label | no-match | +| CSharp7.cs:252:18:252:19 | After "" [match] | CSharp7.cs:252:13:252:31 | After case ...: [match] | semmle.label | match | +| CSharp7.cs:252:18:252:19 | After "" [no-match] | CSharp7.cs:252:13:252:31 | After case ...: [no-match] | semmle.label | no-match | | CSharp7.cs:252:26:252:26 | 1 | CSharp7.cs:252:30:252:30 | 2 | semmle.label | successor | | CSharp7.cs:252:26:252:30 | ... < ... | CSharp7.cs:252:26:252:30 | After ... < ... [false] | semmle.label | false | | CSharp7.cs:252:26:252:30 | ... < ... | CSharp7.cs:252:26:252:30 | After ... < ... [true] | semmle.label | true | @@ -24,11 +28,13 @@ | CSharp7.cs:252:30:252:30 | 2 | CSharp7.cs:252:26:252:30 | ... < ... | semmle.label | successor | | CSharp7.cs:253:17:253:22 | Before break; | CSharp7.cs:253:17:253:22 | break; | semmle.label | successor | | CSharp7.cs:253:17:253:22 | break; | CSharp7.cs:248:9:274:9 | After switch (...) {...} | semmle.label | break | -| CSharp7.cs:254:13:254:41 | After case ...: [match] | CSharp7.cs:254:18:254:20 | "x" | semmle.label | successor | +| CSharp7.cs:254:13:254:41 | After case ...: [match] | CSharp7.cs:254:27:254:40 | Before ... is ... | semmle.label | successor | | CSharp7.cs:254:13:254:41 | After case ...: [no-match] | CSharp7.cs:257:13:257:36 | case ...: | semmle.label | successor | -| CSharp7.cs:254:13:254:41 | case ...: | CSharp7.cs:254:13:254:41 | After case ...: [match] | semmle.label | match | -| CSharp7.cs:254:13:254:41 | case ...: | CSharp7.cs:254:13:254:41 | After case ...: [no-match] | semmle.label | no-match | -| CSharp7.cs:254:18:254:20 | "x" | CSharp7.cs:254:27:254:40 | Before ... is ... | semmle.label | successor | +| CSharp7.cs:254:13:254:41 | case ...: | CSharp7.cs:254:18:254:20 | "x" | semmle.label | successor | +| CSharp7.cs:254:18:254:20 | "x" | CSharp7.cs:254:18:254:20 | After "x" [match] | semmle.label | match | +| CSharp7.cs:254:18:254:20 | "x" | CSharp7.cs:254:18:254:20 | After "x" [no-match] | semmle.label | no-match | +| CSharp7.cs:254:18:254:20 | After "x" [match] | CSharp7.cs:254:13:254:41 | After case ...: [match] | semmle.label | match | +| CSharp7.cs:254:18:254:20 | After "x" [no-match] | CSharp7.cs:254:13:254:41 | After case ...: [no-match] | semmle.label | no-match | | CSharp7.cs:254:27:254:27 | access to local variable o | CSharp7.cs:254:27:254:40 | ... is ... | semmle.label | successor | | CSharp7.cs:254:27:254:40 | ... is ... | CSharp7.cs:254:27:254:40 | After ... is ... [false] | semmle.label | false | | CSharp7.cs:254:27:254:40 | ... is ... | CSharp7.cs:254:27:254:40 | [MatchTrue] ... is ... | semmle.label | true | @@ -52,11 +58,13 @@ | CSharp7.cs:255:40:255:41 | access to local variable s4 | CSharp7.cs:255:39:255:42 | {...} | semmle.label | successor | | CSharp7.cs:256:17:256:22 | Before break; | CSharp7.cs:256:17:256:22 | break; | semmle.label | successor | | CSharp7.cs:256:17:256:22 | break; | CSharp7.cs:248:9:274:9 | After switch (...) {...} | semmle.label | break | -| CSharp7.cs:257:13:257:36 | After case ...: [match] | CSharp7.cs:257:18:257:23 | Int32 i2 | semmle.label | successor | +| CSharp7.cs:257:13:257:36 | After case ...: [match] | CSharp7.cs:257:30:257:35 | Before ... > ... | semmle.label | successor | | CSharp7.cs:257:13:257:36 | After case ...: [no-match] | CSharp7.cs:260:13:260:24 | case ...: | semmle.label | successor | -| CSharp7.cs:257:13:257:36 | case ...: | CSharp7.cs:257:13:257:36 | After case ...: [match] | semmle.label | match | -| CSharp7.cs:257:13:257:36 | case ...: | CSharp7.cs:257:13:257:36 | After case ...: [no-match] | semmle.label | no-match | -| CSharp7.cs:257:18:257:23 | Int32 i2 | CSharp7.cs:257:30:257:35 | Before ... > ... | semmle.label | successor | +| CSharp7.cs:257:13:257:36 | case ...: | CSharp7.cs:257:18:257:23 | Int32 i2 | semmle.label | successor | +| CSharp7.cs:257:18:257:23 | After Int32 i2 [match] | CSharp7.cs:257:13:257:36 | After case ...: [match] | semmle.label | match | +| CSharp7.cs:257:18:257:23 | After Int32 i2 [no-match] | CSharp7.cs:257:13:257:36 | After case ...: [no-match] | semmle.label | no-match | +| CSharp7.cs:257:18:257:23 | Int32 i2 | CSharp7.cs:257:18:257:23 | After Int32 i2 [match] | semmle.label | match | +| CSharp7.cs:257:18:257:23 | Int32 i2 | CSharp7.cs:257:18:257:23 | After Int32 i2 [no-match] | semmle.label | no-match | | CSharp7.cs:257:30:257:31 | access to local variable i2 | CSharp7.cs:257:35:257:35 | 0 | semmle.label | successor | | CSharp7.cs:257:30:257:35 | ... > ... | CSharp7.cs:257:30:257:35 | After ... > ... [false] | semmle.label | false | | CSharp7.cs:257:30:257:35 | ... > ... | CSharp7.cs:257:30:257:35 | After ... > ... [true] | semmle.label | true | @@ -79,11 +87,13 @@ | CSharp7.cs:258:47:258:48 | access to local variable i2 | CSharp7.cs:258:46:258:49 | {...} | semmle.label | successor | | CSharp7.cs:259:17:259:22 | Before break; | CSharp7.cs:259:17:259:22 | break; | semmle.label | successor | | CSharp7.cs:259:17:259:22 | break; | CSharp7.cs:248:9:274:9 | After switch (...) {...} | semmle.label | break | -| CSharp7.cs:260:13:260:24 | After case ...: [match] | CSharp7.cs:260:18:260:23 | Int32 i3 | semmle.label | successor | +| CSharp7.cs:260:13:260:24 | After case ...: [match] | CSharp7.cs:261:17:261:47 | ...; | semmle.label | successor | | CSharp7.cs:260:13:260:24 | After case ...: [no-match] | CSharp7.cs:263:13:263:27 | case ...: | semmle.label | successor | -| CSharp7.cs:260:13:260:24 | case ...: | CSharp7.cs:260:13:260:24 | After case ...: [match] | semmle.label | match | -| CSharp7.cs:260:13:260:24 | case ...: | CSharp7.cs:260:13:260:24 | After case ...: [no-match] | semmle.label | no-match | -| CSharp7.cs:260:18:260:23 | Int32 i3 | CSharp7.cs:261:17:261:47 | ...; | semmle.label | successor | +| CSharp7.cs:260:13:260:24 | case ...: | CSharp7.cs:260:18:260:23 | Int32 i3 | semmle.label | successor | +| CSharp7.cs:260:18:260:23 | After Int32 i3 [match] | CSharp7.cs:260:13:260:24 | After case ...: [match] | semmle.label | match | +| CSharp7.cs:260:18:260:23 | After Int32 i3 [no-match] | CSharp7.cs:260:13:260:24 | After case ...: [no-match] | semmle.label | no-match | +| CSharp7.cs:260:18:260:23 | Int32 i3 | CSharp7.cs:260:18:260:23 | After Int32 i3 [match] | semmle.label | match | +| CSharp7.cs:260:18:260:23 | Int32 i3 | CSharp7.cs:260:18:260:23 | After Int32 i3 [no-match] | semmle.label | no-match | | CSharp7.cs:261:17:261:46 | After call to method WriteLine | CSharp7.cs:261:17:261:47 | After ...; | semmle.label | successor | | CSharp7.cs:261:17:261:46 | Before call to method WriteLine | CSharp7.cs:261:35:261:45 | Before $"..." | semmle.label | successor | | CSharp7.cs:261:17:261:46 | call to method WriteLine | CSharp7.cs:261:17:261:46 | After call to method WriteLine | semmle.label | successor | @@ -99,11 +109,13 @@ | CSharp7.cs:261:42:261:43 | access to local variable i3 | CSharp7.cs:261:41:261:44 | {...} | semmle.label | successor | | CSharp7.cs:262:17:262:22 | Before break; | CSharp7.cs:262:17:262:22 | break; | semmle.label | successor | | CSharp7.cs:262:17:262:22 | break; | CSharp7.cs:248:9:274:9 | After switch (...) {...} | semmle.label | break | -| CSharp7.cs:263:13:263:27 | After case ...: [match] | CSharp7.cs:263:18:263:26 | String s2 | semmle.label | successor | +| CSharp7.cs:263:13:263:27 | After case ...: [match] | CSharp7.cs:264:17:264:50 | ...; | semmle.label | successor | | CSharp7.cs:263:13:263:27 | After case ...: [no-match] | CSharp7.cs:266:13:266:26 | case ...: | semmle.label | successor | -| CSharp7.cs:263:13:263:27 | case ...: | CSharp7.cs:263:13:263:27 | After case ...: [match] | semmle.label | match | -| CSharp7.cs:263:13:263:27 | case ...: | CSharp7.cs:263:13:263:27 | After case ...: [no-match] | semmle.label | no-match | -| CSharp7.cs:263:18:263:26 | String s2 | CSharp7.cs:264:17:264:50 | ...; | semmle.label | successor | +| CSharp7.cs:263:13:263:27 | case ...: | CSharp7.cs:263:18:263:26 | String s2 | semmle.label | successor | +| CSharp7.cs:263:18:263:26 | After String s2 [match] | CSharp7.cs:263:13:263:27 | After case ...: [match] | semmle.label | match | +| CSharp7.cs:263:18:263:26 | After String s2 [no-match] | CSharp7.cs:263:13:263:27 | After case ...: [no-match] | semmle.label | no-match | +| CSharp7.cs:263:18:263:26 | String s2 | CSharp7.cs:263:18:263:26 | After String s2 [match] | semmle.label | match | +| CSharp7.cs:263:18:263:26 | String s2 | CSharp7.cs:263:18:263:26 | After String s2 [no-match] | semmle.label | no-match | | CSharp7.cs:264:17:264:49 | After call to method WriteLine | CSharp7.cs:264:17:264:50 | After ...; | semmle.label | successor | | CSharp7.cs:264:17:264:49 | Before call to method WriteLine | CSharp7.cs:264:35:264:48 | Before $"..." | semmle.label | successor | | CSharp7.cs:264:17:264:49 | call to method WriteLine | CSharp7.cs:264:17:264:49 | After call to method WriteLine | semmle.label | successor | @@ -119,11 +131,13 @@ | CSharp7.cs:264:45:264:46 | access to local variable s2 | CSharp7.cs:264:44:264:47 | {...} | semmle.label | successor | | CSharp7.cs:265:17:265:22 | Before break; | CSharp7.cs:265:17:265:22 | break; | semmle.label | successor | | CSharp7.cs:265:17:265:22 | break; | CSharp7.cs:248:9:274:9 | After switch (...) {...} | semmle.label | break | -| CSharp7.cs:266:13:266:26 | After case ...: [match] | CSharp7.cs:266:18:266:23 | access to type Double | semmle.label | successor | +| CSharp7.cs:266:13:266:26 | After case ...: [match] | CSharp7.cs:267:17:267:44 | ...; | semmle.label | successor | | CSharp7.cs:266:13:266:26 | After case ...: [no-match] | CSharp7.cs:269:13:269:24 | case ...: | semmle.label | successor | -| CSharp7.cs:266:13:266:26 | case ...: | CSharp7.cs:266:13:266:26 | After case ...: [match] | semmle.label | match | -| CSharp7.cs:266:13:266:26 | case ...: | CSharp7.cs:266:13:266:26 | After case ...: [no-match] | semmle.label | no-match | -| CSharp7.cs:266:18:266:23 | access to type Double | CSharp7.cs:267:17:267:44 | ...; | semmle.label | successor | +| CSharp7.cs:266:13:266:26 | case ...: | CSharp7.cs:266:18:266:23 | access to type Double | semmle.label | successor | +| CSharp7.cs:266:18:266:23 | After access to type Double [match] | CSharp7.cs:266:13:266:26 | After case ...: [match] | semmle.label | match | +| CSharp7.cs:266:18:266:23 | After access to type Double [no-match] | CSharp7.cs:266:13:266:26 | After case ...: [no-match] | semmle.label | no-match | +| CSharp7.cs:266:18:266:23 | access to type Double | CSharp7.cs:266:18:266:23 | After access to type Double [match] | semmle.label | match | +| CSharp7.cs:266:18:266:23 | access to type Double | CSharp7.cs:266:18:266:23 | After access to type Double [no-match] | semmle.label | no-match | | CSharp7.cs:267:17:267:43 | After call to method WriteLine | CSharp7.cs:267:17:267:44 | After ...; | semmle.label | successor | | CSharp7.cs:267:17:267:43 | Before call to method WriteLine | CSharp7.cs:267:35:267:42 | "Double" | semmle.label | successor | | CSharp7.cs:267:17:267:43 | call to method WriteLine | CSharp7.cs:267:17:267:43 | After call to method WriteLine | semmle.label | successor | @@ -132,11 +146,13 @@ | CSharp7.cs:267:35:267:42 | "Double" | CSharp7.cs:267:17:267:43 | call to method WriteLine | semmle.label | successor | | CSharp7.cs:268:17:268:22 | Before break; | CSharp7.cs:268:17:268:22 | break; | semmle.label | successor | | CSharp7.cs:268:17:268:22 | break; | CSharp7.cs:248:9:274:9 | After switch (...) {...} | semmle.label | break | -| CSharp7.cs:269:13:269:24 | After case ...: [match] | CSharp7.cs:269:18:269:23 | Object v2 | semmle.label | successor | +| CSharp7.cs:269:13:269:24 | After case ...: [match] | CSharp7.cs:270:17:270:22 | Before break; | semmle.label | successor | | CSharp7.cs:269:13:269:24 | After case ...: [no-match] | CSharp7.cs:271:13:271:20 | default: | semmle.label | successor | -| CSharp7.cs:269:13:269:24 | case ...: | CSharp7.cs:269:13:269:24 | After case ...: [match] | semmle.label | match | -| CSharp7.cs:269:13:269:24 | case ...: | CSharp7.cs:269:13:269:24 | After case ...: [no-match] | semmle.label | no-match | -| CSharp7.cs:269:18:269:23 | Object v2 | CSharp7.cs:270:17:270:22 | Before break; | semmle.label | successor | +| CSharp7.cs:269:13:269:24 | case ...: | CSharp7.cs:269:18:269:23 | Object v2 | semmle.label | successor | +| CSharp7.cs:269:18:269:23 | After Object v2 [match] | CSharp7.cs:269:13:269:24 | After case ...: [match] | semmle.label | match | +| CSharp7.cs:269:18:269:23 | After Object v2 [no-match] | CSharp7.cs:269:13:269:24 | After case ...: [no-match] | semmle.label | no-match | +| CSharp7.cs:269:18:269:23 | Object v2 | CSharp7.cs:269:18:269:23 | After Object v2 [match] | semmle.label | match | +| CSharp7.cs:269:18:269:23 | Object v2 | CSharp7.cs:269:18:269:23 | After Object v2 [no-match] | semmle.label | no-match | | CSharp7.cs:270:17:270:22 | Before break; | CSharp7.cs:270:17:270:22 | break; | semmle.label | successor | | CSharp7.cs:270:17:270:22 | break; | CSharp7.cs:248:9:274:9 | After switch (...) {...} | semmle.label | break | | CSharp7.cs:271:13:271:20 | After default: [match] | CSharp7.cs:272:17:272:52 | ...; | semmle.label | successor | diff --git a/csharp/ql/test/library-tests/csharp8/switchexprcontrolflow.expected b/csharp/ql/test/library-tests/csharp8/switchexprcontrolflow.expected index 898a1ff4691..4493882fa47 100644 --- a/csharp/ql/test/library-tests/csharp8/switchexprcontrolflow.expected +++ b/csharp/ql/test/library-tests/csharp8/switchexprcontrolflow.expected @@ -12,10 +12,12 @@ | patterns.cs:100:20:100:20 | access to parameter x | patterns.cs:101:13:101:40 | ... => ... | semmle.label | successor | | patterns.cs:100:20:103:9 | ... switch { ... } | patterns.cs:100:20:100:20 | access to parameter x | semmle.label | successor | | patterns.cs:100:20:103:9 | After ... switch { ... } | patterns.cs:100:13:103:9 | String size = ... | semmle.label | successor | -| patterns.cs:101:13:101:17 | Int32 y | patterns.cs:101:24:101:29 | Before ... > ... | semmle.label | successor | -| patterns.cs:101:13:101:40 | ... => ... | patterns.cs:101:13:101:40 | After ... => ... [match] | semmle.label | match | -| patterns.cs:101:13:101:40 | ... => ... | patterns.cs:101:13:101:40 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:101:13:101:40 | After ... => ... [match] | patterns.cs:101:13:101:17 | Int32 y | semmle.label | successor | +| patterns.cs:101:13:101:17 | After Int32 y [match] | patterns.cs:101:13:101:40 | After ... => ... [match] | semmle.label | match | +| patterns.cs:101:13:101:17 | After Int32 y [no-match] | patterns.cs:101:13:101:40 | After ... => ... [no-match] | semmle.label | no-match | +| patterns.cs:101:13:101:17 | Int32 y | patterns.cs:101:13:101:17 | After Int32 y [match] | semmle.label | match | +| patterns.cs:101:13:101:17 | Int32 y | patterns.cs:101:13:101:17 | After Int32 y [no-match] | semmle.label | no-match | +| patterns.cs:101:13:101:40 | ... => ... | patterns.cs:101:13:101:17 | Int32 y | semmle.label | successor | +| patterns.cs:101:13:101:40 | After ... => ... [match] | patterns.cs:101:24:101:29 | Before ... > ... | semmle.label | successor | | patterns.cs:101:13:101:40 | After ... => ... [no-match] | patterns.cs:102:13:102:24 | ... => ... | semmle.label | successor | | patterns.cs:101:24:101:24 | access to local variable y | patterns.cs:101:28:101:29 | 10 | semmle.label | successor | | patterns.cs:101:24:101:29 | ... > ... | patterns.cs:101:24:101:29 | After ... > ... [false] | semmle.label | false | @@ -25,9 +27,10 @@ | patterns.cs:101:24:101:29 | Before ... > ... | patterns.cs:101:24:101:24 | access to local variable y | semmle.label | successor | | patterns.cs:101:28:101:29 | 10 | patterns.cs:101:24:101:29 | ... > ... | semmle.label | successor | | patterns.cs:101:34:101:40 | "large" | patterns.cs:100:20:103:9 | After ... switch { ... } | semmle.label | successor | -| patterns.cs:102:13:102:13 | _ | patterns.cs:102:18:102:24 | "small" | semmle.label | successor | -| patterns.cs:102:13:102:24 | ... => ... | patterns.cs:102:13:102:24 | After ... => ... [match] | semmle.label | match | -| patterns.cs:102:13:102:24 | After ... => ... [match] | patterns.cs:102:13:102:13 | _ | semmle.label | successor | +| patterns.cs:102:13:102:13 | After _ [match] | patterns.cs:102:13:102:24 | After ... => ... [match] | semmle.label | match | +| patterns.cs:102:13:102:13 | _ | patterns.cs:102:13:102:13 | After _ [match] | semmle.label | match | +| patterns.cs:102:13:102:24 | ... => ... | patterns.cs:102:13:102:13 | _ | semmle.label | successor | +| patterns.cs:102:13:102:24 | After ... => ... [match] | patterns.cs:102:18:102:24 | "small" | semmle.label | successor | | patterns.cs:102:18:102:24 | "small" | patterns.cs:100:20:103:9 | After ... switch { ... } | semmle.label | successor | | patterns.cs:105:9:105:27 | ... ...; | patterns.cs:105:13:105:18 | Before Int32 x0 = ... | semmle.label | successor | | patterns.cs:105:9:105:27 | After ... ...; | patterns.cs:108:9:112:10 | ...; | semmle.label | successor | @@ -60,13 +63,14 @@ | patterns.cs:108:29:108:30 | access to local variable y0 | patterns.cs:108:24:108:31 | (..., ...) | semmle.label | successor | | patterns.cs:110:13:110:17 | ( ... ) | patterns.cs:110:13:110:17 | After ( ... ) | semmle.label | successor | | patterns.cs:110:13:110:17 | After ( ... ) | patterns.cs:110:13:110:17 | { ... } | semmle.label | successor | -| patterns.cs:110:13:110:17 | After { ... } | patterns.cs:110:22:110:26 | Before (..., ...) | semmle.label | successor | +| patterns.cs:110:13:110:17 | After { ... } [match] | patterns.cs:110:13:110:26 | After ... => ... [match] | semmle.label | match | +| patterns.cs:110:13:110:17 | After { ... } [no-match] | patterns.cs:110:13:110:26 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:110:13:110:17 | Before ( ... ) | patterns.cs:110:14:110:14 | 0 | semmle.label | successor | | patterns.cs:110:13:110:17 | Before { ... } | patterns.cs:110:13:110:17 | Before ( ... ) | semmle.label | successor | -| patterns.cs:110:13:110:17 | { ... } | patterns.cs:110:13:110:17 | After { ... } | semmle.label | successor | -| patterns.cs:110:13:110:26 | ... => ... | patterns.cs:110:13:110:26 | After ... => ... [match] | semmle.label | match | -| patterns.cs:110:13:110:26 | ... => ... | patterns.cs:110:13:110:26 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:110:13:110:26 | After ... => ... [match] | patterns.cs:110:13:110:17 | Before { ... } | semmle.label | successor | +| patterns.cs:110:13:110:17 | { ... } | patterns.cs:110:13:110:17 | After { ... } [match] | semmle.label | match | +| patterns.cs:110:13:110:17 | { ... } | patterns.cs:110:13:110:17 | After { ... } [no-match] | semmle.label | no-match | +| patterns.cs:110:13:110:26 | ... => ... | patterns.cs:110:13:110:17 | Before { ... } | semmle.label | successor | +| patterns.cs:110:13:110:26 | After ... => ... [match] | patterns.cs:110:22:110:26 | Before (..., ...) | semmle.label | successor | | patterns.cs:110:13:110:26 | After ... => ... [no-match] | patterns.cs:111:13:111:26 | ... => ... | semmle.label | successor | | patterns.cs:110:14:110:14 | 0 | patterns.cs:110:16:110:16 | 1 | semmle.label | successor | | patterns.cs:110:16:110:16 | 1 | patterns.cs:110:13:110:17 | ( ... ) | semmle.label | successor | @@ -77,13 +81,14 @@ | patterns.cs:110:25:110:25 | 0 | patterns.cs:110:22:110:26 | (..., ...) | semmle.label | successor | | patterns.cs:111:13:111:17 | ( ... ) | patterns.cs:111:13:111:17 | After ( ... ) | semmle.label | successor | | patterns.cs:111:13:111:17 | After ( ... ) | patterns.cs:111:13:111:17 | { ... } | semmle.label | successor | -| patterns.cs:111:13:111:17 | After { ... } | patterns.cs:111:22:111:26 | Before (..., ...) | semmle.label | successor | +| patterns.cs:111:13:111:17 | After { ... } [match] | patterns.cs:111:13:111:26 | After ... => ... [match] | semmle.label | match | +| patterns.cs:111:13:111:17 | After { ... } [no-match] | patterns.cs:111:13:111:26 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:111:13:111:17 | Before ( ... ) | patterns.cs:111:14:111:14 | 1 | semmle.label | successor | | patterns.cs:111:13:111:17 | Before { ... } | patterns.cs:111:13:111:17 | Before ( ... ) | semmle.label | successor | -| patterns.cs:111:13:111:17 | { ... } | patterns.cs:111:13:111:17 | After { ... } | semmle.label | successor | -| patterns.cs:111:13:111:26 | ... => ... | patterns.cs:111:13:111:26 | After ... => ... [match] | semmle.label | match | -| patterns.cs:111:13:111:26 | ... => ... | patterns.cs:111:13:111:26 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:111:13:111:26 | After ... => ... [match] | patterns.cs:111:13:111:17 | Before { ... } | semmle.label | successor | +| patterns.cs:111:13:111:17 | { ... } | patterns.cs:111:13:111:17 | After { ... } [match] | semmle.label | match | +| patterns.cs:111:13:111:17 | { ... } | patterns.cs:111:13:111:17 | After { ... } [no-match] | semmle.label | no-match | +| patterns.cs:111:13:111:26 | ... => ... | patterns.cs:111:13:111:17 | Before { ... } | semmle.label | successor | +| patterns.cs:111:13:111:26 | After ... => ... [match] | patterns.cs:111:22:111:26 | Before (..., ...) | semmle.label | successor | | patterns.cs:111:13:111:26 | After ... => ... [no-match] | patterns.cs:108:24:112:9 | After ... switch { ... } | semmle.label | successor | | patterns.cs:111:14:111:14 | 1 | patterns.cs:111:16:111:16 | 0 | semmle.label | successor | | patterns.cs:111:16:111:16 | 0 | patterns.cs:111:13:111:17 | ( ... ) | semmle.label | successor | @@ -111,13 +116,14 @@ | patterns.cs:115:25:115:26 | access to local variable y0 | patterns.cs:115:20:115:27 | (..., ...) | semmle.label | successor | | patterns.cs:117:13:117:22 | ( ... ) | patterns.cs:117:13:117:22 | After ( ... ) | semmle.label | successor | | patterns.cs:117:13:117:22 | After ( ... ) | patterns.cs:117:13:117:22 | { ... } | semmle.label | successor | -| patterns.cs:117:13:117:22 | After { ... } | patterns.cs:117:27:117:33 | Before (..., ...) | semmle.label | successor | +| patterns.cs:117:13:117:22 | After { ... } [match] | patterns.cs:117:13:117:33 | After ... => ... [match] | semmle.label | match | +| patterns.cs:117:13:117:22 | After { ... } [no-match] | patterns.cs:117:13:117:33 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:117:13:117:22 | Before ( ... ) | patterns.cs:117:14:117:14 | 0 | semmle.label | successor | | patterns.cs:117:13:117:22 | Before { ... } | patterns.cs:117:13:117:22 | Before ( ... ) | semmle.label | successor | -| patterns.cs:117:13:117:22 | { ... } | patterns.cs:117:13:117:22 | After { ... } | semmle.label | successor | -| patterns.cs:117:13:117:33 | ... => ... | patterns.cs:117:13:117:33 | After ... => ... [match] | semmle.label | match | -| patterns.cs:117:13:117:33 | ... => ... | patterns.cs:117:13:117:33 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:117:13:117:33 | After ... => ... [match] | patterns.cs:117:13:117:22 | Before { ... } | semmle.label | successor | +| patterns.cs:117:13:117:22 | { ... } | patterns.cs:117:13:117:22 | After { ... } [match] | semmle.label | match | +| patterns.cs:117:13:117:22 | { ... } | patterns.cs:117:13:117:22 | After { ... } [no-match] | semmle.label | no-match | +| patterns.cs:117:13:117:33 | ... => ... | patterns.cs:117:13:117:22 | Before { ... } | semmle.label | successor | +| patterns.cs:117:13:117:33 | After ... => ... [match] | patterns.cs:117:27:117:33 | Before (..., ...) | semmle.label | successor | | patterns.cs:117:13:117:33 | After ... => ... [no-match] | patterns.cs:118:13:118:34 | ... => ... | semmle.label | successor | | patterns.cs:117:14:117:14 | 0 | patterns.cs:117:16:117:21 | Int32 y2 | semmle.label | successor | | patterns.cs:117:16:117:21 | Int32 y2 | patterns.cs:117:13:117:22 | ( ... ) | semmle.label | successor | @@ -128,13 +134,14 @@ | patterns.cs:117:32:117:32 | 0 | patterns.cs:117:27:117:33 | (..., ...) | semmle.label | successor | | patterns.cs:118:13:118:23 | ( ... ) | patterns.cs:118:13:118:23 | After ( ... ) | semmle.label | successor | | patterns.cs:118:13:118:23 | After ( ... ) | patterns.cs:118:13:118:23 | { ... } | semmle.label | successor | -| patterns.cs:118:13:118:23 | After { ... } | patterns.cs:118:28:118:34 | Before (..., ...) | semmle.label | successor | +| patterns.cs:118:13:118:23 | After { ... } [match] | patterns.cs:118:13:118:34 | After ... => ... [match] | semmle.label | match | +| patterns.cs:118:13:118:23 | After { ... } [no-match] | patterns.cs:118:13:118:34 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:118:13:118:23 | Before ( ... ) | patterns.cs:118:14:118:19 | Int32 x2 | semmle.label | successor | | patterns.cs:118:13:118:23 | Before { ... } | patterns.cs:118:13:118:23 | Before ( ... ) | semmle.label | successor | -| patterns.cs:118:13:118:23 | { ... } | patterns.cs:118:13:118:23 | After { ... } | semmle.label | successor | -| patterns.cs:118:13:118:34 | ... => ... | patterns.cs:118:13:118:34 | After ... => ... [match] | semmle.label | match | -| patterns.cs:118:13:118:34 | ... => ... | patterns.cs:118:13:118:34 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:118:13:118:34 | After ... => ... [match] | patterns.cs:118:13:118:23 | Before { ... } | semmle.label | successor | +| patterns.cs:118:13:118:23 | { ... } | patterns.cs:118:13:118:23 | After { ... } [match] | semmle.label | match | +| patterns.cs:118:13:118:23 | { ... } | patterns.cs:118:13:118:23 | After { ... } [no-match] | semmle.label | no-match | +| patterns.cs:118:13:118:34 | ... => ... | patterns.cs:118:13:118:23 | Before { ... } | semmle.label | successor | +| patterns.cs:118:13:118:34 | After ... => ... [match] | patterns.cs:118:28:118:34 | Before (..., ...) | semmle.label | successor | | patterns.cs:118:13:118:34 | After ... => ... [no-match] | patterns.cs:119:13:119:38 | ... => ... | semmle.label | successor | | patterns.cs:118:14:118:19 | Int32 x2 | patterns.cs:118:22:118:22 | 0 | semmle.label | successor | | patterns.cs:118:22:118:22 | 0 | patterns.cs:118:13:118:23 | ( ... ) | semmle.label | successor | @@ -145,13 +152,14 @@ | patterns.cs:118:32:118:33 | access to local variable x2 | patterns.cs:118:28:118:34 | (..., ...) | semmle.label | successor | | patterns.cs:119:13:119:28 | ( ... ) | patterns.cs:119:13:119:28 | After ( ... ) | semmle.label | successor | | patterns.cs:119:13:119:28 | After ( ... ) | patterns.cs:119:13:119:28 | { ... } | semmle.label | successor | -| patterns.cs:119:13:119:28 | After { ... } | patterns.cs:119:33:119:38 | Before (..., ...) | semmle.label | successor | +| patterns.cs:119:13:119:28 | After { ... } [match] | patterns.cs:119:13:119:38 | After ... => ... [match] | semmle.label | match | +| patterns.cs:119:13:119:28 | After { ... } [no-match] | patterns.cs:119:13:119:38 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:119:13:119:28 | Before ( ... ) | patterns.cs:119:14:119:19 | Int32 x2 | semmle.label | successor | | patterns.cs:119:13:119:28 | Before { ... } | patterns.cs:119:13:119:28 | Before ( ... ) | semmle.label | successor | -| patterns.cs:119:13:119:28 | { ... } | patterns.cs:119:13:119:28 | After { ... } | semmle.label | successor | -| patterns.cs:119:13:119:38 | ... => ... | patterns.cs:119:13:119:38 | After ... => ... [match] | semmle.label | match | -| patterns.cs:119:13:119:38 | ... => ... | patterns.cs:119:13:119:38 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:119:13:119:38 | After ... => ... [match] | patterns.cs:119:13:119:28 | Before { ... } | semmle.label | successor | +| patterns.cs:119:13:119:28 | { ... } | patterns.cs:119:13:119:28 | After { ... } [match] | semmle.label | match | +| patterns.cs:119:13:119:28 | { ... } | patterns.cs:119:13:119:28 | After { ... } [no-match] | semmle.label | no-match | +| patterns.cs:119:13:119:38 | ... => ... | patterns.cs:119:13:119:28 | Before { ... } | semmle.label | successor | +| patterns.cs:119:13:119:38 | After ... => ... [match] | patterns.cs:119:33:119:38 | Before (..., ...) | semmle.label | successor | | patterns.cs:119:13:119:38 | After ... => ... [no-match] | patterns.cs:115:20:120:9 | After ... switch { ... } | semmle.label | successor | | patterns.cs:119:14:119:19 | Int32 x2 | patterns.cs:119:22:119:27 | Int32 y2 | semmle.label | successor | | patterns.cs:119:22:119:27 | Int32 y2 | patterns.cs:119:13:119:28 | ( ... ) | semmle.label | successor | @@ -193,12 +201,13 @@ | patterns.cs:126:17:132:9 | ... switch { ... } | patterns.cs:126:17:126:17 | access to local variable s | semmle.label | successor | | patterns.cs:126:17:132:9 | After ... switch { ... } | patterns.cs:126:13:132:9 | Int32 r = ... | semmle.label | successor | | patterns.cs:128:13:128:20 | access to type MyStruct | patterns.cs:128:22:128:33 | Before { ... } | semmle.label | successor | -| patterns.cs:128:13:128:33 | After { ... } | patterns.cs:128:40:128:44 | Before ... > ... | semmle.label | successor | +| patterns.cs:128:13:128:33 | After { ... } [match] | patterns.cs:128:13:128:49 | After ... => ... [match] | semmle.label | match | +| patterns.cs:128:13:128:33 | After { ... } [no-match] | patterns.cs:128:13:128:49 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:128:13:128:33 | Before { ... } | patterns.cs:128:13:128:20 | access to type MyStruct | semmle.label | successor | -| patterns.cs:128:13:128:33 | { ... } | patterns.cs:128:13:128:33 | After { ... } | semmle.label | successor | -| patterns.cs:128:13:128:49 | ... => ... | patterns.cs:128:13:128:49 | After ... => ... [match] | semmle.label | match | -| patterns.cs:128:13:128:49 | ... => ... | patterns.cs:128:13:128:49 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:128:13:128:49 | After ... => ... [match] | patterns.cs:128:13:128:33 | Before { ... } | semmle.label | successor | +| patterns.cs:128:13:128:33 | { ... } | patterns.cs:128:13:128:33 | After { ... } [match] | semmle.label | match | +| patterns.cs:128:13:128:33 | { ... } | patterns.cs:128:13:128:33 | After { ... } [no-match] | semmle.label | no-match | +| patterns.cs:128:13:128:49 | ... => ... | patterns.cs:128:13:128:33 | Before { ... } | semmle.label | successor | +| patterns.cs:128:13:128:49 | After ... => ... [match] | patterns.cs:128:40:128:44 | Before ... > ... | semmle.label | successor | | patterns.cs:128:13:128:49 | After ... => ... [no-match] | patterns.cs:129:13:129:38 | ... => ... | semmle.label | successor | | patterns.cs:128:22:128:33 | After { ... } | patterns.cs:128:13:128:33 | { ... } | semmle.label | successor | | patterns.cs:128:22:128:33 | Before { ... } | patterns.cs:128:27:128:31 | Int32 x | semmle.label | successor | @@ -213,13 +222,14 @@ | patterns.cs:128:44:128:44 | 2 | patterns.cs:128:40:128:44 | ... > ... | semmle.label | successor | | patterns.cs:128:49:128:49 | 0 | patterns.cs:126:17:132:9 | After ... switch { ... } | semmle.label | successor | | patterns.cs:129:13:129:20 | access to type MyStruct | patterns.cs:129:22:129:30 | Before { ... } | semmle.label | successor | -| patterns.cs:129:13:129:33 | After { ... } | patterns.cs:129:38:129:38 | 1 | semmle.label | successor | +| patterns.cs:129:13:129:33 | After { ... } [match] | patterns.cs:129:13:129:38 | After ... => ... [match] | semmle.label | match | +| patterns.cs:129:13:129:33 | After { ... } [no-match] | patterns.cs:129:13:129:38 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:129:13:129:33 | Before { ... } | patterns.cs:129:13:129:33 | MyStruct ms | semmle.label | successor | | patterns.cs:129:13:129:33 | MyStruct ms | patterns.cs:129:13:129:20 | access to type MyStruct | semmle.label | successor | -| patterns.cs:129:13:129:33 | { ... } | patterns.cs:129:13:129:33 | After { ... } | semmle.label | successor | -| patterns.cs:129:13:129:38 | ... => ... | patterns.cs:129:13:129:38 | After ... => ... [match] | semmle.label | match | -| patterns.cs:129:13:129:38 | ... => ... | patterns.cs:129:13:129:38 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:129:13:129:38 | After ... => ... [match] | patterns.cs:129:13:129:33 | Before { ... } | semmle.label | successor | +| patterns.cs:129:13:129:33 | { ... } | patterns.cs:129:13:129:33 | After { ... } [match] | semmle.label | match | +| patterns.cs:129:13:129:33 | { ... } | patterns.cs:129:13:129:33 | After { ... } [no-match] | semmle.label | no-match | +| patterns.cs:129:13:129:38 | ... => ... | patterns.cs:129:13:129:33 | Before { ... } | semmle.label | successor | +| patterns.cs:129:13:129:38 | After ... => ... [match] | patterns.cs:129:38:129:38 | 1 | semmle.label | successor | | patterns.cs:129:13:129:38 | After ... => ... [no-match] | patterns.cs:130:13:130:23 | ... => ... | semmle.label | successor | | patterns.cs:129:22:129:30 | After { ... } | patterns.cs:129:13:129:33 | { ... } | semmle.label | successor | | patterns.cs:129:22:129:30 | Before { ... } | patterns.cs:129:27:129:28 | 10 | semmle.label | successor | @@ -228,23 +238,25 @@ | patterns.cs:129:38:129:38 | 1 | patterns.cs:126:17:132:9 | After ... switch { ... } | semmle.label | successor | | patterns.cs:130:13:130:18 | ( ... ) | patterns.cs:130:13:130:18 | After ( ... ) | semmle.label | successor | | patterns.cs:130:13:130:18 | After ( ... ) | patterns.cs:130:13:130:18 | { ... } | semmle.label | successor | -| patterns.cs:130:13:130:18 | After { ... } | patterns.cs:130:23:130:23 | 2 | semmle.label | successor | +| patterns.cs:130:13:130:18 | After { ... } [match] | patterns.cs:130:13:130:23 | After ... => ... [match] | semmle.label | match | +| patterns.cs:130:13:130:18 | After { ... } [no-match] | patterns.cs:130:13:130:23 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:130:13:130:18 | Before ( ... ) | patterns.cs:130:14:130:14 | 1 | semmle.label | successor | | patterns.cs:130:13:130:18 | Before { ... } | patterns.cs:130:13:130:18 | Before ( ... ) | semmle.label | successor | -| patterns.cs:130:13:130:18 | { ... } | patterns.cs:130:13:130:18 | After { ... } | semmle.label | successor | -| patterns.cs:130:13:130:23 | ... => ... | patterns.cs:130:13:130:23 | After ... => ... [match] | semmle.label | match | -| patterns.cs:130:13:130:23 | ... => ... | patterns.cs:130:13:130:23 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:130:13:130:23 | After ... => ... [match] | patterns.cs:130:13:130:18 | Before { ... } | semmle.label | successor | +| patterns.cs:130:13:130:18 | { ... } | patterns.cs:130:13:130:18 | After { ... } [match] | semmle.label | match | +| patterns.cs:130:13:130:18 | { ... } | patterns.cs:130:13:130:18 | After { ... } [no-match] | semmle.label | no-match | +| patterns.cs:130:13:130:23 | ... => ... | patterns.cs:130:13:130:18 | Before { ... } | semmle.label | successor | +| patterns.cs:130:13:130:23 | After ... => ... [match] | patterns.cs:130:23:130:23 | 2 | semmle.label | successor | | patterns.cs:130:13:130:23 | After ... => ... [no-match] | patterns.cs:131:13:131:27 | ... => ... | semmle.label | successor | | patterns.cs:130:14:130:14 | 1 | patterns.cs:130:17:130:17 | 2 | semmle.label | successor | | patterns.cs:130:17:130:17 | 2 | patterns.cs:130:13:130:18 | ( ... ) | semmle.label | successor | | patterns.cs:130:23:130:23 | 2 | patterns.cs:126:17:132:9 | After ... switch { ... } | semmle.label | successor | -| patterns.cs:131:13:131:22 | (..., ...) | patterns.cs:131:13:131:22 | After (..., ...) | semmle.label | successor | -| patterns.cs:131:13:131:22 | After (..., ...) | patterns.cs:131:27:131:27 | 3 | semmle.label | successor | +| patterns.cs:131:13:131:22 | (..., ...) | patterns.cs:131:13:131:22 | After (..., ...) [match] | semmle.label | match | +| patterns.cs:131:13:131:22 | (..., ...) | patterns.cs:131:13:131:22 | After (..., ...) [no-match] | semmle.label | no-match | +| patterns.cs:131:13:131:22 | After (..., ...) [match] | patterns.cs:131:13:131:27 | After ... => ... [match] | semmle.label | match | +| patterns.cs:131:13:131:22 | After (..., ...) [no-match] | patterns.cs:131:13:131:27 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:131:13:131:22 | Before (..., ...) | patterns.cs:131:18:131:18 | Int32 x | semmle.label | successor | -| patterns.cs:131:13:131:27 | ... => ... | patterns.cs:131:13:131:27 | After ... => ... [match] | semmle.label | match | -| patterns.cs:131:13:131:27 | ... => ... | patterns.cs:131:13:131:27 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:131:13:131:27 | After ... => ... [match] | patterns.cs:131:13:131:22 | Before (..., ...) | semmle.label | successor | +| patterns.cs:131:13:131:27 | ... => ... | patterns.cs:131:13:131:22 | Before (..., ...) | semmle.label | successor | +| patterns.cs:131:13:131:27 | After ... => ... [match] | patterns.cs:131:27:131:27 | 3 | semmle.label | successor | | patterns.cs:131:13:131:27 | After ... => ... [no-match] | patterns.cs:126:17:132:9 | After ... switch { ... } | semmle.label | successor | | patterns.cs:131:18:131:18 | Int32 x | patterns.cs:131:21:131:21 | _ | semmle.label | successor | | patterns.cs:131:21:131:21 | _ | patterns.cs:131:13:131:22 | (..., ...) | semmle.label | successor | @@ -262,10 +274,12 @@ | patterns.cs:136:17:136:17 | access to parameter o | patterns.cs:138:17:138:50 | ... => ... | semmle.label | successor | | patterns.cs:136:17:143:13 | ... switch { ... } | patterns.cs:136:17:136:17 | access to parameter o | semmle.label | successor | | patterns.cs:136:17:143:13 | After ... switch { ... } | patterns.cs:136:13:143:13 | ... = ... | semmle.label | successor | -| patterns.cs:138:17:138:17 | 1 | patterns.cs:138:22:138:50 | Before throw ... | semmle.label | successor | -| patterns.cs:138:17:138:50 | ... => ... | patterns.cs:138:17:138:50 | After ... => ... [match] | semmle.label | match | -| patterns.cs:138:17:138:50 | ... => ... | patterns.cs:138:17:138:50 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:138:17:138:50 | After ... => ... [match] | patterns.cs:138:17:138:17 | 1 | semmle.label | successor | +| patterns.cs:138:17:138:17 | 1 | patterns.cs:138:17:138:17 | After 1 [match] | semmle.label | match | +| patterns.cs:138:17:138:17 | 1 | patterns.cs:138:17:138:17 | After 1 [no-match] | semmle.label | no-match | +| patterns.cs:138:17:138:17 | After 1 [match] | patterns.cs:138:17:138:50 | After ... => ... [match] | semmle.label | match | +| patterns.cs:138:17:138:17 | After 1 [no-match] | patterns.cs:138:17:138:50 | After ... => ... [no-match] | semmle.label | no-match | +| patterns.cs:138:17:138:50 | ... => ... | patterns.cs:138:17:138:17 | 1 | semmle.label | successor | +| patterns.cs:138:17:138:50 | After ... => ... [match] | patterns.cs:138:22:138:50 | Before throw ... | semmle.label | successor | | patterns.cs:138:17:138:50 | After ... => ... [no-match] | patterns.cs:139:17:139:22 | ... => ... | semmle.label | successor | | patterns.cs:138:22:138:50 | Before throw ... | patterns.cs:138:28:138:50 | Before object creation of type ArgumentException | semmle.label | successor | | patterns.cs:138:22:138:50 | throw ... | patterns.cs:145:9:148:9 | catch (...) {...} | semmle.label | exception | @@ -273,16 +287,20 @@ | patterns.cs:138:28:138:50 | Before object creation of type ArgumentException | patterns.cs:138:28:138:50 | object creation of type ArgumentException | semmle.label | successor | | patterns.cs:138:28:138:50 | object creation of type ArgumentException | patterns.cs:138:28:138:50 | After object creation of type ArgumentException | semmle.label | successor | | patterns.cs:138:28:138:50 | object creation of type ArgumentException | patterns.cs:145:9:148:9 | catch (...) {...} | semmle.label | exception | -| patterns.cs:139:17:139:17 | 2 | patterns.cs:139:22:139:22 | 3 | semmle.label | successor | -| patterns.cs:139:17:139:22 | ... => ... | patterns.cs:139:17:139:22 | After ... => ... [match] | semmle.label | match | -| patterns.cs:139:17:139:22 | ... => ... | patterns.cs:139:17:139:22 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:139:17:139:22 | After ... => ... [match] | patterns.cs:139:17:139:17 | 2 | semmle.label | successor | +| patterns.cs:139:17:139:17 | 2 | patterns.cs:139:17:139:17 | After 2 [match] | semmle.label | match | +| patterns.cs:139:17:139:17 | 2 | patterns.cs:139:17:139:17 | After 2 [no-match] | semmle.label | no-match | +| patterns.cs:139:17:139:17 | After 2 [match] | patterns.cs:139:17:139:22 | After ... => ... [match] | semmle.label | match | +| patterns.cs:139:17:139:17 | After 2 [no-match] | patterns.cs:139:17:139:22 | After ... => ... [no-match] | semmle.label | no-match | +| patterns.cs:139:17:139:22 | ... => ... | patterns.cs:139:17:139:17 | 2 | semmle.label | successor | +| patterns.cs:139:17:139:22 | After ... => ... [match] | patterns.cs:139:22:139:22 | 3 | semmle.label | successor | | patterns.cs:139:17:139:22 | After ... => ... [no-match] | patterns.cs:140:17:140:42 | ... => ... | semmle.label | successor | | patterns.cs:139:22:139:22 | 3 | patterns.cs:136:17:143:13 | After ... switch { ... } | semmle.label | successor | -| patterns.cs:140:17:140:24 | Object y | patterns.cs:140:31:140:37 | Before ... is ... | semmle.label | successor | -| patterns.cs:140:17:140:42 | ... => ... | patterns.cs:140:17:140:42 | After ... => ... [match] | semmle.label | match | -| patterns.cs:140:17:140:42 | ... => ... | patterns.cs:140:17:140:42 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:140:17:140:42 | After ... => ... [match] | patterns.cs:140:17:140:24 | Object y | semmle.label | successor | +| patterns.cs:140:17:140:24 | After Object y [match] | patterns.cs:140:17:140:42 | After ... => ... [match] | semmle.label | match | +| patterns.cs:140:17:140:24 | After Object y [no-match] | patterns.cs:140:17:140:42 | After ... => ... [no-match] | semmle.label | no-match | +| patterns.cs:140:17:140:24 | Object y | patterns.cs:140:17:140:24 | After Object y [match] | semmle.label | match | +| patterns.cs:140:17:140:24 | Object y | patterns.cs:140:17:140:24 | After Object y [no-match] | semmle.label | no-match | +| patterns.cs:140:17:140:42 | ... => ... | patterns.cs:140:17:140:24 | Object y | semmle.label | successor | +| patterns.cs:140:17:140:42 | After ... => ... [match] | patterns.cs:140:31:140:37 | Before ... is ... | semmle.label | successor | | patterns.cs:140:17:140:42 | After ... => ... [no-match] | patterns.cs:141:17:141:29 | ... => ... | semmle.label | successor | | patterns.cs:140:31:140:31 | access to local variable y | patterns.cs:140:31:140:37 | ... is ... | semmle.label | successor | | patterns.cs:140:31:140:37 | ... is ... | patterns.cs:140:31:140:37 | After ... is ... [false] | semmle.label | false | @@ -296,19 +314,22 @@ | patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:36:140:37 | After { ... } | semmle.label | successor | | patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:36:140:37 | { ... } | semmle.label | successor | | patterns.cs:140:42:140:42 | 4 | patterns.cs:136:17:143:13 | After ... switch { ... } | semmle.label | successor | -| patterns.cs:141:17:141:22 | access to type String | patterns.cs:141:29:141:29 | 5 | semmle.label | successor | -| patterns.cs:141:17:141:29 | ... => ... | patterns.cs:141:17:141:29 | After ... => ... [match] | semmle.label | match | -| patterns.cs:141:17:141:29 | ... => ... | patterns.cs:141:17:141:29 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:141:17:141:29 | After ... => ... [match] | patterns.cs:141:17:141:22 | access to type String | semmle.label | successor | +| patterns.cs:141:17:141:22 | After access to type String [match] | patterns.cs:141:17:141:29 | After ... => ... [match] | semmle.label | match | +| patterns.cs:141:17:141:22 | After access to type String [no-match] | patterns.cs:141:17:141:29 | After ... => ... [no-match] | semmle.label | no-match | +| patterns.cs:141:17:141:22 | access to type String | patterns.cs:141:17:141:22 | After access to type String [match] | semmle.label | match | +| patterns.cs:141:17:141:22 | access to type String | patterns.cs:141:17:141:22 | After access to type String [no-match] | semmle.label | no-match | +| patterns.cs:141:17:141:29 | ... => ... | patterns.cs:141:17:141:22 | access to type String | semmle.label | successor | +| patterns.cs:141:17:141:29 | After ... => ... [match] | patterns.cs:141:29:141:29 | 5 | semmle.label | successor | | patterns.cs:141:17:141:29 | After ... => ... [no-match] | patterns.cs:142:17:142:41 | ... => ... | semmle.label | successor | | patterns.cs:141:29:141:29 | 5 | patterns.cs:136:17:143:13 | After ... switch { ... } | semmle.label | successor | | patterns.cs:142:17:142:24 | access to type MyStruct | patterns.cs:142:26:142:34 | Before { ... } | semmle.label | successor | -| patterns.cs:142:17:142:36 | After { ... } | patterns.cs:142:41:142:41 | 6 | semmle.label | successor | +| patterns.cs:142:17:142:36 | After { ... } [match] | patterns.cs:142:17:142:41 | After ... => ... [match] | semmle.label | match | +| patterns.cs:142:17:142:36 | After { ... } [no-match] | patterns.cs:142:17:142:41 | After ... => ... [no-match] | semmle.label | no-match | | patterns.cs:142:17:142:36 | Before { ... } | patterns.cs:142:17:142:24 | access to type MyStruct | semmle.label | successor | -| patterns.cs:142:17:142:36 | { ... } | patterns.cs:142:17:142:36 | After { ... } | semmle.label | successor | -| patterns.cs:142:17:142:41 | ... => ... | patterns.cs:142:17:142:41 | After ... => ... [match] | semmle.label | match | -| patterns.cs:142:17:142:41 | ... => ... | patterns.cs:142:17:142:41 | After ... => ... [no-match] | semmle.label | no-match | -| patterns.cs:142:17:142:41 | After ... => ... [match] | patterns.cs:142:17:142:36 | Before { ... } | semmle.label | successor | +| patterns.cs:142:17:142:36 | { ... } | patterns.cs:142:17:142:36 | After { ... } [match] | semmle.label | match | +| patterns.cs:142:17:142:36 | { ... } | patterns.cs:142:17:142:36 | After { ... } [no-match] | semmle.label | no-match | +| patterns.cs:142:17:142:41 | ... => ... | patterns.cs:142:17:142:36 | Before { ... } | semmle.label | successor | +| patterns.cs:142:17:142:41 | After ... => ... [match] | patterns.cs:142:41:142:41 | 6 | semmle.label | successor | | patterns.cs:142:17:142:41 | After ... => ... [no-match] | patterns.cs:136:17:143:13 | After ... switch { ... } | semmle.label | successor | | patterns.cs:142:26:142:34 | After { ... } | patterns.cs:142:17:142:36 | { ... } | semmle.label | successor | | patterns.cs:142:26:142:34 | Before { ... } | patterns.cs:142:31:142:32 | 10 | semmle.label | successor | diff --git a/csharp/ql/test/library-tests/csharp8/switchstmtctrlflow.expected b/csharp/ql/test/library-tests/csharp8/switchstmtctrlflow.expected index 0f9769342d1..ee5851bbd8f 100644 --- a/csharp/ql/test/library-tests/csharp8/switchstmtctrlflow.expected +++ b/csharp/ql/test/library-tests/csharp8/switchstmtctrlflow.expected @@ -22,11 +22,13 @@ | patterns.cs:36:9:44:9 | After switch (...) {...} | patterns.cs:46:9:63:9 | switch (...) {...} | semmle.label | successor | | patterns.cs:36:9:44:9 | switch (...) {...} | patterns.cs:36:17:36:17 | access to local variable s | semmle.label | successor | | patterns.cs:36:17:36:17 | access to local variable s | patterns.cs:38:13:38:47 | case ...: | semmle.label | successor | -| patterns.cs:38:13:38:47 | After case ...: [match] | patterns.cs:38:18:38:29 | MyStruct ms1 | semmle.label | successor | +| patterns.cs:38:13:38:47 | After case ...: [match] | patterns.cs:38:36:38:46 | Before ... == ... | semmle.label | successor | | patterns.cs:38:13:38:47 | After case ...: [no-match] | patterns.cs:41:13:41:46 | case ...: | semmle.label | successor | -| patterns.cs:38:13:38:47 | case ...: | patterns.cs:38:13:38:47 | After case ...: [match] | semmle.label | match | -| patterns.cs:38:13:38:47 | case ...: | patterns.cs:38:13:38:47 | After case ...: [no-match] | semmle.label | no-match | -| patterns.cs:38:18:38:29 | MyStruct ms1 | patterns.cs:38:36:38:46 | Before ... == ... | semmle.label | successor | +| patterns.cs:38:13:38:47 | case ...: | patterns.cs:38:18:38:29 | MyStruct ms1 | semmle.label | successor | +| patterns.cs:38:18:38:29 | After MyStruct ms1 [match] | patterns.cs:38:13:38:47 | After case ...: [match] | semmle.label | match | +| patterns.cs:38:18:38:29 | After MyStruct ms1 [no-match] | patterns.cs:38:13:38:47 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:38:18:38:29 | MyStruct ms1 | patterns.cs:38:18:38:29 | After MyStruct ms1 [match] | semmle.label | match | +| patterns.cs:38:18:38:29 | MyStruct ms1 | patterns.cs:38:18:38:29 | After MyStruct ms1 [no-match] | semmle.label | no-match | | patterns.cs:38:36:38:38 | access to local variable ms1 | patterns.cs:38:36:38:40 | access to field X | semmle.label | successor | | patterns.cs:38:36:38:40 | After access to field X | patterns.cs:38:45:38:46 | 10 | semmle.label | successor | | patterns.cs:38:36:38:40 | Before access to field X | patterns.cs:38:36:38:38 | access to local variable ms1 | semmle.label | successor | @@ -45,11 +47,13 @@ | patterns.cs:39:35:39:54 | "Hit the breakpoint" | patterns.cs:39:17:39:55 | call to method WriteLine | semmle.label | successor | | patterns.cs:40:17:40:22 | Before break; | patterns.cs:40:17:40:22 | break; | semmle.label | successor | | patterns.cs:40:17:40:22 | break; | patterns.cs:36:9:44:9 | After switch (...) {...} | semmle.label | break | -| patterns.cs:41:13:41:46 | After case ...: [match] | patterns.cs:41:18:41:29 | MyStruct ms2 | semmle.label | successor | +| patterns.cs:41:13:41:46 | After case ...: [match] | patterns.cs:41:36:41:45 | Before ... < ... | semmle.label | successor | | patterns.cs:41:13:41:46 | After case ...: [no-match] | patterns.cs:36:9:44:9 | After switch (...) {...} | semmle.label | successor | -| patterns.cs:41:13:41:46 | case ...: | patterns.cs:41:13:41:46 | After case ...: [match] | semmle.label | match | -| patterns.cs:41:13:41:46 | case ...: | patterns.cs:41:13:41:46 | After case ...: [no-match] | semmle.label | no-match | -| patterns.cs:41:18:41:29 | MyStruct ms2 | patterns.cs:41:36:41:45 | Before ... < ... | semmle.label | successor | +| patterns.cs:41:13:41:46 | case ...: | patterns.cs:41:18:41:29 | MyStruct ms2 | semmle.label | successor | +| patterns.cs:41:18:41:29 | After MyStruct ms2 [match] | patterns.cs:41:13:41:46 | After case ...: [match] | semmle.label | match | +| patterns.cs:41:18:41:29 | After MyStruct ms2 [no-match] | patterns.cs:41:13:41:46 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:41:18:41:29 | MyStruct ms2 | patterns.cs:41:18:41:29 | After MyStruct ms2 [match] | semmle.label | match | +| patterns.cs:41:18:41:29 | MyStruct ms2 | patterns.cs:41:18:41:29 | After MyStruct ms2 [no-match] | semmle.label | no-match | | patterns.cs:41:36:41:38 | access to local variable ms2 | patterns.cs:41:36:41:40 | access to field X | semmle.label | successor | | patterns.cs:41:36:41:40 | After access to field X | patterns.cs:41:44:41:45 | 10 | semmle.label | successor | | patterns.cs:41:36:41:40 | Before access to field X | patterns.cs:41:36:41:38 | access to local variable ms2 | semmle.label | successor | @@ -71,14 +75,15 @@ | patterns.cs:46:9:63:9 | After switch (...) {...} | patterns.cs:65:9:73:9 | switch (...) {...} | semmle.label | successor | | patterns.cs:46:9:63:9 | switch (...) {...} | patterns.cs:46:17:46:17 | access to local variable s | semmle.label | successor | | patterns.cs:46:17:46:17 | access to local variable s | patterns.cs:48:13:48:50 | case ...: | semmle.label | successor | -| patterns.cs:48:13:48:50 | After case ...: [match] | patterns.cs:48:18:48:38 | Before { ... } | semmle.label | successor | +| patterns.cs:48:13:48:50 | After case ...: [match] | patterns.cs:48:45:48:49 | Before ... > ... | semmle.label | successor | | patterns.cs:48:13:48:50 | After case ...: [no-match] | patterns.cs:51:13:51:39 | case ...: | semmle.label | successor | -| patterns.cs:48:13:48:50 | case ...: | patterns.cs:48:13:48:50 | After case ...: [match] | semmle.label | match | -| patterns.cs:48:13:48:50 | case ...: | patterns.cs:48:13:48:50 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:48:13:48:50 | case ...: | patterns.cs:48:18:48:38 | Before { ... } | semmle.label | successor | | patterns.cs:48:18:48:25 | access to type MyStruct | patterns.cs:48:27:48:38 | Before { ... } | semmle.label | successor | -| patterns.cs:48:18:48:38 | After { ... } | patterns.cs:48:45:48:49 | Before ... > ... | semmle.label | successor | +| patterns.cs:48:18:48:38 | After { ... } [match] | patterns.cs:48:13:48:50 | After case ...: [match] | semmle.label | match | +| patterns.cs:48:18:48:38 | After { ... } [no-match] | patterns.cs:48:13:48:50 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:48:18:48:38 | Before { ... } | patterns.cs:48:18:48:25 | access to type MyStruct | semmle.label | successor | -| patterns.cs:48:18:48:38 | { ... } | patterns.cs:48:18:48:38 | After { ... } | semmle.label | successor | +| patterns.cs:48:18:48:38 | { ... } | patterns.cs:48:18:48:38 | After { ... } [match] | semmle.label | match | +| patterns.cs:48:18:48:38 | { ... } | patterns.cs:48:18:48:38 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:48:27:48:38 | After { ... } | patterns.cs:48:18:48:38 | { ... } | semmle.label | successor | | patterns.cs:48:27:48:38 | Before { ... } | patterns.cs:48:32:48:36 | Int32 x | semmle.label | successor | | patterns.cs:48:27:48:38 | { ... } | patterns.cs:48:27:48:38 | After { ... } | semmle.label | successor | @@ -98,15 +103,16 @@ | patterns.cs:49:35:49:35 | access to local variable x | patterns.cs:49:17:49:36 | call to method WriteLine | semmle.label | successor | | patterns.cs:50:17:50:22 | Before break; | patterns.cs:50:17:50:22 | break; | semmle.label | successor | | patterns.cs:50:17:50:22 | break; | patterns.cs:46:9:63:9 | After switch (...) {...} | semmle.label | break | -| patterns.cs:51:13:51:39 | After case ...: [match] | patterns.cs:51:18:51:38 | Before { ... } | semmle.label | successor | +| patterns.cs:51:13:51:39 | After case ...: [match] | patterns.cs:52:17:52:56 | ...; | semmle.label | successor | | patterns.cs:51:13:51:39 | After case ...: [no-match] | patterns.cs:54:13:54:43 | case ...: | semmle.label | successor | -| patterns.cs:51:13:51:39 | case ...: | patterns.cs:51:13:51:39 | After case ...: [match] | semmle.label | match | -| patterns.cs:51:13:51:39 | case ...: | patterns.cs:51:13:51:39 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:51:13:51:39 | case ...: | patterns.cs:51:18:51:38 | Before { ... } | semmle.label | successor | | patterns.cs:51:18:51:25 | access to type MyStruct | patterns.cs:51:27:51:35 | Before { ... } | semmle.label | successor | -| patterns.cs:51:18:51:38 | After { ... } | patterns.cs:52:17:52:56 | ...; | semmle.label | successor | +| patterns.cs:51:18:51:38 | After { ... } [match] | patterns.cs:51:13:51:39 | After case ...: [match] | semmle.label | match | +| patterns.cs:51:18:51:38 | After { ... } [no-match] | patterns.cs:51:13:51:39 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:51:18:51:38 | Before { ... } | patterns.cs:51:18:51:38 | MyStruct ms | semmle.label | successor | | patterns.cs:51:18:51:38 | MyStruct ms | patterns.cs:51:18:51:25 | access to type MyStruct | semmle.label | successor | -| patterns.cs:51:18:51:38 | { ... } | patterns.cs:51:18:51:38 | After { ... } | semmle.label | successor | +| patterns.cs:51:18:51:38 | { ... } | patterns.cs:51:18:51:38 | After { ... } [match] | semmle.label | match | +| patterns.cs:51:18:51:38 | { ... } | patterns.cs:51:18:51:38 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:51:27:51:35 | After { ... } | patterns.cs:51:18:51:38 | { ... } | semmle.label | successor | | patterns.cs:51:27:51:35 | Before { ... } | patterns.cs:51:32:51:33 | 10 | semmle.label | successor | | patterns.cs:51:27:51:35 | { ... } | patterns.cs:51:27:51:35 | After { ... } | semmle.label | successor | @@ -119,16 +125,17 @@ | patterns.cs:52:35:52:54 | "Hit the breakpoint" | patterns.cs:52:17:52:55 | call to method WriteLine | semmle.label | successor | | patterns.cs:53:17:53:22 | Before break; | patterns.cs:53:17:53:22 | break; | semmle.label | successor | | patterns.cs:53:17:53:22 | break; | patterns.cs:46:9:63:9 | After switch (...) {...} | semmle.label | break | -| patterns.cs:54:13:54:43 | After case ...: [match] | patterns.cs:54:18:54:30 | Before { ... } | semmle.label | successor | +| patterns.cs:54:13:54:43 | After case ...: [match] | patterns.cs:54:37:54:42 | Before ... > ... | semmle.label | successor | | patterns.cs:54:13:54:43 | After case ...: [no-match] | patterns.cs:57:13:57:24 | case ...: | semmle.label | successor | -| patterns.cs:54:13:54:43 | case ...: | patterns.cs:54:13:54:43 | After case ...: [match] | semmle.label | match | -| patterns.cs:54:13:54:43 | case ...: | patterns.cs:54:13:54:43 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:54:13:54:43 | case ...: | patterns.cs:54:18:54:30 | Before { ... } | semmle.label | successor | | patterns.cs:54:18:54:30 | After { ... } | patterns.cs:54:18:54:30 | { ... } | semmle.label | successor | -| patterns.cs:54:18:54:30 | After { ... } | patterns.cs:54:37:54:42 | Before ... > ... | semmle.label | successor | +| patterns.cs:54:18:54:30 | After { ... } [match] | patterns.cs:54:13:54:43 | After case ...: [match] | semmle.label | match | +| patterns.cs:54:18:54:30 | After { ... } [no-match] | patterns.cs:54:13:54:43 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:54:18:54:30 | Before { ... } | patterns.cs:54:18:54:30 | Before { ... } | semmle.label | successor | | patterns.cs:54:18:54:30 | Before { ... } | patterns.cs:54:23:54:28 | Int32 x2 | semmle.label | successor | | patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:18:54:30 | After { ... } | semmle.label | successor | -| patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:18:54:30 | After { ... } | semmle.label | successor | +| patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:18:54:30 | After { ... } [match] | semmle.label | match | +| patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:18:54:30 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:54:23:54:28 | Int32 x2 | patterns.cs:54:18:54:30 | { ... } | semmle.label | successor | | patterns.cs:54:37:54:38 | access to local variable x2 | patterns.cs:54:42:54:42 | 2 | semmle.label | successor | | patterns.cs:54:37:54:42 | ... > ... | patterns.cs:54:37:54:42 | After ... > ... [false] | semmle.label | false | @@ -145,26 +152,28 @@ | patterns.cs:55:35:55:36 | access to local variable x2 | patterns.cs:55:17:55:37 | call to method WriteLine | semmle.label | successor | | patterns.cs:56:17:56:22 | Before break; | patterns.cs:56:17:56:22 | break; | semmle.label | successor | | patterns.cs:56:17:56:22 | break; | patterns.cs:46:9:63:9 | After switch (...) {...} | semmle.label | break | -| patterns.cs:57:13:57:24 | After case ...: [match] | patterns.cs:57:18:57:23 | Before { ... } | semmle.label | successor | +| patterns.cs:57:13:57:24 | After case ...: [match] | patterns.cs:58:17:58:22 | Before break; | semmle.label | successor | | patterns.cs:57:13:57:24 | After case ...: [no-match] | patterns.cs:59:13:59:28 | case ...: | semmle.label | successor | -| patterns.cs:57:13:57:24 | case ...: | patterns.cs:57:13:57:24 | After case ...: [match] | semmle.label | match | -| patterns.cs:57:13:57:24 | case ...: | patterns.cs:57:13:57:24 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:57:13:57:24 | case ...: | patterns.cs:57:18:57:23 | Before { ... } | semmle.label | successor | | patterns.cs:57:18:57:23 | ( ... ) | patterns.cs:57:18:57:23 | After ( ... ) | semmle.label | successor | | patterns.cs:57:18:57:23 | After ( ... ) | patterns.cs:57:18:57:23 | { ... } | semmle.label | successor | -| patterns.cs:57:18:57:23 | After { ... } | patterns.cs:58:17:58:22 | Before break; | semmle.label | successor | +| patterns.cs:57:18:57:23 | After { ... } [match] | patterns.cs:57:13:57:24 | After case ...: [match] | semmle.label | match | +| patterns.cs:57:18:57:23 | After { ... } [no-match] | patterns.cs:57:13:57:24 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:57:18:57:23 | Before ( ... ) | patterns.cs:57:19:57:19 | 1 | semmle.label | successor | | patterns.cs:57:18:57:23 | Before { ... } | patterns.cs:57:18:57:23 | Before ( ... ) | semmle.label | successor | -| patterns.cs:57:18:57:23 | { ... } | patterns.cs:57:18:57:23 | After { ... } | semmle.label | successor | +| patterns.cs:57:18:57:23 | { ... } | patterns.cs:57:18:57:23 | After { ... } [match] | semmle.label | match | +| patterns.cs:57:18:57:23 | { ... } | patterns.cs:57:18:57:23 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:57:19:57:19 | 1 | patterns.cs:57:22:57:22 | 2 | semmle.label | successor | | patterns.cs:57:22:57:22 | 2 | patterns.cs:57:18:57:23 | ( ... ) | semmle.label | successor | | patterns.cs:58:17:58:22 | Before break; | patterns.cs:58:17:58:22 | break; | semmle.label | successor | | patterns.cs:58:17:58:22 | break; | patterns.cs:46:9:63:9 | After switch (...) {...} | semmle.label | break | -| patterns.cs:59:13:59:28 | After case ...: [match] | patterns.cs:59:18:59:27 | Before (..., ...) | semmle.label | successor | +| patterns.cs:59:13:59:28 | After case ...: [match] | patterns.cs:60:17:60:22 | Before break; | semmle.label | successor | | patterns.cs:59:13:59:28 | After case ...: [no-match] | patterns.cs:61:13:61:20 | default: | semmle.label | successor | -| patterns.cs:59:13:59:28 | case ...: | patterns.cs:59:13:59:28 | After case ...: [match] | semmle.label | match | -| patterns.cs:59:13:59:28 | case ...: | patterns.cs:59:13:59:28 | After case ...: [no-match] | semmle.label | no-match | -| patterns.cs:59:18:59:27 | (..., ...) | patterns.cs:59:18:59:27 | After (..., ...) | semmle.label | successor | -| patterns.cs:59:18:59:27 | After (..., ...) | patterns.cs:60:17:60:22 | Before break; | semmle.label | successor | +| patterns.cs:59:13:59:28 | case ...: | patterns.cs:59:18:59:27 | Before (..., ...) | semmle.label | successor | +| patterns.cs:59:18:59:27 | (..., ...) | patterns.cs:59:18:59:27 | After (..., ...) [match] | semmle.label | match | +| patterns.cs:59:18:59:27 | (..., ...) | patterns.cs:59:18:59:27 | After (..., ...) [no-match] | semmle.label | no-match | +| patterns.cs:59:18:59:27 | After (..., ...) [match] | patterns.cs:59:13:59:28 | After case ...: [match] | semmle.label | match | +| patterns.cs:59:18:59:27 | After (..., ...) [no-match] | patterns.cs:59:13:59:28 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:59:18:59:27 | Before (..., ...) | patterns.cs:59:23:59:23 | Int32 x | semmle.label | successor | | patterns.cs:59:23:59:23 | Int32 x | patterns.cs:59:26:59:26 | Int32 y | semmle.label | successor | | patterns.cs:59:26:59:26 | Int32 y | patterns.cs:59:18:59:27 | (..., ...) | semmle.label | successor | @@ -177,14 +186,15 @@ | patterns.cs:65:9:73:9 | After switch (...) {...} | patterns.cs:76:9:84:9 | switch (...) {...} | semmle.label | successor | | patterns.cs:65:9:73:9 | switch (...) {...} | patterns.cs:65:17:65:17 | access to local variable s | semmle.label | successor | | patterns.cs:65:17:65:17 | access to local variable s | patterns.cs:67:13:67:50 | case ...: | semmle.label | successor | -| patterns.cs:67:13:67:50 | After case ...: [match] | patterns.cs:67:18:67:38 | Before { ... } | semmle.label | successor | +| patterns.cs:67:13:67:50 | After case ...: [match] | patterns.cs:67:45:67:49 | Before ... > ... | semmle.label | successor | | patterns.cs:67:13:67:50 | After case ...: [no-match] | patterns.cs:70:13:70:51 | case ...: | semmle.label | successor | -| patterns.cs:67:13:67:50 | case ...: | patterns.cs:67:13:67:50 | After case ...: [match] | semmle.label | match | -| patterns.cs:67:13:67:50 | case ...: | patterns.cs:67:13:67:50 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:67:13:67:50 | case ...: | patterns.cs:67:18:67:38 | Before { ... } | semmle.label | successor | | patterns.cs:67:18:67:25 | access to type MyStruct | patterns.cs:67:27:67:38 | Before { ... } | semmle.label | successor | -| patterns.cs:67:18:67:38 | After { ... } | patterns.cs:67:45:67:49 | Before ... > ... | semmle.label | successor | +| patterns.cs:67:18:67:38 | After { ... } [match] | patterns.cs:67:13:67:50 | After case ...: [match] | semmle.label | match | +| patterns.cs:67:18:67:38 | After { ... } [no-match] | patterns.cs:67:13:67:50 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:67:18:67:38 | Before { ... } | patterns.cs:67:18:67:25 | access to type MyStruct | semmle.label | successor | -| patterns.cs:67:18:67:38 | { ... } | patterns.cs:67:18:67:38 | After { ... } | semmle.label | successor | +| patterns.cs:67:18:67:38 | { ... } | patterns.cs:67:18:67:38 | After { ... } [match] | semmle.label | match | +| patterns.cs:67:18:67:38 | { ... } | patterns.cs:67:18:67:38 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:67:27:67:38 | After { ... } | patterns.cs:67:18:67:38 | { ... } | semmle.label | successor | | patterns.cs:67:27:67:38 | Before { ... } | patterns.cs:67:32:67:36 | Int32 x | semmle.label | successor | | patterns.cs:67:27:67:38 | { ... } | patterns.cs:67:27:67:38 | After { ... } | semmle.label | successor | @@ -204,15 +214,16 @@ | patterns.cs:68:35:68:35 | access to local variable x | patterns.cs:68:17:68:36 | call to method WriteLine | semmle.label | successor | | patterns.cs:69:17:69:22 | Before break; | patterns.cs:69:17:69:22 | break; | semmle.label | successor | | patterns.cs:69:17:69:22 | break; | patterns.cs:65:9:73:9 | After switch (...) {...} | semmle.label | break | -| patterns.cs:70:13:70:51 | After case ...: [match] | patterns.cs:70:18:70:38 | Before { ... } | semmle.label | successor | +| patterns.cs:70:13:70:51 | After case ...: [match] | patterns.cs:70:45:70:50 | Before ... == ... | semmle.label | successor | | patterns.cs:70:13:70:51 | After case ...: [no-match] | patterns.cs:65:9:73:9 | After switch (...) {...} | semmle.label | successor | -| patterns.cs:70:13:70:51 | case ...: | patterns.cs:70:13:70:51 | After case ...: [match] | semmle.label | match | -| patterns.cs:70:13:70:51 | case ...: | patterns.cs:70:13:70:51 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:70:13:70:51 | case ...: | patterns.cs:70:18:70:38 | Before { ... } | semmle.label | successor | | patterns.cs:70:18:70:25 | access to type MyStruct | patterns.cs:70:27:70:35 | Before { ... } | semmle.label | successor | -| patterns.cs:70:18:70:38 | After { ... } | patterns.cs:70:45:70:50 | Before ... == ... | semmle.label | successor | +| patterns.cs:70:18:70:38 | After { ... } [match] | patterns.cs:70:13:70:51 | After case ...: [match] | semmle.label | match | +| patterns.cs:70:18:70:38 | After { ... } [no-match] | patterns.cs:70:13:70:51 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:70:18:70:38 | Before { ... } | patterns.cs:70:18:70:38 | MyStruct ms | semmle.label | successor | | patterns.cs:70:18:70:38 | MyStruct ms | patterns.cs:70:18:70:25 | access to type MyStruct | semmle.label | successor | -| patterns.cs:70:18:70:38 | { ... } | patterns.cs:70:18:70:38 | After { ... } | semmle.label | successor | +| patterns.cs:70:18:70:38 | { ... } | patterns.cs:70:18:70:38 | After { ... } [match] | semmle.label | match | +| patterns.cs:70:18:70:38 | { ... } | patterns.cs:70:18:70:38 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:70:27:70:35 | After { ... } | patterns.cs:70:18:70:38 | { ... } | semmle.label | successor | | patterns.cs:70:27:70:35 | Before { ... } | patterns.cs:70:32:70:33 | 10 | semmle.label | successor | | patterns.cs:70:27:70:35 | { ... } | patterns.cs:70:27:70:35 | After { ... } | semmle.label | successor | @@ -240,16 +251,17 @@ | patterns.cs:76:17:76:28 | After object creation of type Object | patterns.cs:78:13:78:43 | case ...: | semmle.label | successor | | patterns.cs:76:17:76:28 | Before object creation of type Object | patterns.cs:76:17:76:28 | object creation of type Object | semmle.label | successor | | patterns.cs:76:17:76:28 | object creation of type Object | patterns.cs:76:17:76:28 | After object creation of type Object | semmle.label | successor | -| patterns.cs:78:13:78:43 | After case ...: [match] | patterns.cs:78:18:78:33 | Before { ... } | semmle.label | successor | +| patterns.cs:78:13:78:43 | After case ...: [match] | patterns.cs:78:40:78:42 | Before ... < ... | semmle.label | successor | | patterns.cs:78:13:78:43 | After case ...: [no-match] | patterns.cs:80:13:80:20 | case ...: | semmle.label | successor | -| patterns.cs:78:13:78:43 | case ...: | patterns.cs:78:13:78:43 | After case ...: [match] | semmle.label | match | -| patterns.cs:78:13:78:43 | case ...: | patterns.cs:78:13:78:43 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:78:13:78:43 | case ...: | patterns.cs:78:18:78:33 | Before { ... } | semmle.label | successor | | patterns.cs:78:18:78:33 | ( ... ) | patterns.cs:78:18:78:33 | After ( ... ) | semmle.label | successor | | patterns.cs:78:18:78:33 | After ( ... ) | patterns.cs:78:18:78:33 | { ... } | semmle.label | successor | -| patterns.cs:78:18:78:33 | After { ... } | patterns.cs:78:40:78:42 | Before ... < ... | semmle.label | successor | +| patterns.cs:78:18:78:33 | After { ... } [match] | patterns.cs:78:13:78:43 | After case ...: [match] | semmle.label | match | +| patterns.cs:78:18:78:33 | After { ... } [no-match] | patterns.cs:78:13:78:43 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:78:18:78:33 | Before ( ... ) | patterns.cs:78:19:78:23 | Int32 x | semmle.label | successor | | patterns.cs:78:18:78:33 | Before { ... } | patterns.cs:78:18:78:33 | Before ( ... ) | semmle.label | successor | -| patterns.cs:78:18:78:33 | { ... } | patterns.cs:78:18:78:33 | After { ... } | semmle.label | successor | +| patterns.cs:78:18:78:33 | { ... } | patterns.cs:78:18:78:33 | After { ... } [match] | semmle.label | match | +| patterns.cs:78:18:78:33 | { ... } | patterns.cs:78:18:78:33 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:78:19:78:23 | Int32 x | patterns.cs:78:26:78:32 | Single y | semmle.label | successor | | patterns.cs:78:26:78:32 | Single y | patterns.cs:78:18:78:33 | ( ... ) | semmle.label | successor | | patterns.cs:78:40:78:40 | (...) ... | patterns.cs:78:40:78:40 | After (...) ... | semmle.label | successor | @@ -264,23 +276,25 @@ | patterns.cs:78:42:78:42 | access to local variable y | patterns.cs:78:40:78:42 | ... < ... | semmle.label | successor | | patterns.cs:79:17:79:22 | Before break; | patterns.cs:79:17:79:22 | break; | semmle.label | successor | | patterns.cs:79:17:79:22 | break; | patterns.cs:76:9:84:9 | After switch (...) {...} | semmle.label | break | -| patterns.cs:80:13:80:20 | After case ...: [match] | patterns.cs:80:18:80:19 | Before { ... } | semmle.label | successor | +| patterns.cs:80:13:80:20 | After case ...: [match] | patterns.cs:81:17:81:22 | Before break; | semmle.label | successor | | patterns.cs:80:13:80:20 | After case ...: [no-match] | patterns.cs:82:13:82:20 | case ...: | semmle.label | successor | -| patterns.cs:80:13:80:20 | case ...: | patterns.cs:80:13:80:20 | After case ...: [match] | semmle.label | match | -| patterns.cs:80:13:80:20 | case ...: | patterns.cs:80:13:80:20 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:80:13:80:20 | case ...: | patterns.cs:80:18:80:19 | Before { ... } | semmle.label | successor | | patterns.cs:80:18:80:19 | ( ... ) | patterns.cs:80:18:80:19 | { ... } | semmle.label | successor | -| patterns.cs:80:18:80:19 | After { ... } | patterns.cs:81:17:81:22 | Before break; | semmle.label | successor | +| patterns.cs:80:18:80:19 | After { ... } [match] | patterns.cs:80:13:80:20 | After case ...: [match] | semmle.label | match | +| patterns.cs:80:18:80:19 | After { ... } [no-match] | patterns.cs:80:13:80:20 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:80:18:80:19 | Before { ... } | patterns.cs:80:18:80:19 | ( ... ) | semmle.label | successor | -| patterns.cs:80:18:80:19 | { ... } | patterns.cs:80:18:80:19 | After { ... } | semmle.label | successor | +| patterns.cs:80:18:80:19 | { ... } | patterns.cs:80:18:80:19 | After { ... } [match] | semmle.label | match | +| patterns.cs:80:18:80:19 | { ... } | patterns.cs:80:18:80:19 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:81:17:81:22 | Before break; | patterns.cs:81:17:81:22 | break; | semmle.label | successor | | patterns.cs:81:17:81:22 | break; | patterns.cs:76:9:84:9 | After switch (...) {...} | semmle.label | break | -| patterns.cs:82:13:82:20 | After case ...: [match] | patterns.cs:82:18:82:19 | Before { ... } | semmle.label | successor | +| patterns.cs:82:13:82:20 | After case ...: [match] | patterns.cs:83:17:83:22 | Before break; | semmle.label | successor | | patterns.cs:82:13:82:20 | After case ...: [no-match] | patterns.cs:76:9:84:9 | After switch (...) {...} | semmle.label | successor | -| patterns.cs:82:13:82:20 | case ...: | patterns.cs:82:13:82:20 | After case ...: [match] | semmle.label | match | -| patterns.cs:82:13:82:20 | case ...: | patterns.cs:82:13:82:20 | After case ...: [no-match] | semmle.label | no-match | -| patterns.cs:82:18:82:19 | After { ... } | patterns.cs:83:17:83:22 | Before break; | semmle.label | successor | +| patterns.cs:82:13:82:20 | case ...: | patterns.cs:82:18:82:19 | Before { ... } | semmle.label | successor | +| patterns.cs:82:18:82:19 | After { ... } [match] | patterns.cs:82:13:82:20 | After case ...: [match] | semmle.label | match | +| patterns.cs:82:18:82:19 | After { ... } [no-match] | patterns.cs:82:13:82:20 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:82:18:82:19 | Before { ... } | patterns.cs:82:18:82:19 | { ... } | semmle.label | successor | -| patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | After { ... } | semmle.label | successor | +| patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | After { ... } [match] | semmle.label | match | +| patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | { ... } | semmle.label | successor | | patterns.cs:83:17:83:22 | Before break; | patterns.cs:83:17:83:22 | break; | semmle.label | successor | | patterns.cs:83:17:83:22 | break; | patterns.cs:76:9:84:9 | After switch (...) {...} | semmle.label | break | @@ -291,16 +305,17 @@ | patterns.cs:86:15:86:19 | Before (..., ...) | patterns.cs:86:16:86:16 | 1 | semmle.label | successor | | patterns.cs:86:16:86:16 | 1 | patterns.cs:86:18:86:18 | 2 | semmle.label | successor | | patterns.cs:86:18:86:18 | 2 | patterns.cs:86:15:86:19 | (..., ...) | semmle.label | successor | -| patterns.cs:88:13:88:24 | After case ...: [match] | patterns.cs:88:18:88:23 | Before { ... } | semmle.label | successor | +| patterns.cs:88:13:88:24 | After case ...: [match] | patterns.cs:88:26:88:31 | Before break; | semmle.label | successor | | patterns.cs:88:13:88:24 | After case ...: [no-match] | patterns.cs:86:9:89:9 | After switch (...) {...} | semmle.label | successor | -| patterns.cs:88:13:88:24 | case ...: | patterns.cs:88:13:88:24 | After case ...: [match] | semmle.label | match | -| patterns.cs:88:13:88:24 | case ...: | patterns.cs:88:13:88:24 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:88:13:88:24 | case ...: | patterns.cs:88:18:88:23 | Before { ... } | semmle.label | successor | | patterns.cs:88:18:88:23 | ( ... ) | patterns.cs:88:18:88:23 | After ( ... ) | semmle.label | successor | | patterns.cs:88:18:88:23 | After ( ... ) | patterns.cs:88:18:88:23 | { ... } | semmle.label | successor | -| patterns.cs:88:18:88:23 | After { ... } | patterns.cs:88:26:88:31 | Before break; | semmle.label | successor | +| patterns.cs:88:18:88:23 | After { ... } [match] | patterns.cs:88:13:88:24 | After case ...: [match] | semmle.label | match | +| patterns.cs:88:18:88:23 | After { ... } [no-match] | patterns.cs:88:13:88:24 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:88:18:88:23 | Before ( ... ) | patterns.cs:88:19:88:19 | 1 | semmle.label | successor | | patterns.cs:88:18:88:23 | Before { ... } | patterns.cs:88:18:88:23 | Before ( ... ) | semmle.label | successor | -| patterns.cs:88:18:88:23 | { ... } | patterns.cs:88:18:88:23 | After { ... } | semmle.label | successor | +| patterns.cs:88:18:88:23 | { ... } | patterns.cs:88:18:88:23 | After { ... } [match] | semmle.label | match | +| patterns.cs:88:18:88:23 | { ... } | patterns.cs:88:18:88:23 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:88:19:88:19 | 1 | patterns.cs:88:22:88:22 | 2 | semmle.label | successor | | patterns.cs:88:22:88:22 | 2 | patterns.cs:88:18:88:23 | ( ... ) | semmle.label | successor | | patterns.cs:88:26:88:31 | Before break; | patterns.cs:88:26:88:31 | break; | semmle.label | successor | @@ -312,30 +327,32 @@ | patterns.cs:91:16:91:20 | Before (..., ...) | patterns.cs:91:17:91:17 | 1 | semmle.label | successor | | patterns.cs:91:17:91:17 | 1 | patterns.cs:91:19:91:19 | 2 | semmle.label | successor | | patterns.cs:91:19:91:19 | 2 | patterns.cs:91:16:91:20 | (..., ...) | semmle.label | successor | -| patterns.cs:93:13:93:28 | After case ...: [match] | patterns.cs:93:18:93:27 | Before { ... } | semmle.label | successor | +| patterns.cs:93:13:93:28 | After case ...: [match] | patterns.cs:93:30:93:35 | Before break; | semmle.label | successor | | patterns.cs:93:13:93:28 | After case ...: [no-match] | patterns.cs:94:13:94:24 | case ...: | semmle.label | successor | -| patterns.cs:93:13:93:28 | case ...: | patterns.cs:93:13:93:28 | After case ...: [match] | semmle.label | match | -| patterns.cs:93:13:93:28 | case ...: | patterns.cs:93:13:93:28 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:93:13:93:28 | case ...: | patterns.cs:93:18:93:27 | Before { ... } | semmle.label | successor | | patterns.cs:93:18:93:27 | ( ... ) | patterns.cs:93:18:93:27 | After ( ... ) | semmle.label | successor | | patterns.cs:93:18:93:27 | After ( ... ) | patterns.cs:93:18:93:27 | { ... } | semmle.label | successor | -| patterns.cs:93:18:93:27 | After { ... } | patterns.cs:93:30:93:35 | Before break; | semmle.label | successor | +| patterns.cs:93:18:93:27 | After { ... } [match] | patterns.cs:93:13:93:28 | After case ...: [match] | semmle.label | match | +| patterns.cs:93:18:93:27 | After { ... } [no-match] | patterns.cs:93:13:93:28 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:93:18:93:27 | Before ( ... ) | patterns.cs:93:19:93:19 | 1 | semmle.label | successor | | patterns.cs:93:18:93:27 | Before { ... } | patterns.cs:93:18:93:27 | Before ( ... ) | semmle.label | successor | -| patterns.cs:93:18:93:27 | { ... } | patterns.cs:93:18:93:27 | After { ... } | semmle.label | successor | +| patterns.cs:93:18:93:27 | { ... } | patterns.cs:93:18:93:27 | After { ... } [match] | semmle.label | match | +| patterns.cs:93:18:93:27 | { ... } | patterns.cs:93:18:93:27 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:93:19:93:19 | 1 | patterns.cs:93:22:93:26 | Int32 x | semmle.label | successor | | patterns.cs:93:22:93:26 | Int32 x | patterns.cs:93:18:93:27 | ( ... ) | semmle.label | successor | | patterns.cs:93:30:93:35 | Before break; | patterns.cs:93:30:93:35 | break; | semmle.label | successor | | patterns.cs:93:30:93:35 | break; | patterns.cs:91:9:95:9 | After switch (...) {...} | semmle.label | break | -| patterns.cs:94:13:94:24 | After case ...: [match] | patterns.cs:94:18:94:23 | Before { ... } | semmle.label | successor | +| patterns.cs:94:13:94:24 | After case ...: [match] | patterns.cs:94:26:94:31 | Before break; | semmle.label | successor | | patterns.cs:94:13:94:24 | After case ...: [no-match] | patterns.cs:91:9:95:9 | After switch (...) {...} | semmle.label | successor | -| patterns.cs:94:13:94:24 | case ...: | patterns.cs:94:13:94:24 | After case ...: [match] | semmle.label | match | -| patterns.cs:94:13:94:24 | case ...: | patterns.cs:94:13:94:24 | After case ...: [no-match] | semmle.label | no-match | +| patterns.cs:94:13:94:24 | case ...: | patterns.cs:94:18:94:23 | Before { ... } | semmle.label | successor | | patterns.cs:94:18:94:23 | ( ... ) | patterns.cs:94:18:94:23 | After ( ... ) | semmle.label | successor | | patterns.cs:94:18:94:23 | After ( ... ) | patterns.cs:94:18:94:23 | { ... } | semmle.label | successor | -| patterns.cs:94:18:94:23 | After { ... } | patterns.cs:94:26:94:31 | Before break; | semmle.label | successor | +| patterns.cs:94:18:94:23 | After { ... } [match] | patterns.cs:94:13:94:24 | After case ...: [match] | semmle.label | match | +| patterns.cs:94:18:94:23 | After { ... } [no-match] | patterns.cs:94:13:94:24 | After case ...: [no-match] | semmle.label | no-match | | patterns.cs:94:18:94:23 | Before ( ... ) | patterns.cs:94:19:94:19 | 2 | semmle.label | successor | | patterns.cs:94:18:94:23 | Before { ... } | patterns.cs:94:18:94:23 | Before ( ... ) | semmle.label | successor | -| patterns.cs:94:18:94:23 | { ... } | patterns.cs:94:18:94:23 | After { ... } | semmle.label | successor | +| patterns.cs:94:18:94:23 | { ... } | patterns.cs:94:18:94:23 | After { ... } [match] | semmle.label | match | +| patterns.cs:94:18:94:23 | { ... } | patterns.cs:94:18:94:23 | After { ... } [no-match] | semmle.label | no-match | | patterns.cs:94:19:94:19 | 2 | patterns.cs:94:22:94:22 | _ | semmle.label | successor | | patterns.cs:94:22:94:22 | _ | patterns.cs:94:18:94:23 | ( ... ) | semmle.label | successor | | patterns.cs:94:26:94:31 | Before break; | patterns.cs:94:26:94:31 | break; | semmle.label | successor | diff --git a/csharp/ql/test/library-tests/goto/Goto1.expected b/csharp/ql/test/library-tests/goto/Goto1.expected index e649e3a07de..35494165164 100644 --- a/csharp/ql/test/library-tests/goto/Goto1.expected +++ b/csharp/ql/test/library-tests/goto/Goto1.expected @@ -27,45 +27,55 @@ | goto.cs:10:9:18:9 | After switch (...) {...} | goto.cs:19:9:19:10 | s9: | semmle.label | successor | | goto.cs:10:9:18:9 | switch (...) {...} | goto.cs:10:17:10:17 | access to local variable s | semmle.label | successor | | goto.cs:10:17:10:17 | access to local variable s | goto.cs:12:13:12:22 | case ...: | semmle.label | successor | -| goto.cs:12:13:12:22 | After case ...: [match] | goto.cs:12:18:12:21 | null | semmle.label | successor | +| goto.cs:12:13:12:22 | After case ...: [match] | goto.cs:12:24:12:25 | s3: | semmle.label | successor | | goto.cs:12:13:12:22 | After case ...: [no-match] | goto.cs:13:13:13:21 | case ...: | semmle.label | successor | -| goto.cs:12:13:12:22 | case ...: | goto.cs:12:13:12:22 | After case ...: [match] | semmle.label | match | -| goto.cs:12:13:12:22 | case ...: | goto.cs:12:13:12:22 | After case ...: [no-match] | semmle.label | no-match | -| goto.cs:12:18:12:21 | null | goto.cs:12:24:12:25 | s3: | semmle.label | successor | +| goto.cs:12:13:12:22 | case ...: | goto.cs:12:18:12:21 | null | semmle.label | successor | +| goto.cs:12:18:12:21 | After null [match] | goto.cs:12:13:12:22 | After case ...: [match] | semmle.label | match | +| goto.cs:12:18:12:21 | After null [no-match] | goto.cs:12:13:12:22 | After case ...: [no-match] | semmle.label | no-match | +| goto.cs:12:18:12:21 | null | goto.cs:12:18:12:21 | After null [match] | semmle.label | match | +| goto.cs:12:18:12:21 | null | goto.cs:12:18:12:21 | After null [no-match] | semmle.label | no-match | | goto.cs:12:24:12:25 | s3: | goto.cs:12:28:12:41 | Before goto case ...; | semmle.label | successor | | goto.cs:12:28:12:41 | Before goto case ...; | goto.cs:12:38:12:40 | "1" | semmle.label | successor | | goto.cs:12:28:12:41 | goto case ...; | goto.cs:13:13:13:21 | After case ...: [match] | semmle.label | goto | | goto.cs:12:38:12:40 | "1" | goto.cs:12:28:12:41 | goto case ...; | semmle.label | successor | -| goto.cs:13:13:13:21 | After case ...: [match] | goto.cs:13:18:13:20 | "1" | semmle.label | successor | +| goto.cs:13:13:13:21 | After case ...: [match] | goto.cs:13:23:13:24 | s4: | semmle.label | successor | | goto.cs:13:13:13:21 | After case ...: [no-match] | goto.cs:14:13:14:21 | case ...: | semmle.label | successor | -| goto.cs:13:13:13:21 | case ...: | goto.cs:13:13:13:21 | After case ...: [match] | semmle.label | match | -| goto.cs:13:13:13:21 | case ...: | goto.cs:13:13:13:21 | After case ...: [no-match] | semmle.label | no-match | -| goto.cs:13:18:13:20 | "1" | goto.cs:13:23:13:24 | s4: | semmle.label | successor | +| goto.cs:13:13:13:21 | case ...: | goto.cs:13:18:13:20 | "1" | semmle.label | successor | +| goto.cs:13:18:13:20 | "1" | goto.cs:13:18:13:20 | After "1" [match] | semmle.label | match | +| goto.cs:13:18:13:20 | "1" | goto.cs:13:18:13:20 | After "1" [no-match] | semmle.label | no-match | +| goto.cs:13:18:13:20 | After "1" [match] | goto.cs:13:13:13:21 | After case ...: [match] | semmle.label | match | +| goto.cs:13:18:13:20 | After "1" [no-match] | goto.cs:13:13:13:21 | After case ...: [no-match] | semmle.label | no-match | | goto.cs:13:23:13:24 | s4: | goto.cs:13:27:13:40 | Before goto case ...; | semmle.label | successor | | goto.cs:13:27:13:40 | Before goto case ...; | goto.cs:13:37:13:39 | "2" | semmle.label | successor | | goto.cs:13:27:13:40 | goto case ...; | goto.cs:14:13:14:21 | After case ...: [match] | semmle.label | goto | | goto.cs:13:37:13:39 | "2" | goto.cs:13:27:13:40 | goto case ...; | semmle.label | successor | -| goto.cs:14:13:14:21 | After case ...: [match] | goto.cs:14:18:14:20 | "2" | semmle.label | successor | +| goto.cs:14:13:14:21 | After case ...: [match] | goto.cs:14:23:14:24 | s5: | semmle.label | successor | | goto.cs:14:13:14:21 | After case ...: [no-match] | goto.cs:15:13:15:21 | case ...: | semmle.label | successor | -| goto.cs:14:13:14:21 | case ...: | goto.cs:14:13:14:21 | After case ...: [match] | semmle.label | match | -| goto.cs:14:13:14:21 | case ...: | goto.cs:14:13:14:21 | After case ...: [no-match] | semmle.label | no-match | -| goto.cs:14:18:14:20 | "2" | goto.cs:14:23:14:24 | s5: | semmle.label | successor | +| goto.cs:14:13:14:21 | case ...: | goto.cs:14:18:14:20 | "2" | semmle.label | successor | +| goto.cs:14:18:14:20 | "2" | goto.cs:14:18:14:20 | After "2" [match] | semmle.label | match | +| goto.cs:14:18:14:20 | "2" | goto.cs:14:18:14:20 | After "2" [no-match] | semmle.label | no-match | +| goto.cs:14:18:14:20 | After "2" [match] | goto.cs:14:13:14:21 | After case ...: [match] | semmle.label | match | +| goto.cs:14:18:14:20 | After "2" [no-match] | goto.cs:14:13:14:21 | After case ...: [no-match] | semmle.label | no-match | | goto.cs:14:23:14:24 | s5: | goto.cs:14:27:14:34 | Before goto ...; | semmle.label | successor | | goto.cs:14:27:14:34 | Before goto ...; | goto.cs:14:27:14:34 | goto ...; | semmle.label | successor | | goto.cs:14:27:14:34 | goto ...; | goto.cs:9:9:9:10 | s2: | semmle.label | goto | -| goto.cs:15:13:15:21 | After case ...: [match] | goto.cs:15:18:15:20 | "3" | semmle.label | successor | +| goto.cs:15:13:15:21 | After case ...: [match] | goto.cs:15:23:15:24 | s6: | semmle.label | successor | | goto.cs:15:13:15:21 | After case ...: [no-match] | goto.cs:16:13:16:21 | case ...: | semmle.label | successor | -| goto.cs:15:13:15:21 | case ...: | goto.cs:15:13:15:21 | After case ...: [match] | semmle.label | match | -| goto.cs:15:13:15:21 | case ...: | goto.cs:15:13:15:21 | After case ...: [no-match] | semmle.label | no-match | -| goto.cs:15:18:15:20 | "3" | goto.cs:15:23:15:24 | s6: | semmle.label | successor | +| goto.cs:15:13:15:21 | case ...: | goto.cs:15:18:15:20 | "3" | semmle.label | successor | +| goto.cs:15:18:15:20 | "3" | goto.cs:15:18:15:20 | After "3" [match] | semmle.label | match | +| goto.cs:15:18:15:20 | "3" | goto.cs:15:18:15:20 | After "3" [no-match] | semmle.label | no-match | +| goto.cs:15:18:15:20 | After "3" [match] | goto.cs:15:13:15:21 | After case ...: [match] | semmle.label | match | +| goto.cs:15:18:15:20 | After "3" [no-match] | goto.cs:15:13:15:21 | After case ...: [no-match] | semmle.label | no-match | | goto.cs:15:23:15:24 | s6: | goto.cs:15:27:15:39 | Before goto default; | semmle.label | successor | | goto.cs:15:27:15:39 | Before goto default; | goto.cs:15:27:15:39 | goto default; | semmle.label | successor | | goto.cs:15:27:15:39 | goto default; | goto.cs:17:13:17:20 | After default: [match] | semmle.label | goto | -| goto.cs:16:13:16:21 | After case ...: [match] | goto.cs:16:18:16:20 | "4" | semmle.label | successor | +| goto.cs:16:13:16:21 | After case ...: [match] | goto.cs:16:23:16:24 | s7: | semmle.label | successor | | goto.cs:16:13:16:21 | After case ...: [no-match] | goto.cs:17:13:17:20 | default: | semmle.label | successor | -| goto.cs:16:13:16:21 | case ...: | goto.cs:16:13:16:21 | After case ...: [match] | semmle.label | match | -| goto.cs:16:13:16:21 | case ...: | goto.cs:16:13:16:21 | After case ...: [no-match] | semmle.label | no-match | -| goto.cs:16:18:16:20 | "4" | goto.cs:16:23:16:24 | s7: | semmle.label | successor | +| goto.cs:16:13:16:21 | case ...: | goto.cs:16:18:16:20 | "4" | semmle.label | successor | +| goto.cs:16:18:16:20 | "4" | goto.cs:16:18:16:20 | After "4" [match] | semmle.label | match | +| goto.cs:16:18:16:20 | "4" | goto.cs:16:18:16:20 | After "4" [no-match] | semmle.label | no-match | +| goto.cs:16:18:16:20 | After "4" [match] | goto.cs:16:13:16:21 | After case ...: [match] | semmle.label | match | +| goto.cs:16:18:16:20 | After "4" [no-match] | goto.cs:16:13:16:21 | After case ...: [no-match] | semmle.label | no-match | | goto.cs:16:23:16:24 | s7: | goto.cs:16:27:16:32 | Before break; | semmle.label | successor | | goto.cs:16:27:16:32 | Before break; | goto.cs:16:27:16:32 | break; | semmle.label | successor | | goto.cs:16:27:16:32 | break; | goto.cs:10:9:18:9 | After switch (...) {...} | semmle.label | break | diff --git a/java/ql/test/library-tests/guards/guardslogic.expected b/java/ql/test/library-tests/guards/guardslogic.expected index f186c385b8c..3a4aeeeef7b 100644 --- a/java/ql/test/library-tests/guards/guardslogic.expected +++ b/java/ql/test/library-tests/guards/guardslogic.expected @@ -19,15 +19,15 @@ | Logic.java:17:11:17:15 | ... > ... | false | Logic.java:15:29:15:29 | i | | Logic.java:17:11:17:15 | ... > ... | true | Logic.java:17:18:17:23 | break | | Logic.java:19:9:19:12 | g(...) | false | Logic.java:24:7:24:17 | case ... | -| Logic.java:19:9:19:12 | g(...) | false | Logic.java:24:12:24:16 | "foo" | +| Logic.java:19:9:19:12 | g(...) | false | Logic.java:25:9:25:14 | break | | Logic.java:19:9:19:12 | g(...) | false | Logic.java:26:7:26:14 | default | | Logic.java:19:9:19:12 | g(...) | true | Logic.java:20:7:20:16 | ; | | Logic.java:22:7:22:17 | case ... | false | Logic.java:24:7:24:17 | case ... | -| Logic.java:22:7:22:17 | case ... | false | Logic.java:24:12:24:16 | "foo" | +| Logic.java:22:7:22:17 | case ... | false | Logic.java:25:9:25:14 | break | | Logic.java:22:7:22:17 | case ... | false | Logic.java:26:7:26:14 | default | -| Logic.java:22:7:22:17 | case ... | true | Logic.java:22:12:22:16 | "bar" | +| Logic.java:22:7:22:17 | case ... | true | Logic.java:23:9:23:14 | break | | Logic.java:24:7:24:17 | case ... | false | Logic.java:26:7:26:14 | default | -| Logic.java:24:7:24:17 | case ... | true | Logic.java:24:12:24:16 | "foo" | +| Logic.java:24:7:24:17 | case ... | true | Logic.java:25:9:25:14 | break | | Logic.java:29:16:29:19 | g(...) | false | Logic.java:29:30:29:30 | s | | Logic.java:29:16:29:19 | g(...) | false | Logic.java:30:30:31:5 | { ... } | | Logic.java:29:16:29:19 | g(...) | true | Logic.java:29:23:29:26 | null | diff --git a/java/ql/test/library-tests/guards12/guard.expected b/java/ql/test/library-tests/guards12/guard.expected index e12bf8c6edb..f88b560c9a4 100644 --- a/java/ql/test/library-tests/guards12/guard.expected +++ b/java/ql/test/library-tests/guards12/guard.expected @@ -1,80 +1,76 @@ hasBranchEdge -| Test.java:4:7:4:22 | case ... | Test.java:2:39:36:3 | { ... } | Test.java:4:7:4:22 | After case ... [match] | true | -| Test.java:4:7:4:22 | case ... | Test.java:2:39:36:3 | { ... } | Test.java:5:7:5:17 | case ... | false | -| Test.java:5:7:5:17 | case ... | Test.java:5:7:5:17 | case ... | Test.java:5:12:5:14 | "c" | true | +| Test.java:5:7:5:17 | case ... | Test.java:5:7:5:17 | case ... | Test.java:5:19:5:19 | 2 | true | | Test.java:5:7:5:17 | case ... | Test.java:5:7:5:17 | case ... | Test.java:6:7:6:17 | case ... | false | -| Test.java:6:7:6:17 | case ... | Test.java:6:7:6:17 | case ... | Test.java:6:12:6:14 | "d" | true | +| Test.java:6:7:6:17 | case ... | Test.java:6:7:6:17 | case ... | Test.java:6:19:6:19 | 2 | true | | Test.java:6:7:6:17 | case ... | Test.java:6:7:6:17 | case ... | Test.java:7:7:7:16 | default | false | -| Test.java:10:7:10:22 | case ... | Test.java:3:9:3:21 | x | Test.java:10:7:10:22 | After case ... [match] | true | -| Test.java:10:7:10:22 | case ... | Test.java:3:9:3:21 | x | Test.java:11:7:11:17 | case ... | false | -| Test.java:11:7:11:17 | case ... | Test.java:11:7:11:17 | case ... | Test.java:11:12:11:14 | "c" | true | +| Test.java:11:7:11:17 | case ... | Test.java:11:7:11:17 | case ... | Test.java:11:19:11:21 | { ... } | true | | Test.java:11:7:11:17 | case ... | Test.java:11:7:11:17 | case ... | Test.java:12:7:12:17 | case ... | false | -| Test.java:12:7:12:17 | case ... | Test.java:12:7:12:17 | case ... | Test.java:12:12:12:14 | "d" | true | +| Test.java:12:7:12:17 | case ... | Test.java:12:7:12:17 | case ... | Test.java:12:19:12:21 | { ... } | true | | Test.java:12:7:12:17 | case ... | Test.java:12:7:12:17 | case ... | Test.java:13:7:13:16 | default | false | -| Test.java:17:7:17:36 | case | Test.java:15:5:15:25 | var ...; | Test.java:17:7:17:36 | After case [no-match] | false | -| Test.java:17:7:17:36 | case | Test.java:15:5:15:25 | var ...; | Test.java:17:19:17:19 | | true | -| Test.java:17:26:17:33 | ... == ... | Test.java:17:19:17:19 | | Test.java:17:26:17:33 | After ... == ... [false] | false | -| Test.java:17:26:17:33 | ... == ... | Test.java:17:19:17:19 | | Test.java:17:38:17:40 | { ... } | true | -| Test.java:18:7:18:17 | case ... | Test.java:18:7:18:17 | case ... | Test.java:18:12:18:14 | "e" | true | +| Test.java:17:7:17:36 | case | Test.java:15:5:15:25 | var ...; | Test.java:17:19:17:19 | After [no-match] | false | +| Test.java:17:7:17:36 | case | Test.java:15:5:15:25 | var ...; | Test.java:17:26:17:28 | len | true | +| Test.java:17:26:17:33 | ... == ... | Test.java:17:26:17:28 | len | Test.java:17:26:17:33 | After ... == ... [false] | false | +| Test.java:17:26:17:33 | ... == ... | Test.java:17:26:17:28 | len | Test.java:17:38:17:40 | { ... } | true | +| Test.java:18:7:18:17 | case ... | Test.java:18:7:18:17 | case ... | Test.java:18:19:18:21 | { ... } | true | | Test.java:18:7:18:17 | case ... | Test.java:18:7:18:17 | case ... | Test.java:19:7:19:16 | default | false | | Test.java:21:13:21:19 | unknown | Test.java:21:5:21:42 | switch (...) | Test.java:21:23:21:23 | s | true | | Test.java:21:13:21:19 | unknown | Test.java:21:5:21:42 | switch (...) | Test.java:21:27:21:27 | s | false | -| Test.java:22:7:22:17 | case ... | Test.java:22:7:22:17 | case ... | Test.java:22:12:22:14 | "f" | true | +| Test.java:22:7:22:17 | case ... | Test.java:22:7:22:17 | case ... | Test.java:22:19:22:21 | { ... } | true | | Test.java:22:7:22:17 | case ... | Test.java:22:7:22:17 | case ... | Test.java:23:7:23:37 | case | false | -| Test.java:23:7:23:37 | case | Test.java:23:7:23:37 | case | Test.java:23:7:23:37 | After case [no-match] | false | -| Test.java:23:7:23:37 | case | Test.java:23:7:23:37 | case | Test.java:23:19:23:20 | s2 | true | -| Test.java:23:27:23:34 | ... == ... | Test.java:23:19:23:20 | s2 | Test.java:23:27:23:34 | After ... == ... [false] | false | -| Test.java:23:27:23:34 | ... == ... | Test.java:23:19:23:20 | s2 | Test.java:23:39:23:41 | { ... } | true | -| Test.java:24:7:24:17 | case ... | Test.java:24:7:24:17 | case ... | Test.java:24:12:24:14 | "g" | true | +| Test.java:23:7:23:37 | case | Test.java:23:7:23:37 | case | Test.java:23:19:23:20 | After s2 [no-match] | false | +| Test.java:23:7:23:37 | case | Test.java:23:7:23:37 | case | Test.java:23:27:23:29 | len | true | +| Test.java:23:27:23:34 | ... == ... | Test.java:23:27:23:29 | len | Test.java:23:27:23:34 | After ... == ... [false] | false | +| Test.java:23:27:23:34 | ... == ... | Test.java:23:27:23:29 | len | Test.java:23:39:23:41 | { ... } | true | +| Test.java:24:7:24:17 | case ... | Test.java:24:7:24:17 | case ... | Test.java:24:19:24:21 | { ... } | true | | Test.java:24:7:24:17 | case ... | Test.java:24:7:24:17 | case ... | Test.java:25:7:25:16 | default | false | -| Test.java:28:7:28:15 | case ... | Test.java:27:5:27:14 | switch (...) | Test.java:28:12:28:14 | "h" | true | +| Test.java:28:7:28:15 | case ... | Test.java:27:5:27:14 | switch (...) | Test.java:28:12:28:14 | After "h" [match] | true | | Test.java:28:7:28:15 | case ... | Test.java:27:5:27:14 | switch (...) | Test.java:29:7:29:34 | case | false | -| Test.java:29:7:29:34 | case | Test.java:29:7:29:34 | case | Test.java:29:7:29:34 | After case [no-match] | false | -| Test.java:29:7:29:34 | case | Test.java:29:7:29:34 | case | Test.java:29:19:29:19 | | true | -| Test.java:29:26:29:33 | ... == ... | Test.java:29:19:29:19 | | Test.java:29:26:29:33 | After ... == ... [false] | false | -| Test.java:29:26:29:33 | ... == ... | Test.java:29:19:29:19 | | Test.java:29:26:29:33 | After ... == ... [true] | true | -| Test.java:30:7:30:15 | case ... | Test.java:30:7:30:15 | case ... | Test.java:30:12:30:14 | "i" | true | +| Test.java:29:7:29:34 | case | Test.java:29:7:29:34 | case | Test.java:29:19:29:19 | After [no-match] | false | +| Test.java:29:7:29:34 | case | Test.java:29:7:29:34 | case | Test.java:29:26:29:28 | len | true | +| Test.java:29:26:29:33 | ... == ... | Test.java:29:26:29:28 | len | Test.java:29:26:29:33 | After ... == ... [false] | false | +| Test.java:29:26:29:33 | ... == ... | Test.java:29:26:29:28 | len | Test.java:29:26:29:33 | After ... == ... [true] | true | +| Test.java:30:7:30:15 | case ... | Test.java:30:7:30:15 | case ... | Test.java:30:12:30:14 | After "i" [match] | true | | Test.java:30:7:30:15 | case ... | Test.java:30:7:30:15 | case ... | Test.java:33:7:33:14 | default | false | #select | Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | false | Test.java:6:7:6:17 | case ... | -| Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | false | Test.java:6:12:6:14 | "d" | +| Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | false | Test.java:6:19:6:19 | 2 | | Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | false | Test.java:7:7:7:16 | default | -| Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | true | Test.java:5:12:5:14 | "c" | +| Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | true | Test.java:5:19:5:19 | 2 | | Test.java:6:7:6:17 | case ... | Test.java:3:20:3:20 | s | Test.java:6:12:6:14 | "d" | true | false | Test.java:7:7:7:16 | default | -| Test.java:6:7:6:17 | case ... | Test.java:3:20:3:20 | s | Test.java:6:12:6:14 | "d" | true | true | Test.java:6:12:6:14 | "d" | +| Test.java:6:7:6:17 | case ... | Test.java:3:20:3:20 | s | Test.java:6:12:6:14 | "d" | true | true | Test.java:6:19:6:19 | 2 | | Test.java:11:7:11:17 | case ... | Test.java:9:13:9:13 | s | Test.java:11:12:11:14 | "c" | true | false | Test.java:12:7:12:17 | case ... | -| Test.java:11:7:11:17 | case ... | Test.java:9:13:9:13 | s | Test.java:11:12:11:14 | "c" | true | false | Test.java:12:12:12:14 | "d" | +| Test.java:11:7:11:17 | case ... | Test.java:9:13:9:13 | s | Test.java:11:12:11:14 | "c" | true | false | Test.java:12:19:12:21 | { ... } | | Test.java:11:7:11:17 | case ... | Test.java:9:13:9:13 | s | Test.java:11:12:11:14 | "c" | true | false | Test.java:13:7:13:16 | default | -| Test.java:11:7:11:17 | case ... | Test.java:9:13:9:13 | s | Test.java:11:12:11:14 | "c" | true | true | Test.java:11:12:11:14 | "c" | +| Test.java:11:7:11:17 | case ... | Test.java:9:13:9:13 | s | Test.java:11:12:11:14 | "c" | true | true | Test.java:11:19:11:21 | { ... } | | Test.java:12:7:12:17 | case ... | Test.java:9:13:9:13 | s | Test.java:12:12:12:14 | "d" | true | false | Test.java:13:7:13:16 | default | -| Test.java:12:7:12:17 | case ... | Test.java:9:13:9:13 | s | Test.java:12:12:12:14 | "d" | true | true | Test.java:12:12:12:14 | "d" | +| Test.java:12:7:12:17 | case ... | Test.java:9:13:9:13 | s | Test.java:12:12:12:14 | "d" | true | true | Test.java:12:19:12:21 | { ... } | | Test.java:17:26:17:33 | ... == ... | Test.java:17:26:17:28 | len | Test.java:17:33:17:33 | 4 | true | false | Test.java:17:26:17:33 | After ... == ... [false] | | Test.java:17:26:17:33 | ... == ... | Test.java:17:26:17:28 | len | Test.java:17:33:17:33 | 4 | true | true | Test.java:17:38:17:40 | { ... } | | Test.java:18:7:18:17 | case ... | Test.java:16:13:16:13 | s | Test.java:18:12:18:14 | "e" | true | false | Test.java:19:7:19:16 | default | -| Test.java:18:7:18:17 | case ... | Test.java:16:13:16:13 | s | Test.java:18:12:18:14 | "e" | true | true | Test.java:18:12:18:14 | "e" | -| Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:23:7:23:37 | After case [no-match] | +| Test.java:18:7:18:17 | case ... | Test.java:16:13:16:13 | s | Test.java:18:12:18:14 | "e" | true | true | Test.java:18:19:18:21 | { ... } | | Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:23:7:23:37 | case | -| Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:23:19:23:20 | s2 | +| Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:23:19:23:20 | After s2 [no-match] | +| Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:23:27:23:29 | len | | Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:23:27:23:34 | After ... == ... [false] | | Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:23:39:23:41 | { ... } | | Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:24:7:24:17 | case ... | -| Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:24:12:24:14 | "g" | +| Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:24:19:24:21 | { ... } | | Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:25:7:25:16 | default | -| Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | true | Test.java:22:12:22:14 | "f" | +| Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | true | Test.java:22:19:22:21 | { ... } | | Test.java:23:27:23:34 | ... == ... | Test.java:23:27:23:29 | len | Test.java:23:34:23:34 | 4 | true | false | Test.java:23:27:23:34 | After ... == ... [false] | | Test.java:23:27:23:34 | ... == ... | Test.java:23:27:23:29 | len | Test.java:23:34:23:34 | 4 | true | true | Test.java:23:39:23:41 | { ... } | | Test.java:24:7:24:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:24:12:24:14 | "g" | true | false | Test.java:25:7:25:16 | default | -| Test.java:24:7:24:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:24:12:24:14 | "g" | true | true | Test.java:24:12:24:14 | "g" | -| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:29:7:29:34 | After case [no-match] | +| Test.java:24:7:24:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:24:12:24:14 | "g" | true | true | Test.java:24:19:24:21 | { ... } | | Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:29:7:29:34 | case | -| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:29:19:29:19 | | +| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:29:19:29:19 | After [no-match] | +| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:29:26:29:28 | len | | Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:29:26:29:33 | After ... == ... [false] | | Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:29:26:29:33 | After ... == ... [true] | | Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:30:7:30:15 | case ... | -| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:30:12:30:14 | "i" | +| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:30:12:30:14 | After "i" [match] | | Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:33:7:33:14 | default | -| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | true | Test.java:28:12:28:14 | "h" | +| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | true | Test.java:28:12:28:14 | After "h" [match] | | Test.java:29:26:29:33 | ... == ... | Test.java:29:26:29:28 | len | Test.java:29:33:29:33 | 4 | true | false | Test.java:29:26:29:33 | After ... == ... [false] | | Test.java:29:26:29:33 | ... == ... | Test.java:29:26:29:28 | len | Test.java:29:33:29:33 | 4 | true | true | Test.java:29:26:29:33 | After ... == ... [true] | | Test.java:30:7:30:15 | case ... | Test.java:27:13:27:13 | s | Test.java:30:12:30:14 | "i" | true | false | Test.java:33:7:33:14 | default | -| Test.java:30:7:30:15 | case ... | Test.java:27:13:27:13 | s | Test.java:30:12:30:14 | "i" | true | true | Test.java:30:12:30:14 | "i" | +| Test.java:30:7:30:15 | case ... | Test.java:27:13:27:13 | s | Test.java:30:12:30:14 | "i" | true | true | Test.java:30:12:30:14 | After "i" [match] | diff --git a/java/ql/test/library-tests/pattern-switch/cfg/test.expected b/java/ql/test/library-tests/pattern-switch/cfg/test.expected index d398c5f6ecd..1abd0419db0 100644 --- a/java/ql/test/library-tests/pattern-switch/cfg/test.expected +++ b/java/ql/test/library-tests/pattern-switch/cfg/test.expected @@ -35,8 +35,8 @@ | Exhaustive.java:11:5:11:14 | switch (...) | Exhaustive.java:11:13:11:13 | o | | Exhaustive.java:11:13:11:13 | o | Exhaustive.java:12:7:12:22 | case | | Exhaustive.java:12:7:12:22 | case | Exhaustive.java:12:19:12:19 | s | -| Exhaustive.java:12:7:12:22 | case | Exhaustive.java:13:7:13:23 | case | | Exhaustive.java:12:19:12:19 | s | Exhaustive.java:12:24:12:26 | { ... } | +| Exhaustive.java:12:19:12:19 | s | Exhaustive.java:13:7:13:23 | case | | Exhaustive.java:12:24:12:26 | { ... } | Exhaustive.java:18:5:18:14 | switch (...) | | Exhaustive.java:13:7:13:23 | case | Exhaustive.java:13:19:13:20 | o2 | | Exhaustive.java:13:19:13:20 | o2 | Exhaustive.java:13:25:13:27 | { ... } | @@ -44,22 +44,22 @@ | Exhaustive.java:18:5:18:14 | switch (...) | Exhaustive.java:18:13:18:13 | e | | Exhaustive.java:18:13:18:13 | e | Exhaustive.java:19:7:19:15 | case ... | | Exhaustive.java:19:7:19:15 | case ... | Exhaustive.java:19:12:19:12 | A | -| Exhaustive.java:19:7:19:15 | case ... | Exhaustive.java:20:7:20:15 | case ... | | Exhaustive.java:19:12:19:12 | A | Exhaustive.java:19:17:19:19 | { ... } | +| Exhaustive.java:19:12:19:12 | A | Exhaustive.java:20:7:20:15 | case ... | | Exhaustive.java:19:17:19:19 | { ... } | Exhaustive.java:24:5:24:14 | switch (...) | | Exhaustive.java:20:7:20:15 | case ... | Exhaustive.java:20:12:20:12 | B | -| Exhaustive.java:20:7:20:15 | case ... | Exhaustive.java:21:7:21:15 | case ... | | Exhaustive.java:20:12:20:12 | B | Exhaustive.java:20:17:20:19 | { ... } | +| Exhaustive.java:20:12:20:12 | B | Exhaustive.java:21:7:21:15 | case ... | | Exhaustive.java:20:17:20:19 | { ... } | Exhaustive.java:24:5:24:14 | switch (...) | | Exhaustive.java:21:7:21:15 | case ... | Exhaustive.java:21:12:21:12 | C | -| Exhaustive.java:21:7:21:15 | case ... | Exhaustive.java:24:5:24:14 | switch (...) | | Exhaustive.java:21:12:21:12 | C | Exhaustive.java:21:17:21:19 | { ... } | +| Exhaustive.java:21:12:21:12 | C | Exhaustive.java:24:5:24:14 | switch (...) | | Exhaustive.java:21:17:21:19 | { ... } | Exhaustive.java:24:5:24:14 | switch (...) | | Exhaustive.java:24:5:24:14 | switch (...) | Exhaustive.java:24:13:24:13 | i | | Exhaustive.java:24:13:24:13 | i | Exhaustive.java:25:7:25:17 | case | | Exhaustive.java:25:7:25:17 | case | Exhaustive.java:25:14:25:14 | x | -| Exhaustive.java:25:7:25:17 | case | Exhaustive.java:26:7:26:17 | case | | Exhaustive.java:25:14:25:14 | x | Exhaustive.java:25:19:25:21 | { ... } | +| Exhaustive.java:25:14:25:14 | x | Exhaustive.java:26:7:26:17 | case | | Exhaustive.java:25:19:25:21 | { ... } | Exhaustive.java:30:5:30:14 | switch (...) | | Exhaustive.java:26:7:26:17 | case | Exhaustive.java:26:14:26:14 | y | | Exhaustive.java:26:14:26:14 | y | Exhaustive.java:26:19:26:21 | { ... } | @@ -67,8 +67,8 @@ | Exhaustive.java:30:5:30:14 | switch (...) | Exhaustive.java:30:13:30:13 | i | | Exhaustive.java:30:13:30:13 | i | Exhaustive.java:31:7:31:15 | case | | Exhaustive.java:31:7:31:15 | case | Exhaustive.java:31:14:31:14 | | -| Exhaustive.java:31:7:31:15 | case | Exhaustive.java:32:7:32:15 | case | | Exhaustive.java:31:14:31:14 | | Exhaustive.java:8:22:8:25 | Normal Exit | +| Exhaustive.java:31:14:31:14 | | Exhaustive.java:32:7:32:15 | case | | Exhaustive.java:32:7:32:15 | case | Exhaustive.java:32:14:32:14 | | | Exhaustive.java:32:14:32:14 | | Exhaustive.java:8:22:8:25 | Normal Exit | | Test.java:1:14:1:17 | Entry | Test.java:1:14:1:17 | { ... } | @@ -81,14 +81,14 @@ | Test.java:5:6:5:19 | switch (...) | Test.java:5:14:5:18 | thing | | Test.java:5:14:5:18 | thing | Test.java:6:8:6:23 | case | | Test.java:6:8:6:23 | case | Test.java:6:20:6:20 | s | -| Test.java:6:8:6:23 | case | Test.java:7:8:7:24 | case | | Test.java:6:20:6:20 | s | Test.java:6:25:6:34 | System.out | +| Test.java:6:20:6:20 | s | Test.java:7:8:7:24 | case | | Test.java:6:25:6:34 | System.out | Test.java:6:44:6:44 | s | | Test.java:6:25:6:45 | println(...) | Test.java:11:6:11:19 | switch (...) | | Test.java:6:44:6:44 | s | Test.java:6:25:6:45 | println(...) | | Test.java:7:8:7:24 | case | Test.java:7:21:7:21 | i | -| Test.java:7:8:7:24 | case | Test.java:8:8:8:17 | default | | Test.java:7:21:7:21 | i | Test.java:7:26:7:35 | System.out | +| Test.java:7:21:7:21 | i | Test.java:8:8:8:17 | default | | Test.java:7:26:7:35 | System.out | Test.java:7:45:7:58 | "An integer: " | | Test.java:7:26:7:63 | println(...) | Test.java:11:6:11:19 | switch (...) | | Test.java:7:45:7:58 | "An integer: " | Test.java:7:62:7:62 | i | @@ -99,16 +99,16 @@ | Test.java:11:6:11:19 | switch (...) | Test.java:11:14:11:18 | thing | | Test.java:11:14:11:18 | thing | Test.java:12:8:12:21 | case | | Test.java:12:8:12:21 | case | Test.java:12:20:12:20 | s | -| Test.java:12:8:12:21 | case | Test.java:15:8:15:22 | case | | Test.java:12:20:12:20 | s | Test.java:13:10:13:31 | ; | +| Test.java:12:20:12:20 | s | Test.java:15:8:15:22 | case | | Test.java:13:10:13:19 | System.out | Test.java:13:29:13:29 | s | | Test.java:13:10:13:30 | println(...) | Test.java:14:10:14:15 | break | | Test.java:13:10:13:31 | ; | Test.java:13:10:13:19 | System.out | | Test.java:13:29:13:29 | s | Test.java:13:10:13:30 | println(...) | | Test.java:14:10:14:15 | break | Test.java:22:6:26:7 | var ...; | | Test.java:15:8:15:22 | case | Test.java:15:21:15:21 | i | -| Test.java:15:8:15:22 | case | Test.java:18:8:18:15 | default | | Test.java:15:21:15:21 | i | Test.java:16:10:16:47 | ; | +| Test.java:15:21:15:21 | i | Test.java:18:8:18:15 | default | | Test.java:16:10:16:19 | System.out | Test.java:16:29:16:41 | "An integer:" | | Test.java:16:10:16:46 | println(...) | Test.java:17:10:17:15 | break | | Test.java:16:10:16:47 | ; | Test.java:16:10:16:19 | System.out | @@ -123,12 +123,12 @@ | Test.java:22:26:22:38 | switch (...) | Test.java:22:33:22:37 | thing | | Test.java:22:33:22:37 | thing | Test.java:23:8:23:23 | case | | Test.java:23:8:23:23 | case | Test.java:23:20:23:20 | s | -| Test.java:23:8:23:23 | case | Test.java:24:8:24:24 | case | | Test.java:23:20:23:20 | s | Test.java:23:25:23:25 | s | +| Test.java:23:20:23:20 | s | Test.java:24:8:24:24 | case | | Test.java:23:25:23:25 | s | Test.java:22:10:22:38 | thingAsString | | Test.java:24:8:24:24 | case | Test.java:24:21:24:21 | i | -| Test.java:24:8:24:24 | case | Test.java:25:8:25:17 | default | | Test.java:24:21:24:21 | i | Test.java:24:26:24:39 | "An integer: " | +| Test.java:24:21:24:21 | i | Test.java:25:8:25:17 | default | | Test.java:24:26:24:39 | "An integer: " | Test.java:24:43:24:43 | i | | Test.java:24:26:24:43 | ... + ... | Test.java:22:10:22:38 | thingAsString | | Test.java:24:43:24:43 | i | Test.java:24:26:24:43 | ... + ... | @@ -139,13 +139,13 @@ | Test.java:28:27:28:39 | switch (...) | Test.java:28:34:28:38 | thing | | Test.java:28:34:28:38 | thing | Test.java:29:8:29:21 | case | | Test.java:29:8:29:21 | case | Test.java:29:20:29:20 | s | -| Test.java:29:8:29:21 | case | Test.java:31:8:31:22 | case | | Test.java:29:20:29:20 | s | Test.java:30:16:30:16 | s | +| Test.java:29:20:29:20 | s | Test.java:31:8:31:22 | case | | Test.java:30:10:30:17 | yield ... | Test.java:28:10:28:39 | thingAsString2 | | Test.java:30:16:30:16 | s | Test.java:30:10:30:17 | yield ... | | Test.java:31:8:31:22 | case | Test.java:31:21:31:21 | i | -| Test.java:31:8:31:22 | case | Test.java:33:8:33:15 | default | | Test.java:31:21:31:21 | i | Test.java:32:16:32:29 | "An integer: " | +| Test.java:31:21:31:21 | i | Test.java:33:8:33:15 | default | | Test.java:32:10:32:34 | yield ... | Test.java:28:10:28:39 | thingAsString2 | | Test.java:32:16:32:29 | "An integer: " | Test.java:32:33:32:33 | i | | Test.java:32:16:32:33 | ... + ... | Test.java:32:10:32:34 | yield ... | @@ -156,8 +156,8 @@ | Test.java:37:6:37:18 | switch (...) | Test.java:37:13:37:17 | thing | | Test.java:37:13:37:17 | thing | Test.java:38:8:38:42 | case | | Test.java:38:8:38:42 | case | Test.java:38:20:38:20 | s | -| Test.java:38:8:38:42 | case | Test.java:41:8:41:42 | case | | Test.java:38:20:38:20 | s | Test.java:38:27:38:27 | s | +| Test.java:38:20:38:20 | s | Test.java:41:8:41:42 | case | | Test.java:38:27:38:27 | s | Test.java:38:27:38:36 | length(...) | | Test.java:38:27:38:36 | length(...) | Test.java:38:41:38:41 | 3 | | Test.java:38:27:38:41 | ... == ... | Test.java:39:10:39:40 | ; | @@ -169,8 +169,8 @@ | Test.java:39:29:39:38 | "Length 3" | Test.java:39:10:39:39 | println(...) | | Test.java:40:10:40:15 | break | Test.java:49:6:49:18 | switch (...) | | Test.java:41:8:41:42 | case | Test.java:41:20:41:20 | s | -| Test.java:41:8:41:42 | case | Test.java:44:8:44:15 | default | | Test.java:41:20:41:20 | s | Test.java:41:27:41:27 | s | +| Test.java:41:20:41:20 | s | Test.java:44:8:44:15 | default | | Test.java:41:27:41:27 | s | Test.java:41:27:41:36 | length(...) | | Test.java:41:27:41:36 | length(...) | Test.java:41:41:41:41 | 5 | | Test.java:41:27:41:41 | ... == ... | Test.java:42:10:42:40 | ; | @@ -190,8 +190,8 @@ | Test.java:49:6:49:18 | switch (...) | Test.java:49:13:49:17 | thing | | Test.java:49:13:49:17 | thing | Test.java:50:8:50:44 | case | | Test.java:50:8:50:44 | case | Test.java:50:20:50:20 | s | -| Test.java:50:8:50:44 | case | Test.java:51:8:51:44 | case | | Test.java:50:20:50:20 | s | Test.java:50:27:50:27 | s | +| Test.java:50:20:50:20 | s | Test.java:51:8:51:44 | case | | Test.java:50:27:50:27 | s | Test.java:50:27:50:36 | length(...) | | Test.java:50:27:50:36 | length(...) | Test.java:50:41:50:41 | 3 | | Test.java:50:27:50:41 | ... == ... | Test.java:50:46:50:55 | System.out | @@ -201,8 +201,8 @@ | Test.java:50:46:50:75 | println(...) | Test.java:55:6:55:26 | switch (...) | | Test.java:50:65:50:74 | "Length 3" | Test.java:50:46:50:75 | println(...) | | Test.java:51:8:51:44 | case | Test.java:51:20:51:20 | s | -| Test.java:51:8:51:44 | case | Test.java:52:8:52:17 | default | | Test.java:51:20:51:20 | s | Test.java:51:27:51:27 | s | +| Test.java:51:20:51:20 | s | Test.java:52:8:52:17 | default | | Test.java:51:27:51:27 | s | Test.java:51:27:51:36 | length(...) | | Test.java:51:27:51:36 | length(...) | Test.java:51:41:51:41 | 5 | | Test.java:51:27:51:41 | ... == ... | Test.java:51:46:51:55 | System.out | @@ -217,23 +217,23 @@ | Test.java:55:13:55:25 | (...)... | Test.java:56:8:56:21 | case ... | | Test.java:55:21:55:25 | thing | Test.java:55:13:55:25 | (...)... | | Test.java:56:8:56:21 | case ... | Test.java:56:13:56:20 | "Const1" | -| Test.java:56:8:56:21 | case ... | Test.java:58:8:58:21 | case ... | | Test.java:56:13:56:20 | "Const1" | Test.java:57:10:57:44 | ; | +| Test.java:56:13:56:20 | "Const1" | Test.java:58:8:58:21 | case ... | | Test.java:57:10:57:19 | System.out | Test.java:57:29:57:42 | "It's Const1!" | | Test.java:57:10:57:43 | println(...) | Test.java:59:10:59:54 | ; | | Test.java:57:10:57:44 | ; | Test.java:57:10:57:19 | System.out | | Test.java:57:29:57:42 | "It's Const1!" | Test.java:57:10:57:43 | println(...) | | Test.java:58:8:58:21 | case ... | Test.java:58:13:58:20 | "Const2" | -| Test.java:58:8:58:21 | case ... | Test.java:61:8:61:42 | case | | Test.java:58:13:58:20 | "Const2" | Test.java:59:10:59:54 | ; | +| Test.java:58:13:58:20 | "Const2" | Test.java:61:8:61:42 | case | | Test.java:59:10:59:19 | System.out | Test.java:59:29:59:52 | "It's Const1 or Const2!" | | Test.java:59:10:59:53 | println(...) | Test.java:60:10:60:15 | break | | Test.java:59:10:59:54 | ; | Test.java:59:10:59:19 | System.out | | Test.java:59:29:59:52 | "It's Const1 or Const2!" | Test.java:59:10:59:53 | println(...) | | Test.java:60:10:60:15 | break | Test.java:73:6:73:18 | switch (...) | | Test.java:61:8:61:42 | case | Test.java:61:20:61:20 | s | -| Test.java:61:8:61:42 | case | Test.java:63:8:63:21 | case ... | | Test.java:61:20:61:20 | s | Test.java:61:27:61:27 | s | +| Test.java:61:20:61:20 | s | Test.java:63:8:63:21 | case ... | | Test.java:61:27:61:27 | s | Test.java:61:27:61:36 | length(...) | | Test.java:61:27:61:36 | length(...) | Test.java:61:41:61:41 | 6 | | Test.java:61:27:61:41 | ... <= ... | Test.java:62:10:62:83 | ; | @@ -244,16 +244,16 @@ | Test.java:62:10:62:83 | ; | Test.java:62:10:62:19 | System.out | | Test.java:62:29:62:81 | "It's <= 6 chars long, and neither Const1 nor Const2" | Test.java:62:10:62:82 | println(...) | | Test.java:63:8:63:21 | case ... | Test.java:63:13:63:20 | "Const3" | -| Test.java:63:8:63:21 | case ... | Test.java:66:8:66:22 | case ... | | Test.java:63:13:63:20 | "Const3" | Test.java:64:10:64:96 | ; | +| Test.java:63:13:63:20 | "Const3" | Test.java:66:8:66:22 | case ... | | Test.java:64:10:64:19 | System.out | Test.java:64:29:64:94 | "It's (<= 6 chars long, and neither Const1 nor Const2), or Const3" | | Test.java:64:10:64:95 | println(...) | Test.java:65:10:65:15 | break | | Test.java:64:10:64:96 | ; | Test.java:64:10:64:19 | System.out | | Test.java:64:29:64:94 | "It's (<= 6 chars long, and neither Const1 nor Const2), or Const3" | Test.java:64:10:64:95 | println(...) | | Test.java:65:10:65:15 | break | Test.java:73:6:73:18 | switch (...) | | Test.java:66:8:66:22 | case ... | Test.java:66:13:66:21 | "Const30" | -| Test.java:66:8:66:22 | case ... | Test.java:69:8:69:26 | case null, default | | Test.java:66:13:66:21 | "Const30" | Test.java:67:10:67:44 | ; | +| Test.java:66:13:66:21 | "Const30" | Test.java:69:8:69:26 | case null, default | | Test.java:67:10:67:19 | System.out | Test.java:67:29:67:42 | "It's Const30" | | Test.java:67:10:67:43 | println(...) | Test.java:68:10:68:15 | break | | Test.java:67:10:67:44 | ; | Test.java:67:10:67:19 | System.out | @@ -267,24 +267,24 @@ | Test.java:73:6:73:18 | switch (...) | Test.java:73:13:73:17 | thing | | Test.java:73:13:73:17 | thing | Test.java:74:8:74:21 | case | | Test.java:74:8:74:21 | case | Test.java:74:20:74:20 | s | -| Test.java:74:8:74:21 | case | Test.java:77:8:77:17 | case ... | | Test.java:74:20:74:20 | s | Test.java:75:10:75:31 | ; | +| Test.java:74:20:74:20 | s | Test.java:77:8:77:17 | case ... | | Test.java:75:10:75:19 | System.out | Test.java:75:29:75:29 | s | | Test.java:75:10:75:30 | println(...) | Test.java:76:10:76:15 | break | | Test.java:75:10:75:31 | ; | Test.java:75:10:75:19 | System.out | | Test.java:75:29:75:29 | s | Test.java:75:10:75:30 | println(...) | | Test.java:76:10:76:15 | break | Test.java:87:6:87:18 | switch (...) | | Test.java:77:8:77:17 | case ... | Test.java:77:13:77:16 | null | -| Test.java:77:8:77:17 | case ... | Test.java:80:8:80:22 | case | | Test.java:77:13:77:16 | null | Test.java:78:10:78:41 | ; | +| Test.java:77:13:77:16 | null | Test.java:80:8:80:22 | case | | Test.java:78:10:78:19 | System.out | Test.java:78:29:78:39 | "It's null" | | Test.java:78:10:78:40 | println(...) | Test.java:79:10:79:15 | break | | Test.java:78:10:78:41 | ; | Test.java:78:10:78:19 | System.out | | Test.java:78:29:78:39 | "It's null" | Test.java:78:10:78:40 | println(...) | | Test.java:79:10:79:15 | break | Test.java:87:6:87:18 | switch (...) | | Test.java:80:8:80:22 | case | Test.java:80:21:80:21 | i | -| Test.java:80:8:80:22 | case | Test.java:83:8:83:15 | default | | Test.java:80:21:80:21 | i | Test.java:81:10:81:47 | ; | +| Test.java:80:21:80:21 | i | Test.java:83:8:83:15 | default | | Test.java:81:10:81:19 | System.out | Test.java:81:29:81:41 | "An integer:" | | Test.java:81:10:81:46 | println(...) | Test.java:82:10:82:15 | break | | Test.java:81:10:81:47 | ; | Test.java:81:10:81:19 | System.out | @@ -297,8 +297,8 @@ | Test.java:87:6:87:18 | switch (...) | Test.java:87:13:87:17 | thing | | Test.java:87:13:87:17 | thing | Test.java:88:8:88:43 | case | | Test.java:88:8:88:43 | case | Test.java:88:21:88:21 | x | -| Test.java:88:8:88:43 | case | Test.java:90:8:90:15 | default | | Test.java:88:13:88:42 | A(...) | Test.java:89:10:89:15 | break | +| Test.java:88:13:88:42 | A(...) | Test.java:90:8:90:15 | default | | Test.java:88:15:88:32 | B(...) | Test.java:88:41:88:41 | z | | Test.java:88:21:88:21 | x | Test.java:88:31:88:31 | y | | Test.java:88:31:88:31 | y | Test.java:88:15:88:32 | B(...) | @@ -309,8 +309,8 @@ | Test.java:94:6:94:18 | switch (...) | Test.java:94:13:94:17 | thing | | Test.java:94:13:94:17 | thing | Test.java:95:8:95:38 | case | | Test.java:95:8:95:38 | case | Test.java:95:21:95:21 | x | -| Test.java:95:8:95:38 | case | Test.java:97:8:97:15 | default | | Test.java:95:13:95:37 | A(...) | Test.java:96:10:96:15 | break | +| Test.java:95:13:95:37 | A(...) | Test.java:97:8:97:15 | default | | Test.java:95:15:95:29 | B(...) | Test.java:95:36:95:36 | z | | Test.java:95:21:95:21 | x | Test.java:95:28:95:28 | y | | Test.java:95:28:95:28 | y | Test.java:95:15:95:29 | B(...) | @@ -321,17 +321,17 @@ | Test.java:101:6:101:18 | switch (...) | Test.java:101:13:101:17 | thing | | Test.java:101:13:101:17 | thing | Test.java:102:8:102:20 | case | | Test.java:102:8:102:20 | case | Test.java:102:15:102:15 | | -| Test.java:102:8:102:20 | case | Test.java:103:8:103:77 | case | +| Test.java:102:13:102:19 | B(...) | Test.java:103:8:103:77 | case | | Test.java:102:13:102:19 | B(...) | Test.java:105:10:105:15 | break | | Test.java:102:15:102:15 | | Test.java:102:18:102:18 | | | Test.java:102:18:102:18 | | Test.java:102:13:102:19 | B(...) | | Test.java:103:8:103:77 | case | Test.java:103:21:103:21 | | -| Test.java:103:8:103:77 | case | Test.java:103:31:103:31 | | -| Test.java:103:8:103:77 | case | Test.java:103:36:103:36 | | -| Test.java:103:8:103:77 | case | Test.java:104:8:104:20 | case | +| Test.java:103:21:103:21 | | Test.java:103:31:103:31 | | | Test.java:103:21:103:21 | | Test.java:103:47:103:51 | thing | +| Test.java:103:31:103:31 | | Test.java:103:36:103:36 | | | Test.java:103:31:103:31 | | Test.java:103:47:103:51 | thing | | Test.java:103:34:103:40 | A(...) | Test.java:103:47:103:51 | thing | +| Test.java:103:34:103:40 | A(...) | Test.java:104:8:104:20 | case | | Test.java:103:36:103:36 | | Test.java:103:39:103:39 | | | Test.java:103:39:103:39 | | Test.java:103:34:103:40 | A(...) | | Test.java:103:47:103:51 | thing | Test.java:103:47:103:62 | toString(...) | @@ -340,8 +340,8 @@ | Test.java:103:47:103:76 | equals(...) | Test.java:105:10:105:15 | break | | Test.java:103:71:103:75 | "abc" | Test.java:103:47:103:76 | equals(...) | | Test.java:104:8:104:20 | case | Test.java:104:19:104:19 | | -| Test.java:104:8:104:20 | case | Test.java:106:8:106:15 | default | | Test.java:104:19:104:19 | | Test.java:105:10:105:15 | break | +| Test.java:104:19:104:19 | | Test.java:106:8:106:15 | default | | Test.java:105:10:105:15 | break | Test.java:110:6:117:7 | var ...; | | Test.java:106:8:106:15 | default | Test.java:107:10:107:15 | break | | Test.java:107:10:107:15 | break | Test.java:110:6:117:7 | var ...; | @@ -350,17 +350,17 @@ | Test.java:110:19:110:31 | switch (...) | Test.java:110:26:110:30 | thing | | Test.java:110:26:110:30 | thing | Test.java:111:8:111:20 | case | | Test.java:111:8:111:20 | case | Test.java:111:15:111:15 | | -| Test.java:111:8:111:20 | case | Test.java:112:8:112:77 | case | +| Test.java:111:13:111:19 | B(...) | Test.java:112:8:112:77 | case | | Test.java:111:13:111:19 | B(...) | Test.java:114:16:114:16 | 1 | | Test.java:111:15:111:15 | | Test.java:111:18:111:18 | | | Test.java:111:18:111:18 | | Test.java:111:13:111:19 | B(...) | | Test.java:112:8:112:77 | case | Test.java:112:21:112:21 | | -| Test.java:112:8:112:77 | case | Test.java:112:31:112:31 | | -| Test.java:112:8:112:77 | case | Test.java:112:36:112:36 | | -| Test.java:112:8:112:77 | case | Test.java:113:8:113:20 | case | +| Test.java:112:21:112:21 | | Test.java:112:31:112:31 | | | Test.java:112:21:112:21 | | Test.java:112:47:112:51 | thing | +| Test.java:112:31:112:31 | | Test.java:112:36:112:36 | | | Test.java:112:31:112:31 | | Test.java:112:47:112:51 | thing | | Test.java:112:34:112:40 | A(...) | Test.java:112:47:112:51 | thing | +| Test.java:112:34:112:40 | A(...) | Test.java:113:8:113:20 | case | | Test.java:112:36:112:36 | | Test.java:112:39:112:39 | | | Test.java:112:39:112:39 | | Test.java:112:34:112:40 | A(...) | | Test.java:112:47:112:51 | thing | Test.java:112:47:112:62 | toString(...) | @@ -369,8 +369,8 @@ | Test.java:112:47:112:76 | equals(...) | Test.java:114:16:114:16 | 1 | | Test.java:112:71:112:75 | "abc" | Test.java:112:47:112:76 | equals(...) | | Test.java:113:8:113:20 | case | Test.java:113:19:113:19 | | -| Test.java:113:8:113:20 | case | Test.java:115:8:115:15 | default | | Test.java:113:19:113:19 | | Test.java:114:16:114:16 | 1 | +| Test.java:113:19:113:19 | | Test.java:115:8:115:15 | default | | Test.java:114:10:114:17 | yield ... | Test.java:110:10:110:31 | result | | Test.java:114:16:114:16 | 1 | Test.java:114:10:114:17 | yield ... | | Test.java:115:8:115:15 | default | Test.java:116:16:116:16 | 2 | @@ -380,11 +380,11 @@ | Test.java:119:14:119:26 | (...)... | Test.java:120:8:120:16 | case ... | | Test.java:119:22:119:26 | thing | Test.java:119:14:119:26 | (...)... | | Test.java:120:8:120:16 | case ... | Test.java:120:13:120:15 | "a" | -| Test.java:120:8:120:16 | case ... | Test.java:121:8:121:56 | case | +| Test.java:120:13:120:15 | "a" | Test.java:121:8:121:56 | case | | Test.java:120:13:120:15 | "a" | Test.java:123:10:123:15 | break | | Test.java:121:8:121:56 | case | Test.java:121:20:121:20 | | -| Test.java:121:8:121:56 | case | Test.java:122:8:122:16 | case ... | | Test.java:121:20:121:20 | | Test.java:121:36:121:40 | thing | +| Test.java:121:20:121:20 | | Test.java:122:8:122:16 | case ... | | Test.java:121:27:121:50 | length(...) | Test.java:121:55:121:55 | 5 | | Test.java:121:27:121:55 | ... == ... | Test.java:122:8:122:16 | case ... | | Test.java:121:27:121:55 | ... == ... | Test.java:123:10:123:15 | break | @@ -392,16 +392,16 @@ | Test.java:121:36:121:40 | thing | Test.java:121:28:121:40 | (...)... | | Test.java:121:55:121:55 | 5 | Test.java:121:27:121:55 | ... == ... | | Test.java:122:8:122:16 | case ... | Test.java:122:13:122:15 | "b" | -| Test.java:122:8:122:16 | case ... | Test.java:124:8:124:15 | default | | Test.java:122:13:122:15 | "b" | Test.java:123:10:123:15 | break | +| Test.java:122:13:122:15 | "b" | Test.java:124:8:124:15 | default | | Test.java:123:10:123:15 | break | Test.java:129:6:129:18 | switch (...) | | Test.java:124:8:124:15 | default | Test.java:125:10:125:15 | break | | Test.java:125:10:125:15 | break | Test.java:129:6:129:18 | switch (...) | | Test.java:129:6:129:18 | switch (...) | Test.java:129:13:129:17 | thing | | Test.java:129:13:129:17 | thing | Test.java:130:8:130:21 | case | | Test.java:130:8:130:21 | case | Test.java:130:20:130:20 | | -| Test.java:130:8:130:21 | case | Test.java:131:8:131:15 | default | | Test.java:130:20:130:20 | | Test.java:3:22:3:25 | Normal Exit | +| Test.java:130:20:130:20 | | Test.java:131:8:131:15 | default | | Test.java:131:8:131:15 | default | Test.java:3:22:3:25 | Normal Exit | | Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | ; | | Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | Normal Exit | diff --git a/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected b/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected index ad033101fd6..923978b4979 100644 --- a/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected @@ -87,8 +87,8 @@ | TestBreak.java:52:3:52:12 | switch (...) | TestBreak.java:52:11:52:11 | x | | TestBreak.java:52:11:52:11 | x | TestBreak.java:54:3:54:9 | case ... | | TestBreak.java:54:3:54:9 | case ... | TestBreak.java:54:8:54:8 | 1 | -| TestBreak.java:54:3:54:9 | case ... | TestBreak.java:57:3:57:9 | case ... | | TestBreak.java:54:8:54:8 | 1 | TestBreak.java:55:4:55:13 | ; | +| TestBreak.java:54:8:54:8 | 1 | TestBreak.java:57:3:57:9 | case ... | | TestBreak.java:55:4:55:4 | x | TestBreak.java:55:8:55:8 | x | | TestBreak.java:55:4:55:12 | ...=... | TestBreak.java:56:4:56:13 | ; | | TestBreak.java:55:4:55:13 | ; | TestBreak.java:55:4:55:4 | x | @@ -102,8 +102,8 @@ | TestBreak.java:56:8:56:12 | ... + ... | TestBreak.java:56:4:56:12 | ...=... | | TestBreak.java:56:12:56:12 | 1 | TestBreak.java:56:8:56:12 | ... + ... | | TestBreak.java:57:3:57:9 | case ... | TestBreak.java:57:8:57:8 | 2 | -| TestBreak.java:57:3:57:9 | case ... | TestBreak.java:61:3:61:9 | case ... | | TestBreak.java:57:8:57:8 | 2 | TestBreak.java:58:4:58:13 | ; | +| TestBreak.java:57:8:57:8 | 2 | TestBreak.java:61:3:61:9 | case ... | | TestBreak.java:58:4:58:4 | x | TestBreak.java:58:8:58:8 | x | | TestBreak.java:58:4:58:12 | ...=... | TestBreak.java:59:4:59:13 | ; | | TestBreak.java:58:4:58:13 | ; | TestBreak.java:58:4:58:4 | x | @@ -118,11 +118,11 @@ | TestBreak.java:59:12:59:12 | 2 | TestBreak.java:59:8:59:12 | ... + ... | | TestBreak.java:60:4:60:9 | break | TestBreak.java:76:3:76:11 | switch (...) | | TestBreak.java:61:3:61:9 | case ... | TestBreak.java:61:8:61:8 | 3 | -| TestBreak.java:61:3:61:9 | case ... | TestBreak.java:62:3:62:9 | case ... | +| TestBreak.java:61:8:61:8 | 3 | TestBreak.java:62:3:62:9 | case ... | | TestBreak.java:61:8:61:8 | 3 | TestBreak.java:63:4:63:13 | ; | | TestBreak.java:62:3:62:9 | case ... | TestBreak.java:62:8:62:8 | 4 | -| TestBreak.java:62:3:62:9 | case ... | TestBreak.java:66:3:66:9 | case ... | | TestBreak.java:62:8:62:8 | 4 | TestBreak.java:63:4:63:13 | ; | +| TestBreak.java:62:8:62:8 | 4 | TestBreak.java:66:3:66:9 | case ... | | TestBreak.java:63:4:63:4 | x | TestBreak.java:63:8:63:8 | x | | TestBreak.java:63:4:63:12 | ...=... | TestBreak.java:64:4:64:13 | ; | | TestBreak.java:63:4:63:13 | ; | TestBreak.java:63:4:63:4 | x | @@ -137,11 +137,11 @@ | TestBreak.java:64:12:64:12 | 4 | TestBreak.java:64:8:64:12 | ... + ... | | TestBreak.java:65:4:65:9 | break | TestBreak.java:76:3:76:11 | switch (...) | | TestBreak.java:66:3:66:9 | case ... | TestBreak.java:66:8:66:8 | 5 | -| TestBreak.java:66:3:66:9 | case ... | TestBreak.java:67:3:67:9 | case ... | +| TestBreak.java:66:8:66:8 | 5 | TestBreak.java:67:3:67:9 | case ... | | TestBreak.java:66:8:66:8 | 5 | TestBreak.java:68:4:68:13 | ; | | TestBreak.java:67:3:67:9 | case ... | TestBreak.java:67:8:67:8 | 6 | -| TestBreak.java:67:3:67:9 | case ... | TestBreak.java:70:3:70:10 | default | | TestBreak.java:67:8:67:8 | 6 | TestBreak.java:68:4:68:13 | ; | +| TestBreak.java:67:8:67:8 | 6 | TestBreak.java:70:3:70:10 | default | | TestBreak.java:68:4:68:4 | x | TestBreak.java:68:8:68:8 | x | | TestBreak.java:68:4:68:12 | ...=... | TestBreak.java:69:4:69:13 | ; | | TestBreak.java:68:4:68:13 | ; | TestBreak.java:68:4:68:4 | x | @@ -166,15 +166,15 @@ | TestBreak.java:76:3:76:11 | switch (...) | TestBreak.java:76:10:76:10 | x | | TestBreak.java:76:10:76:10 | x | TestBreak.java:78:3:78:9 | case ... | | TestBreak.java:78:3:78:9 | case ... | TestBreak.java:78:8:78:8 | 1 | -| TestBreak.java:78:3:78:9 | case ... | TestBreak.java:81:3:81:9 | case ... | | TestBreak.java:78:8:78:8 | 1 | TestBreak.java:79:4:79:9 | ; | +| TestBreak.java:78:8:78:8 | 1 | TestBreak.java:81:3:81:9 | case ... | | TestBreak.java:79:4:79:4 | x | TestBreak.java:79:8:79:8 | 1 | | TestBreak.java:79:4:79:8 | ...=... | TestBreak.java:80:4:80:9 | break | | TestBreak.java:79:4:79:9 | ; | TestBreak.java:79:4:79:4 | x | | TestBreak.java:79:8:79:8 | 1 | TestBreak.java:79:4:79:8 | ...=... | | TestBreak.java:80:4:80:9 | break | TestBreak.java:4:14:4:14 | Normal Exit | -| TestBreak.java:81:3:81:9 | case ... | TestBreak.java:4:14:4:14 | Normal Exit | | TestBreak.java:81:3:81:9 | case ... | TestBreak.java:81:8:81:8 | 2 | +| TestBreak.java:81:8:81:8 | 2 | TestBreak.java:4:14:4:14 | Normal Exit | | TestBreak.java:81:8:81:8 | 2 | TestBreak.java:82:4:82:9 | ; | | TestBreak.java:82:4:82:4 | x | TestBreak.java:82:8:82:8 | 2 | | TestBreak.java:82:4:82:8 | ...=... | TestBreak.java:83:4:83:9 | break | diff --git a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected index a6b5849eef6..fb986684465 100644 --- a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected @@ -148,8 +148,8 @@ | TestLoopBranch.java:62:3:62:12 | switch (...) | TestLoopBranch.java:62:11:62:11 | x | | TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:64:3:64:9 | case ... | | TestLoopBranch.java:64:3:64:9 | case ... | TestLoopBranch.java:64:8:64:8 | 1 | -| TestLoopBranch.java:64:3:64:9 | case ... | TestLoopBranch.java:67:3:67:9 | case ... | | TestLoopBranch.java:64:8:64:8 | 1 | TestLoopBranch.java:65:4:65:13 | ; | +| TestLoopBranch.java:64:8:64:8 | 1 | TestLoopBranch.java:67:3:67:9 | case ... | | TestLoopBranch.java:65:4:65:4 | x | TestLoopBranch.java:65:8:65:8 | x | | TestLoopBranch.java:65:4:65:12 | ...=... | TestLoopBranch.java:66:4:66:13 | ; | | TestLoopBranch.java:65:4:65:13 | ; | TestLoopBranch.java:65:4:65:4 | x | @@ -163,8 +163,8 @@ | TestLoopBranch.java:66:8:66:12 | ... + ... | TestLoopBranch.java:66:4:66:12 | ...=... | | TestLoopBranch.java:66:12:66:12 | 1 | TestLoopBranch.java:66:8:66:12 | ... + ... | | TestLoopBranch.java:67:3:67:9 | case ... | TestLoopBranch.java:67:8:67:8 | 2 | -| TestLoopBranch.java:67:3:67:9 | case ... | TestLoopBranch.java:71:3:71:9 | case ... | | TestLoopBranch.java:67:8:67:8 | 2 | TestLoopBranch.java:68:4:68:13 | ; | +| TestLoopBranch.java:67:8:67:8 | 2 | TestLoopBranch.java:71:3:71:9 | case ... | | TestLoopBranch.java:68:4:68:4 | x | TestLoopBranch.java:68:8:68:8 | x | | TestLoopBranch.java:68:4:68:12 | ...=... | TestLoopBranch.java:69:4:69:13 | ; | | TestLoopBranch.java:68:4:68:13 | ; | TestLoopBranch.java:68:4:68:4 | x | @@ -179,11 +179,11 @@ | TestLoopBranch.java:69:12:69:12 | 2 | TestLoopBranch.java:69:8:69:12 | ... + ... | | TestLoopBranch.java:70:4:70:9 | break | TestLoopBranch.java:86:3:86:11 | switch (...) | | TestLoopBranch.java:71:3:71:9 | case ... | TestLoopBranch.java:71:8:71:8 | 3 | -| TestLoopBranch.java:71:3:71:9 | case ... | TestLoopBranch.java:72:3:72:9 | case ... | +| TestLoopBranch.java:71:8:71:8 | 3 | TestLoopBranch.java:72:3:72:9 | case ... | | TestLoopBranch.java:71:8:71:8 | 3 | TestLoopBranch.java:73:4:73:13 | ; | | TestLoopBranch.java:72:3:72:9 | case ... | TestLoopBranch.java:72:8:72:8 | 4 | -| TestLoopBranch.java:72:3:72:9 | case ... | TestLoopBranch.java:76:3:76:9 | case ... | | TestLoopBranch.java:72:8:72:8 | 4 | TestLoopBranch.java:73:4:73:13 | ; | +| TestLoopBranch.java:72:8:72:8 | 4 | TestLoopBranch.java:76:3:76:9 | case ... | | TestLoopBranch.java:73:4:73:4 | x | TestLoopBranch.java:73:8:73:8 | x | | TestLoopBranch.java:73:4:73:12 | ...=... | TestLoopBranch.java:74:4:74:13 | ; | | TestLoopBranch.java:73:4:73:13 | ; | TestLoopBranch.java:73:4:73:4 | x | @@ -198,11 +198,11 @@ | TestLoopBranch.java:74:12:74:12 | 4 | TestLoopBranch.java:74:8:74:12 | ... + ... | | TestLoopBranch.java:75:4:75:9 | break | TestLoopBranch.java:86:3:86:11 | switch (...) | | TestLoopBranch.java:76:3:76:9 | case ... | TestLoopBranch.java:76:8:76:8 | 5 | -| TestLoopBranch.java:76:3:76:9 | case ... | TestLoopBranch.java:77:3:77:9 | case ... | +| TestLoopBranch.java:76:8:76:8 | 5 | TestLoopBranch.java:77:3:77:9 | case ... | | TestLoopBranch.java:76:8:76:8 | 5 | TestLoopBranch.java:78:4:78:13 | ; | | TestLoopBranch.java:77:3:77:9 | case ... | TestLoopBranch.java:77:8:77:8 | 6 | -| TestLoopBranch.java:77:3:77:9 | case ... | TestLoopBranch.java:80:3:80:10 | default | | TestLoopBranch.java:77:8:77:8 | 6 | TestLoopBranch.java:78:4:78:13 | ; | +| TestLoopBranch.java:77:8:77:8 | 6 | TestLoopBranch.java:80:3:80:10 | default | | TestLoopBranch.java:78:4:78:4 | x | TestLoopBranch.java:78:8:78:8 | x | | TestLoopBranch.java:78:4:78:12 | ...=... | TestLoopBranch.java:79:4:79:13 | ; | | TestLoopBranch.java:78:4:78:13 | ; | TestLoopBranch.java:78:4:78:4 | x | @@ -227,16 +227,16 @@ | TestLoopBranch.java:86:3:86:11 | switch (...) | TestLoopBranch.java:86:10:86:10 | x | | TestLoopBranch.java:86:10:86:10 | x | TestLoopBranch.java:88:3:88:9 | case ... | | TestLoopBranch.java:88:3:88:9 | case ... | TestLoopBranch.java:88:8:88:8 | 1 | -| TestLoopBranch.java:88:3:88:9 | case ... | TestLoopBranch.java:91:3:91:9 | case ... | | TestLoopBranch.java:88:8:88:8 | 1 | TestLoopBranch.java:89:4:89:9 | ; | +| TestLoopBranch.java:88:8:88:8 | 1 | TestLoopBranch.java:91:3:91:9 | case ... | | TestLoopBranch.java:89:4:89:4 | x | TestLoopBranch.java:89:8:89:8 | 1 | | TestLoopBranch.java:89:4:89:8 | ...=... | TestLoopBranch.java:90:4:90:9 | break | | TestLoopBranch.java:89:4:89:9 | ; | TestLoopBranch.java:89:4:89:4 | x | | TestLoopBranch.java:89:8:89:8 | 1 | TestLoopBranch.java:89:4:89:8 | ...=... | | TestLoopBranch.java:90:4:90:9 | break | TestLoopBranch.java:96:3:102:4 | var ...; | | TestLoopBranch.java:91:3:91:9 | case ... | TestLoopBranch.java:91:8:91:8 | 2 | -| TestLoopBranch.java:91:3:91:9 | case ... | TestLoopBranch.java:96:3:102:4 | var ...; | | TestLoopBranch.java:91:8:91:8 | 2 | TestLoopBranch.java:92:4:92:9 | ; | +| TestLoopBranch.java:91:8:91:8 | 2 | TestLoopBranch.java:96:3:102:4 | var ...; | | TestLoopBranch.java:92:4:92:4 | x | TestLoopBranch.java:92:8:92:8 | 2 | | TestLoopBranch.java:92:4:92:8 | ...=... | TestLoopBranch.java:93:4:93:9 | break | | TestLoopBranch.java:92:4:92:9 | ; | TestLoopBranch.java:92:4:92:4 | x | From f9240e7058782be85af2f0376f73b693c99e6d36 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Thu, 7 May 2026 15:57:33 +0100 Subject: [PATCH 31/43] Fix QL formatting --- java/ql/lib/semmle/code/java/security/PathSanitizer.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll index 000b953f5b8..1288569fa5b 100644 --- a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll +++ b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll @@ -290,9 +290,7 @@ private Method getSourceMethod(Method m) { } private class ExternalPathInjectionSanitizer extends PathInjectionSanitizer { - ExternalPathInjectionSanitizer() { - barrierNode(this, ["path-injection", "path-injection[read]"]) - } + ExternalPathInjectionSanitizer() { barrierNode(this, ["path-injection", "path-injection[read]"]) } } /** Holds if `g` is a guard that checks for `..` components. */ From a4df96aad68813f516c907676833f2aaa25e811f Mon Sep 17 00:00:00 2001 From: Taus Date: Thu, 7 May 2026 12:18:04 +0000 Subject: [PATCH 32/43] yeast: Support capturing unnamed nodes in queries Three improvements to the query parser, all aimed at allowing query patterns to refer to unnamed tokens: 1. Bare-literal capture: `"=" @op` now captures the unnamed `=` token, matching the parenthesized form `("=") @op`. Previously the literal branch in parse_query_list skipped the maybe_wrap_capture call, so the `@op` was a leftover token and would error. 2. Bare `_` matches any node, named or unnamed. Previously bare `_` and `(_)` both produced QueryNode::Any with the same matches_named_only behaviour, so bare `_` would skip unnamed children. Now Any carries a match_unnamed flag: false for `(_)` (named-only, tree-sitter default) and true for bare `_` (any node). 3. Named fields and bare child patterns may be intermixed in any order. Previously, once parse_query_fields saw a bare pattern it would stop accepting named fields. The fix accumulates bare patterns into the implicit `child` field and keeps parsing. Each named field independently selects its target field for matching, so the source-order of fields in the query is purely cosmetic and intermixing is safe. Add tests covering parenthesized capture, bare-literal capture, and the named-vs-any distinction between `(_)` and bare `_`. Update query-syntax docs to reflect all three. --- shared/yeast-macros/src/lib.rs | 9 ++- shared/yeast-macros/src/parse.rs | 50 ++++++++---- shared/yeast/doc/yeast.md | 25 ++++-- shared/yeast/src/query.rs | 14 +++- shared/yeast/tests/test.rs | 129 +++++++++++++++++++++++++++++++ 5 files changed, 200 insertions(+), 27 deletions(-) diff --git a/shared/yeast-macros/src/lib.rs b/shared/yeast-macros/src/lib.rs index 0c264ee13c8..1d7236b500a 100644 --- a/shared/yeast-macros/src/lib.rs +++ b/shared/yeast-macros/src/lib.rs @@ -9,14 +9,21 @@ mod parse; /// /// ```text /// (_) - match any named node (skips unnamed tokens) +/// _ - match any node, named or unnamed /// (kind) - match a named node of the given kind /// ("literal") - match an unnamed token by its text +/// "literal" - shorthand for `("literal")` /// (kind field: (pattern)) - match with named field -/// (kind (pat) (pat)...) - match unnamed children (after all fields) +/// (kind field: _) - bare `_` and bare literals work in field position too +/// (kind (pat) (pat)...) - match unnamed children /// (pattern) @capture - capture the matched node +/// "literal" @capture - capture an unnamed token +/// _ @capture - capture any node /// (pattern)* @capture - capture each repeated match /// (pattern)? - zero or one /// ``` +/// +/// Named fields and bare child patterns may be intermixed in any order. #[proc_macro] pub fn query(input: TokenStream) -> TokenStream { let input2: TokenStream2 = input.into(); diff --git a/shared/yeast-macros/src/parse.rs b/shared/yeast-macros/src/parse.rs index f8554f3178c..70bd46d5b6f 100644 --- a/shared/yeast-macros/src/parse.rs +++ b/shared/yeast-macros/src/parse.rs @@ -38,7 +38,8 @@ fn parse_query_node(tokens: &mut Tokens) -> Result { } } -/// Parse a query atom: `(kind fields...)` or `(kind fields... bare_children...)`. +/// Parse a query atom: a parenthesized node, a bare `_` (any node), or a +/// bare string literal (unnamed token). /// Does not handle `@capture` — that's handled by the caller as a postfix. fn parse_query_atom(tokens: &mut Tokens) -> Result { match tokens.peek() { @@ -58,9 +59,17 @@ fn parse_query_atom(tokens: &mut Tokens) -> Result { } Ok(result) } + Some(TokenTree::Ident(id)) if *id == "_" => { + tokens.next(); + Ok(quote! { yeast::query::QueryNode::Any { match_unnamed: true } }) + } + Some(TokenTree::Literal(_)) => { + let lit = expect_literal(tokens)?; + Ok(quote! { yeast::query::QueryNode::UnnamedNode { kind: #lit } }) + } Some(tok) => Err(syn::Error::new_spanned( tok.clone(), - "expected `(` in query; use `(_) @name` to capture a wildcard", + "expected `(`, `_`, or string literal in query", )), } } @@ -74,7 +83,7 @@ fn parse_query_node_inner(tokens: &mut Tokens) -> Result { )), Some(TokenTree::Ident(id)) if *id == "_" => { tokens.next(); - Ok(quote! { yeast::query::QueryNode::Any() }) + Ok(quote! { yeast::query::QueryNode::Any { match_unnamed: false } }) } Some(TokenTree::Literal(_)) => { let lit = expect_literal(tokens)?; @@ -98,11 +107,14 @@ fn parse_query_node_inner(tokens: &mut Tokens) -> Result { } } -/// Parse zero or more field specifications and trailing bare patterns. -/// Named fields: `name: pattern` or `name*: (list...)`. -/// Bare patterns (no field name) become implicit `child` field entries. +/// Parse zero or more field specifications and bare patterns. +/// Named fields: `name: pattern`. Bare patterns (no field name) become +/// implicit `child` field entries. Named fields and bare patterns may +/// 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(); + let mut bare_children: Vec = Vec::new(); while tokens.peek().is_some() { if peek_is_field(tokens) { let field_name = expect_ident(tokens, "expected field name")?; @@ -115,16 +127,21 @@ fn parse_query_fields(tokens: &mut Tokens) -> Result> { (#field_str, vec![yeast::query::QueryListElem::SingleNode(#child)]) }); } else { - // Bare patterns — collect as implicit `child` field + // Bare patterns — accumulate into the implicit `child` field. + // We don't break here, so we can interleave with named fields. let elems = parse_query_list(tokens)?; - if !elems.is_empty() { - fields.push(quote! { - ("child", vec![#(#elems),*]) - }); + if elems.is_empty() { + // Nothing more we can parse at this level. + break; } - break; + bare_children.extend(elems); } } + if !bare_children.is_empty() { + fields.push(quote! { + ("child", vec![#(#bare_children),*]) + }); + } Ok(fields) } @@ -178,10 +195,11 @@ fn parse_query_list(tokens: &mut Tokens) -> Result> { continue; } - // Check for string literal (unnamed node) + // Check for string literal (unnamed node), optionally followed by @capture if peek_is_literal(tokens) { let lit = expect_literal(tokens)?; let node = quote! { yeast::query::QueryNode::UnnamedNode { kind: #lit } }; + let node = maybe_wrap_capture(tokens, node)?; let elem = maybe_wrap_repetition( tokens, quote! { @@ -192,10 +210,12 @@ fn parse_query_list(tokens: &mut Tokens) -> Result> { continue; } - // Check for bare _ (wildcard), possibly followed by @capture + // Check for bare `_` (any node, named or unnamed), possibly followed by @capture. + // Distinct from `(_)` which only matches named nodes — this matches + // tree-sitter query semantics. if peek_is_underscore(tokens) { tokens.next(); - let node = quote! { yeast::query::QueryNode::Any() }; + let node = quote! { yeast::query::QueryNode::Any { match_unnamed: true } }; let node = maybe_wrap_capture(tokens, node)?; let elem = maybe_wrap_repetition( tokens, diff --git a/shared/yeast/doc/yeast.md b/shared/yeast/doc/yeast.md index d49ff96f11d..4deb89d3058 100644 --- a/shared/yeast/doc/yeast.md +++ b/shared/yeast/doc/yeast.md @@ -103,19 +103,30 @@ Captures bind matched nodes to names for use in the transform. A capture (identifier) @name // capture an identifier node (_) @value // capture any named node (identifier)* @items // capture each repeated match +("=") @op // capture an unnamed token by its text +"=" @op // shorthand for the line above +_ @anything // capture any node, named or unnamed ``` -### Unnamed children +### Named vs unnamed children -Patterns that appear after all named fields match unnamed (positional) -children. Named node patterns like `(_)` automatically skip unnamed tokens -(keywords, operators, punctuation), matching tree-sitter semantics: +The two wildcard forms `(_)` and bare `_` differ: + +- `(_)` matches only **named** nodes. When used as a positional pattern, + unnamed children (keywords, operators, punctuation) are skipped over to + find the next named child. +- Bare `_` matches **any** node, named or unnamed, taking whatever is next + in the child list. + +Similarly, named-kind patterns like `(call ...)` skip unnamed children; +unnamed-kind patterns like `("end")` or `"end"` consume the next child +unconditionally: ```rust (for - pattern: (_) @pat // named field - value: (in (_) @val) // "in" token is skipped automatically - body: (do (_)* @body) // "do" and "end" tokens skipped + pattern: (_) @pat // named field, captures any named node + value: (in (_) @val) // "in" wrapper is a named node here + body: (do (_)* @body) // "do" and "end" tokens skipped by (_) ) ``` diff --git a/shared/yeast/src/query.rs b/shared/yeast/src/query.rs index 223b3456919..710aaa7477d 100644 --- a/shared/yeast/src/query.rs +++ b/shared/yeast/src/query.rs @@ -2,7 +2,13 @@ use crate::{captures::Captures, Ast, Id}; #[derive(Debug, Clone)] pub enum QueryNode { - Any(), + /// A wildcard. With `match_unnamed = false` (the default for `(_)`), + /// only matches named nodes when used positionally — unnamed children + /// are skipped over. With `match_unnamed = true` (for bare `_`), the + /// wildcard consumes whatever the next child is, named or unnamed. + Any { + match_unnamed: bool, + }, Node { kind: &'static str, children: Vec<(&'static str, Vec)>, @@ -24,7 +30,7 @@ impl QueryNode { QueryNode::Node { kind, .. } => Some(kind), QueryNode::UnnamedNode { kind } => Some(kind), QueryNode::Capture { node, .. } => node.root_kind(), - QueryNode::Any() => None, + QueryNode::Any { .. } => None, } } } @@ -51,7 +57,7 @@ impl QueryNode { /// semantics where `(_)` only matches named nodes. fn matches_named_only(&self) -> bool { match self { - QueryNode::Any() => true, + QueryNode::Any { match_unnamed } => !match_unnamed, QueryNode::Node { .. } => true, QueryNode::UnnamedNode { .. } => false, QueryNode::Capture { node, .. } => node.matches_named_only(), @@ -60,7 +66,7 @@ impl QueryNode { pub fn do_match(&self, ast: &Ast, node: Id, matches: &mut Captures) -> Result { match self { - QueryNode::Any() => Ok(true), + QueryNode::Any { .. } => Ok(true), QueryNode::Node { kind, children } => { let node = ast.get_node(node).unwrap(); let target_kind = ast diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index e4485857bff..594e4cb35bc 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -170,6 +170,135 @@ fn test_query_repeated_capture() { assert_eq!(captures.get_all("names").len(), 3); } +#[test] +fn test_capture_unnamed_node_parenthesized() { + // `("=") @op` captures the unnamed `=` token between left and right. + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("x = 1").unwrap(); + + let query = yeast::query!( + (assignment + left: (_) @lhs + ("=") @op + right: (_) @rhs + ) + ); + + let mut cursor = AstCursor::new(&ast); + cursor.goto_first_child(); + let assignment_id = cursor.node().id(); + + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, assignment_id, &mut captures).unwrap(); + assert!(matched); + let op_id = captures.get_var("op").unwrap(); + let op_node = ast.get_node(op_id).unwrap(); + assert_eq!(op_node.kind(), "="); + assert!(!op_node.is_named()); +} + +#[test] +fn test_capture_unnamed_node_bare_literal() { + // `"=" @op` (without surrounding parens) is the same as `("=") @op`. + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("x = 1").unwrap(); + + let query = yeast::query!( + (assignment + left: (_) @lhs + "=" @op + right: (_) @rhs + ) + ); + + let mut cursor = AstCursor::new(&ast); + cursor.goto_first_child(); + let assignment_id = cursor.node().id(); + + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, assignment_id, &mut captures).unwrap(); + assert!(matched); + let op_id = captures.get_var("op").unwrap(); + let op_node = ast.get_node(op_id).unwrap(); + assert_eq!(op_node.kind(), "="); + assert!(!op_node.is_named()); +} + +#[test] +fn test_bare_underscore_matches_unnamed() { + // Bare `_` matches any node, including unnamed tokens, while `(_)` + // matches only named nodes. Demonstrate by matching the unnamed `=` + // token in the implicit `child` field of an `assignment`. + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("x = 1").unwrap(); + + let mut cursor = AstCursor::new(&ast); + cursor.goto_first_child(); + let assignment_id = cursor.node().id(); + + // `(_)` skips unnamed children, so a query containing a single `(_)` + // bare pattern fails to match the assignment (whose only unfielded + // child is the unnamed `=`). + let query_named = yeast::query!((assignment (_) @any)); + let mut captures = yeast::captures::Captures::new(); + let matched = query_named + .do_match(&ast, assignment_id, &mut captures) + .unwrap(); + assert!( + !matched, + "(_) should skip the unnamed `=` and fail to match" + ); + + // Bare `_` accepts the next child whatever it is, so it matches the + // unnamed `=` token. + let query_any = yeast::query!((assignment _ @any)); + let mut captures = yeast::captures::Captures::new(); + let matched = query_any + .do_match(&ast, assignment_id, &mut captures) + .unwrap(); + assert!(matched, "_ should match the unnamed `=`"); + let any_node = ast.get_node(captures.get_var("any").unwrap()).unwrap(); + assert_eq!(any_node.kind(), "="); + assert!(!any_node.is_named()); +} + +#[test] +fn test_bare_forms_in_field_position() { + // The bare `_` and bare-literal forms should be accepted as a + // field's value, not just in the bare-children position. This is + // syntactic sugar for `(_)` / `("…")` and goes through the same + // code paths. + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("x = 1").unwrap(); + + let mut cursor = AstCursor::new(&ast); + cursor.goto_first_child(); + let assignment_id = cursor.node().id(); + + // Bare `_` in field position. Captures the named `identifier "x"` + // child of the `left` field — bare `_` admits unnamed too, but the + // first child of `left` happens to be named. + let query = yeast::query!((assignment left: _ @lhs)); + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, assignment_id, &mut captures).unwrap(); + assert!(matched); + assert_eq!( + ast.get_node(captures.get_var("lhs").unwrap()) + .unwrap() + .kind(), + "identifier" + ); + + // Bare literal in field position. Equivalent to `("=") @op`. + let query = yeast::query!((assignment child: "=" @op)); + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, assignment_id, &mut captures).unwrap(); + assert!(matched); + let op = ast.get_node(captures.get_var("op").unwrap()).unwrap(); + assert_eq!(op.kind(), "="); + assert!(!op.is_named()); +} + // ---- Tree builder tests ---- #[test] From 6f643a36045d559c5b6c2410a9f37d87f2aa6dcb Mon Sep 17 00:00:00 2001 From: Taus Date: Thu, 7 May 2026 12:35:58 +0000 Subject: [PATCH 33/43] yeast: Use canonical ID when registering unnamed kinds in Schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Schema::from_language registered unnamed kinds via or_insert(id), where `id` came from iterating 0..node_kind_count. For names with multiple unnamed IDs (notably "end" in tree-sitter-ruby has IDs 0 and 13, where ID 0 is the reserved error token), this picked the first encountered ID — typically the wrong one. The visitor sets node.kind via language.id_for_node_kind(name, false), which returns the canonical ID. So a query for ("end") would compare node.kind=13 against schema=0 and silently fail to match, with no diagnostic. Use language.id_for_node_kind(name, false) to obtain the canonical ID when registering, mirroring the named-kind path that already does the same with id_for_node_kind(name, true). --- shared/yeast/src/schema.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/shared/yeast/src/schema.rs b/shared/yeast/src/schema.rs index 0a33fd6e0ed..12554d9c869 100644 --- a/shared/yeast/src/schema.rs +++ b/shared/yeast/src/schema.rs @@ -61,9 +61,10 @@ impl Schema { } } // Import all node kind names, preserving tree-sitter's IDs. - // Track named and unnamed variants separately. - // For named kinds, use the canonical ID from id_for_node_kind(name, true) - // since some languages have multiple IDs for the same named kind. + // Track named and unnamed variants separately. For both named and + // unnamed kinds, use the canonical ID from id_for_node_kind, since + // some languages have multiple IDs for the same name (e.g., the + // reserved error token at ID 0 may share a name with a real token). for id in 0..language.node_kind_count() as u16 { if let Some(name) = language.node_kind_for_id(id) { if !name.is_empty() { @@ -75,12 +76,13 @@ impl Schema { schema.kind_names.insert(canonical_id, name); } } else { - // For unnamed kinds, only insert if we don't already have one - // (some languages have multiple unnamed IDs for the same text) - schema - .unnamed_kind_ids - .entry(name.to_string()) - .or_insert(id); + let canonical_id = language.id_for_node_kind(name, false); + if canonical_id != 0 && !schema.unnamed_kind_ids.contains_key(name) { + schema + .unnamed_kind_ids + .insert(name.to_string(), canonical_id); + schema.kind_names.insert(canonical_id, name); + } } // Always track the name for any ID we encounter schema.kind_names.entry(id).or_insert(name); From af6e921da5ce8f894e31b7751d43f134141d534a Mon Sep 17 00:00:00 2001 From: Taus Date: Thu, 7 May 2026 12:36:13 +0000 Subject: [PATCH 34/43] yeast: Forward-scan bare child patterns instead of strict positional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, a bare child pattern in a query took whatever the next child of the iterator was and either matched or failed: it would not scan ahead to find a match. So `(foo ("baz"))` against a `foo` whose implicit `child` field was `["bar", "baz"]` would fail (the pattern took "bar" first). Switch to forward-scan semantics: a SingleNode matcher advances through the iterator until it finds a child that matches its sub-query. Patterns that are named-only continue to skip past unnamed children for free. Order is preserved across multiple bare patterns at the same level — each pattern advances the shared iterator past whatever it consumed — so a query cannot match children out of source order. Captures from a failed match attempt are rolled back via a snapshot, so partial captures from a complex sub-query do not leak across attempts. Add two regression tests against the `do` body wrapper in a Ruby for-loop, whose implicit `child` field contains [do, identifier, end]: - a query for ("end") matches by skipping past `do` and the identifier - a query for ("end") then ("do") fails, demonstrating order preservation --- shared/yeast/doc/yeast.md | 20 +++++++++++---- shared/yeast/src/query.rs | 37 ++++++++++++++------------- shared/yeast/tests/test.rs | 52 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 22 deletions(-) diff --git a/shared/yeast/doc/yeast.md b/shared/yeast/doc/yeast.md index 4deb89d3058..5a6267fba0f 100644 --- a/shared/yeast/doc/yeast.md +++ b/shared/yeast/doc/yeast.md @@ -113,14 +113,24 @@ _ @anything // capture any node, named or unnamed The two wildcard forms `(_)` and bare `_` differ: - `(_)` matches only **named** nodes. When used as a positional pattern, - unnamed children (keywords, operators, punctuation) are skipped over to - find the next named child. + unnamed children (keywords, operators, punctuation) are skipped over. - Bare `_` matches **any** node, named or unnamed, taking whatever is next in the child list. -Similarly, named-kind patterns like `(call ...)` skip unnamed children; -unnamed-kind patterns like `("end")` or `"end"` consume the next child -unconditionally: +Bare child patterns are matched **forward-scan**: each pattern advances +through the iterator until it finds a child that matches, skipping +non-matching children along the way. So `(foo ("baz"))` against a `foo` +whose children are `[bar, baz]` succeeds — the matcher scans past `bar` +and matches `baz`. The iterator advances as it goes, so subsequent +patterns can never match children that appear earlier in source order +than already-matched ones. + +For named-only patterns (`(_)`, `(some_kind ...)`), the scan additionally +skips past unnamed tokens without trying to match them, since they can +never match anyway. + +Anchors (`.`) for forcing immediate adjacency, like in tree-sitter +queries, are not supported. ```rust (for diff --git a/shared/yeast/src/query.rs b/shared/yeast/src/query.rs index 710aaa7477d..01e5e22ad73 100644 --- a/shared/yeast/src/query.rs +++ b/shared/yeast/src/query.rs @@ -167,25 +167,28 @@ impl QueryListElem { } } QueryListElem::SingleNode(sub_query) => { - if sub_query.matches_named_only() { - // Skip unnamed children, matching tree-sitter semantics - // where (_) only matches named nodes. - loop { - match remaining_children.next() { - Some(child) => { - let node = ast.get_node(child).unwrap(); - if node.is_named() { - return sub_query.do_match(ast, child, matches); - } - // Skip unnamed child, continue to next - } - None => return Ok(false), + // Forward-scan semantics: advance through the iterator until + // we find a child that matches `sub_query`. Skip ahead past + // unnamed children when the sub-query is named-only (so they + // can never match anyway). On a match attempt that fails, + // restore the captures so partial captures from a complex + // sub-query don't leak. + let skip_unnamed = sub_query.matches_named_only(); + loop { + 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; } } - } else if let Some(child) = remaining_children.next() { - sub_query.do_match(ast, child, matches) - } else { - Ok(false) + let snapshot = matches.clone(); + if sub_query.do_match(ast, child, matches)? { + return Ok(true); + } + *matches = snapshot; } } } diff --git a/shared/yeast/tests/test.rs b/shared/yeast/tests/test.rs index 594e4cb35bc..f7b363294bc 100644 --- a/shared/yeast/tests/test.rs +++ b/shared/yeast/tests/test.rs @@ -299,6 +299,58 @@ fn test_bare_forms_in_field_position() { assert!(!op.is_named()); } +#[test] +fn test_forward_scan_finds_unnamed_token_late() { + // The `do` named-wrapper node has three children in its implicit + // `child` field, in source order: `do` (unnamed kw), the body + // identifier, and `end` (unnamed kw). Forward-scan semantics let a + // query for `("end")` skip past the first two and match the third. + // Without forward-scan, the matcher took the first child unconditionally + // and failed. + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("for x in list do\n y\nend").unwrap(); + + // Navigate: program > for > do (the body wrapper). + let mut cursor = AstCursor::new(&ast); + cursor.goto_first_child(); // for + cursor.goto_first_child(); // do (the body) + while cursor.node().kind() != "do" || !cursor.node().is_named() { + assert!(cursor.goto_next_sibling(), "expected to find named `do`"); + } + let do_id = cursor.node().id(); + + let query = yeast::query!((do ("end") @kw)); + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, do_id, &mut captures).unwrap(); + assert!(matched, "forward-scan should find the `end` keyword"); + let kw = ast.get_node(captures.get_var("kw").unwrap()).unwrap(); + assert_eq!(kw.kind(), "end"); + assert!(!kw.is_named()); +} + +#[test] +fn test_forward_scan_preserves_order() { + // Bare patterns are scanned left-to-right and consume positions in + // order. A query for ("end") then ("do") should fail because `do` + // appears before `end` in the source order; once forward-scan has + // consumed `end`, the iterator is exhausted. + let runner = Runner::new(tree_sitter_ruby::LANGUAGE.into(), &[]); + let ast = runner.run("for x in list do\n y\nend").unwrap(); + + let mut cursor = AstCursor::new(&ast); + cursor.goto_first_child(); + cursor.goto_first_child(); + while cursor.node().kind() != "do" || !cursor.node().is_named() { + assert!(cursor.goto_next_sibling(), "expected to find named `do`"); + } + let do_id = cursor.node().id(); + + let query = yeast::query!((do ("end") @first ("do") @second)); + let mut captures = yeast::captures::Captures::new(); + let matched = query.do_match(&ast, do_id, &mut captures).unwrap(); + assert!(!matched, "scan must not go backwards"); +} + // ---- Tree builder tests ---- #[test] From 0210c970f24545ca664ec2dca925c8f5083eaa27 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 6 May 2026 15:46:44 +0200 Subject: [PATCH 35/43] Add tree-sitter for Swift (called 'unified') --- Cargo.lock | 28 + Cargo.toml | 1 + MODULE.bazel | 1 + .../tree_sitter_extractors_deps/BUILD.bazel | 12 + .../BUILD.tree-sitter-swift-0.7.2.bazel | 166 + .../tree_sitter_extractors_deps/defs.bzl | 50 + unified/.gitignore | 6 + unified/BUILD.bazel | 57 + unified/codeql-extractor.yml | 17 + unified/extractor/BUILD.bazel | 19 + unified/extractor/Cargo.toml | 22 + unified/extractor/src/autobuilder.rs | 20 + unified/extractor/src/extractor.rs | 43 + unified/extractor/src/generator.rs | 27 + unified/extractor/src/main.rs | 23 + unified/ql/lib/BUILD.bazel | 13 + unified/ql/lib/codeql/Locations.qll | 70 + unified/ql/lib/codeql/files/FileSystem.qll | 38 + unified/ql/lib/codeql/unified/Ast.qll | 2842 +++++++++++++++++ unified/ql/lib/qlpack.lock.yml | 4 + unified/ql/lib/qlpack.yml | 11 + unified/ql/lib/unified.dbscheme | 2741 ++++++++++++++++ unified/ql/lib/unified.dbscheme.stats | 4 + unified/ql/src/qlpack.lock.yml | 4 + unified/ql/src/qlpack.yml | 11 + .../library-tests/BasicTest/test.expected | 100 + .../ql/test/library-tests/BasicTest/test.ql | 5 + .../test/library-tests/BasicTest/test.swift | 88 + unified/ql/test/qlpack.lock.yml | 4 + unified/ql/test/qlpack.yml | 8 + unified/scripts/create-extractor-pack.sh | 25 + unified/tools/BUILD.bazel | 11 + unified/tools/autobuild.cmd | 5 + unified/tools/autobuild.sh | 3 + unified/tools/index-files.cmd | 9 + unified/tools/index-files.sh | 9 + unified/tools/qltest.cmd | 14 + unified/tools/qltest.sh | 12 + 38 files changed, 6523 insertions(+) create mode 100644 misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-swift-0.7.2.bazel create mode 100644 unified/.gitignore create mode 100644 unified/BUILD.bazel create mode 100644 unified/codeql-extractor.yml create mode 100644 unified/extractor/BUILD.bazel create mode 100644 unified/extractor/Cargo.toml create mode 100644 unified/extractor/src/autobuilder.rs create mode 100644 unified/extractor/src/extractor.rs create mode 100644 unified/extractor/src/generator.rs create mode 100644 unified/extractor/src/main.rs create mode 100644 unified/ql/lib/BUILD.bazel create mode 100644 unified/ql/lib/codeql/Locations.qll create mode 100644 unified/ql/lib/codeql/files/FileSystem.qll create mode 100644 unified/ql/lib/codeql/unified/Ast.qll create mode 100644 unified/ql/lib/qlpack.lock.yml create mode 100644 unified/ql/lib/qlpack.yml create mode 100644 unified/ql/lib/unified.dbscheme create mode 100644 unified/ql/lib/unified.dbscheme.stats create mode 100644 unified/ql/src/qlpack.lock.yml create mode 100644 unified/ql/src/qlpack.yml create mode 100644 unified/ql/test/library-tests/BasicTest/test.expected create mode 100644 unified/ql/test/library-tests/BasicTest/test.ql create mode 100644 unified/ql/test/library-tests/BasicTest/test.swift create mode 100644 unified/ql/test/qlpack.lock.yml create mode 100644 unified/ql/test/qlpack.yml create mode 100755 unified/scripts/create-extractor-pack.sh create mode 100644 unified/tools/BUILD.bazel create mode 100644 unified/tools/autobuild.cmd create mode 100755 unified/tools/autobuild.sh create mode 100644 unified/tools/index-files.cmd create mode 100755 unified/tools/index-files.sh create mode 100644 unified/tools/qltest.cmd create mode 100755 unified/tools/qltest.sh diff --git a/Cargo.lock b/Cargo.lock index 12be6b1cc43..895349ca6e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -438,6 +438,24 @@ dependencies = [ "tree-sitter-ruby", ] +[[package]] +name = "codeql-extractor-unified" +version = "0.1.0" +dependencies = [ + "clap", + "codeql-extractor", + "encoding", + "lazy_static", + "rayon", + "regex", + "serde_json", + "tracing", + "tracing-subscriber", + "tree-sitter", + "tree-sitter-embedded-template", + "tree-sitter-swift", +] + [[package]] name = "codeql-rust" version = "0.1.0" @@ -2922,6 +2940,16 @@ dependencies = [ "tree-sitter-language", ] +[[package]] +name = "tree-sitter-swift" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b98fb6bc8e6a6a10023f401aa6a1858115e849dfaf7de57dd8b8ea0f257bd9" +dependencies = [ + "cc", + "tree-sitter-language", +] + [[package]] name = "triomphe" version = "0.1.14" diff --git a/Cargo.toml b/Cargo.toml index 1e2be0d9ca5..4054c3a50be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "shared/yeast", "shared/yeast-macros", "ruby/extractor", + "unified/extractor", "rust/extractor", "rust/extractor/macros", "rust/ast-generator", diff --git a/MODULE.bazel b/MODULE.bazel index e7474e9a393..ee40f7789e4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -153,6 +153,7 @@ use_repo( "vendor_ts__tree-sitter-python-0.23.6", "vendor_ts__tree-sitter-ql-0.23.1", "vendor_ts__tree-sitter-ruby-0.23.1", + "vendor_ts__tree-sitter-swift-0.7.2", "vendor_ts__triomphe-0.1.14", "vendor_ts__ungrammar-1.16.1", "vendor_ts__zstd-0.13.3", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel index 27d36c221ea..1d1b47192a2 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel @@ -673,6 +673,18 @@ alias( tags = ["manual"], ) +alias( + name = "tree-sitter-swift-0.7.2", + actual = "@vendor_ts__tree-sitter-swift-0.7.2//:tree_sitter_swift", + tags = ["manual"], +) + +alias( + name = "tree-sitter-swift", + actual = "@vendor_ts__tree-sitter-swift-0.7.2//:tree_sitter_swift", + tags = ["manual"], +) + alias( name = "triomphe-0.1.14", actual = "@vendor_ts__triomphe-0.1.14//:triomphe", diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-swift-0.7.2.bazel b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-swift-0.7.2.bazel new file mode 100644 index 00000000000..f9bb6fa50c3 --- /dev/null +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.tree-sitter-swift-0.7.2.bazel @@ -0,0 +1,166 @@ +############################################################################### +# @generated +# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To +# regenerate this file, run the following: +# +# bazel run @@//misc/bazel/3rdparty:vendor_tree_sitter_extractors +############################################################################### + +load( + "@rules_rust//cargo:defs.bzl", + "cargo_build_script", + "cargo_toml_env_vars", +) +load("@rules_rust//rust:defs.bzl", "rust_library") + +package(default_visibility = ["//visibility:public"]) + +cargo_toml_env_vars( + name = "cargo_toml_env_vars", + src = "Cargo.toml", +) + +rust_library( + name = "tree_sitter_swift", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_root = "bindings/rust/lib.rs", + edition = "2018", + rustc_env_files = [ + ":cargo_toml_env_vars", + ], + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=tree-sitter-swift", + "manual", + "noclippy", + "norustfmt", + ], + target_compatible_with = select({ + "@rules_rust//rust/platform:aarch64-apple-darwin": [], + "@rules_rust//rust/platform:aarch64-apple-ios": [], + "@rules_rust//rust/platform:aarch64-apple-ios-sim": [], + "@rules_rust//rust/platform:aarch64-linux-android": [], + "@rules_rust//rust/platform:aarch64-pc-windows-msvc": [], + "@rules_rust//rust/platform:aarch64-unknown-fuchsia": [], + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [], + "@rules_rust//rust/platform:aarch64-unknown-uefi": [], + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:arm-unknown-linux-musleabi": [], + "@rules_rust//rust/platform:armv7-linux-androideabi": [], + "@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [], + "@rules_rust//rust/platform:i686-apple-darwin": [], + "@rules_rust//rust/platform:i686-linux-android": [], + "@rules_rust//rust/platform:i686-pc-windows-msvc": [], + "@rules_rust//rust/platform:i686-unknown-freebsd": [], + "@rules_rust//rust/platform:i686-unknown-linux-gnu": [], + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [], + "@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu": [], + "@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [], + "@rules_rust//rust/platform:s390x-unknown-linux-gnu": [], + "@rules_rust//rust/platform:thumbv7em-none-eabi": [], + "@rules_rust//rust/platform:thumbv8m.main-none-eabi": [], + "@rules_rust//rust/platform:wasm32-unknown-emscripten": [], + "@rules_rust//rust/platform:wasm32-unknown-unknown": [], + "@rules_rust//rust/platform:wasm32-wasip1": [], + "@rules_rust//rust/platform:wasm32-wasip1-threads": [], + "@rules_rust//rust/platform:wasm32-wasip2": [], + "@rules_rust//rust/platform:x86_64-apple-darwin": [], + "@rules_rust//rust/platform:x86_64-apple-ios": [], + "@rules_rust//rust/platform:x86_64-linux-android": [], + "@rules_rust//rust/platform:x86_64-pc-windows-msvc": [], + "@rules_rust//rust/platform:x86_64-unknown-freebsd": [], + "@rules_rust//rust/platform:x86_64-unknown-fuchsia": [], + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [], + "@rules_rust//rust/platform:x86_64-unknown-none": [], + "@rules_rust//rust/platform:x86_64-unknown-uefi": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + version = "0.7.2", + deps = [ + "@vendor_ts__tree-sitter-language-0.1.5//:tree_sitter_language", + "@vendor_ts__tree-sitter-swift-0.7.2//:build_script_build", + ], +) + +cargo_build_script( + name = "_bs", + srcs = glob( + include = ["**/*.rs"], + allow_empty = True, + ), + compile_data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + "**/*.rs", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + crate_name = "build_script_build", + crate_root = "bindings/rust/build.rs", + data = glob( + include = ["**"], + allow_empty = True, + exclude = [ + "**/* *", + ".tmp_git_root/**/*", + "BUILD", + "BUILD.bazel", + "WORKSPACE", + "WORKSPACE.bazel", + ], + ), + edition = "2018", + pkg_name = "tree-sitter-swift", + rustc_env_files = [ + ":cargo_toml_env_vars", + ], + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-bazel", + "crate-name=tree-sitter-swift", + "manual", + "noclippy", + "norustfmt", + ], + version = "0.7.2", + visibility = ["//visibility:private"], + deps = [ + "@vendor_ts__cc-1.2.61//:cc", + ], +) + +alias( + name = "build_script_build", + actual = ":_bs", + tags = ["manual"], +) diff --git a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl index d1da77819f3..4f70edd6ab3 100644 --- a/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl +++ b/misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl @@ -403,6 +403,21 @@ _NORMAL_DEPENDENCIES = { "syn": Label("@vendor_ts__syn-2.0.106//:syn"), }, }, + "unified/extractor": { + _COMMON_CONDITION: { + "clap": Label("@vendor_ts__clap-4.5.48//:clap"), + "encoding": Label("@vendor_ts__encoding-0.2.33//:encoding"), + "lazy_static": Label("@vendor_ts__lazy_static-1.5.0//:lazy_static"), + "rayon": Label("@vendor_ts__rayon-1.11.0//:rayon"), + "regex": Label("@vendor_ts__regex-1.11.3//:regex"), + "serde_json": Label("@vendor_ts__serde_json-1.0.145//:serde_json"), + "tracing": Label("@vendor_ts__tracing-0.1.41//:tracing"), + "tracing-subscriber": Label("@vendor_ts__tracing-subscriber-0.3.20//:tracing_subscriber"), + "tree-sitter": Label("@vendor_ts__tree-sitter-0.26.8//:tree_sitter"), + "tree-sitter-embedded-template": Label("@vendor_ts__tree-sitter-embedded-template-0.25.0//:tree_sitter_embedded_template"), + "tree-sitter-swift": Label("@vendor_ts__tree-sitter-swift-0.7.2//:tree_sitter_swift"), + }, + }, } _NORMAL_ALIASES = { @@ -437,6 +452,10 @@ _NORMAL_ALIASES = { _COMMON_CONDITION: { }, }, + "unified/extractor": { + _COMMON_CONDITION: { + }, + }, } _NORMAL_DEV_DEPENDENCIES = { @@ -461,6 +480,8 @@ _NORMAL_DEV_DEPENDENCIES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _NORMAL_DEV_ALIASES = { @@ -482,6 +503,8 @@ _NORMAL_DEV_ALIASES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _PROC_MACRO_DEPENDENCIES = { @@ -501,6 +524,8 @@ _PROC_MACRO_DEPENDENCIES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _PROC_MACRO_ALIASES = { @@ -520,6 +545,8 @@ _PROC_MACRO_ALIASES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _PROC_MACRO_DEV_DEPENDENCIES = { @@ -539,6 +566,8 @@ _PROC_MACRO_DEV_DEPENDENCIES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _PROC_MACRO_DEV_ALIASES = { @@ -560,6 +589,8 @@ _PROC_MACRO_DEV_ALIASES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _BUILD_DEPENDENCIES = { @@ -579,6 +610,8 @@ _BUILD_DEPENDENCIES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _BUILD_ALIASES = { @@ -598,6 +631,8 @@ _BUILD_ALIASES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _BUILD_PROC_MACRO_DEPENDENCIES = { @@ -617,6 +652,8 @@ _BUILD_PROC_MACRO_DEPENDENCIES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _BUILD_PROC_MACRO_ALIASES = { @@ -636,6 +673,8 @@ _BUILD_PROC_MACRO_ALIASES = { }, "shared/yeast-macros": { }, + "unified/extractor": { + }, } _CONDITIONS = { @@ -3497,6 +3536,16 @@ def crate_repositories(): build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.tree-sitter-ruby-0.23.1.bazel"), ) + maybe( + http_archive, + name = "vendor_ts__tree-sitter-swift-0.7.2", + sha256 = "f3b98fb6bc8e6a6a10023f401aa6a1858115e849dfaf7de57dd8b8ea0f257bd9", + type = "tar.gz", + urls = ["https://static.crates.io/crates/tree-sitter-swift/0.7.2/download"], + strip_prefix = "tree-sitter-swift-0.7.2", + build_file = Label("//misc/bazel/3rdparty/tree_sitter_extractors_deps:BUILD.tree-sitter-swift-0.7.2.bazel"), + ) + maybe( http_archive, name = "vendor_ts__triomphe-0.1.14", @@ -4238,6 +4287,7 @@ def crate_repositories(): struct(repo = "vendor_ts__tree-sitter-embedded-template-0.25.0", is_dev_dep = False), struct(repo = "vendor_ts__tree-sitter-python-0.23.6", is_dev_dep = False), struct(repo = "vendor_ts__tree-sitter-ruby-0.23.1", is_dev_dep = False), + struct(repo = "vendor_ts__tree-sitter-swift-0.7.2", is_dev_dep = False), struct(repo = "vendor_ts__triomphe-0.1.14", is_dev_dep = False), struct(repo = "vendor_ts__ungrammar-1.16.1", is_dev_dep = False), struct(repo = "vendor_ts__zstd-0.13.3", is_dev_dep = False), diff --git a/unified/.gitignore b/unified/.gitignore new file mode 100644 index 00000000000..5878737805f --- /dev/null +++ b/unified/.gitignore @@ -0,0 +1,6 @@ +target +.vscode/launch.json +.cache +ql/test/**/*.testproj +ql/test/**/*.actual +.codeql diff --git a/unified/BUILD.bazel b/unified/BUILD.bazel new file mode 100644 index 00000000000..e702fd25159 --- /dev/null +++ b/unified/BUILD.bazel @@ -0,0 +1,57 @@ +load("@rules_pkg//pkg:mappings.bzl", "pkg_filegroup") +load("//misc/bazel:pkg.bzl", "codeql_pack", "codeql_pkg_files") + +package(default_visibility = ["//visibility:public"]) + +alias( + name = "dbscheme", + actual = "//unified/ql/lib:dbscheme", +) + +alias( + name = "dbscheme-stats", + actual = "//unified/ql/lib:dbscheme-stats", +) + +codeql_pkg_files( + name = "dbscheme-group", + srcs = [ + ":dbscheme", + ":dbscheme-stats", + ], + strip_prefix = None, +) + +pkg_filegroup( + name = "db-files", + srcs = [ + ":dbscheme-group", + ], +) + +codeql_pkg_files( + name = "codeql-extractor-yml", + srcs = [ + "codeql-extractor.yml", + "//:LICENSE", + ], + strip_prefix = None, +) + +codeql_pkg_files( + name = "extractor-arch", + exes = [ + "//unified/extractor", + ], + prefix = "tools/{CODEQL_PLATFORM}", +) + +codeql_pack( + name = "unified", + srcs = [ + ":codeql-extractor-yml", + ":dbscheme-group", + ":extractor-arch", + "//unified/tools", + ], +) diff --git a/unified/codeql-extractor.yml b/unified/codeql-extractor.yml new file mode 100644 index 00000000000..388566c09f1 --- /dev/null +++ b/unified/codeql-extractor.yml @@ -0,0 +1,17 @@ +name: "unified" +display_name: "Unified Language" +version: 0.0.1 +column_kind: "utf8" +legacy_qltest_extraction: true +build_modes: + - none +github_api_languages: + - Swift +scc_languages: + - Swift +file_types: + - name: swift + display_name: Swift files + extensions: + - .swift + - .swiftinterface diff --git a/unified/extractor/BUILD.bazel b/unified/extractor/BUILD.bazel new file mode 100644 index 00000000000..8c22b4775f2 --- /dev/null +++ b/unified/extractor/BUILD.bazel @@ -0,0 +1,19 @@ +load("//misc/bazel:rust.bzl", "codeql_rust_binary") +load("//misc/bazel/3rdparty/tree_sitter_extractors_deps:defs.bzl", "aliases", "all_crate_deps") + +exports_files(["Cargo.toml"]) + +codeql_rust_binary( + name = "extractor", + srcs = glob(["src/*.rs"]), + aliases = aliases(), + proc_macro_deps = all_crate_deps( + proc_macro = True, + ), + visibility = ["//visibility:public"], + deps = all_crate_deps( + normal = True, + ) + [ + "//shared/tree-sitter-extractor", + ], +) diff --git a/unified/extractor/Cargo.toml b/unified/extractor/Cargo.toml new file mode 100644 index 00000000000..fb377a995e7 --- /dev/null +++ b/unified/extractor/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "codeql-extractor-unified" +description = "CodeQL Unified extractor" +version = "0.1.0" +authors = ["GitHub"] +edition = "2024" + +# When updating these dependencies, run `misc/bazel/3rdparty/update_cargo_deps.sh` +[dependencies] +tree-sitter = ">= 0.23.0" +tree-sitter-embedded-template = "0.25.0" +tree-sitter-swift = "0.7.2" +clap = { version = "4.5", features = ["derive"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } +rayon = "1.11.0" +regex = "1.11.3" +encoding = "0.2" +lazy_static = "1.5.0" +serde_json = "1.0.145" + +codeql-extractor = { path = "../../shared/tree-sitter-extractor" } diff --git a/unified/extractor/src/autobuilder.rs b/unified/extractor/src/autobuilder.rs new file mode 100644 index 00000000000..3bcb87aedd8 --- /dev/null +++ b/unified/extractor/src/autobuilder.rs @@ -0,0 +1,20 @@ +use std::env; +use std::path::PathBuf; + +use clap::Args; + +use codeql_extractor::autobuilder; + +#[derive(Args)] +// The autobuilder takes no command-line options, but this may change in the future. +pub struct Options {} + +pub fn run(_: Options) -> std::io::Result<()> { + let database = env::var("CODEQL_EXTRACTOR_UNIFIED_WIP_DATABASE") + .expect("CODEQL_EXTRACTOR_UNIFIED_WIP_DATABASE not set"); + + autobuilder::Autobuilder::new("unified", PathBuf::from(database)) + .include_extensions(&[".swift", ".swiftinterface"]) + .size_limit("10m") + .run() +} diff --git a/unified/extractor/src/extractor.rs b/unified/extractor/src/extractor.rs new file mode 100644 index 00000000000..ae9e538a5ec --- /dev/null +++ b/unified/extractor/src/extractor.rs @@ -0,0 +1,43 @@ +use clap::Args; +use std::path::PathBuf; + +use codeql_extractor::extractor::simple; +use codeql_extractor::trap; + +#[derive(Args)] +pub struct Options { + /// Sets a custom source achive folder + #[arg(long)] + source_archive_dir: PathBuf, + + /// Sets a custom trap folder + #[arg(long)] + output_dir: PathBuf, + + /// A text file containing the paths of the files to extract + #[arg(long)] + file_list: PathBuf, +} + +pub fn run(options: Options) -> std::io::Result<()> { + codeql_extractor::extractor::set_tracing_level("ql"); + + let extractor = simple::Extractor { + prefix: "unified".to_string(), + languages: vec![ + simple::LanguageSpec { + prefix: "swift", + ts_language: tree_sitter_swift::LANGUAGE.into(), + node_types: tree_sitter_swift::NODE_TYPES, + file_globs: vec!["*.swift".into(), "*.swiftinterface".into()], + desugar: None, + }, + ], + trap_dir: options.output_dir, + trap_compression: trap::Compression::from_env("CODEQL_QL_TRAP_COMPRESSION"), + source_archive_dir: options.source_archive_dir, + file_lists: vec![options.file_list], + }; + + extractor.run() +} diff --git a/unified/extractor/src/generator.rs b/unified/extractor/src/generator.rs new file mode 100644 index 00000000000..ee65da7a600 --- /dev/null +++ b/unified/extractor/src/generator.rs @@ -0,0 +1,27 @@ +use clap::Args; +use std::path::PathBuf; + +use codeql_extractor::generator::{generate, language::Language}; + +#[derive(Args)] +pub struct Options { + /// Path of the generated dbscheme file + #[arg(long)] + dbscheme: PathBuf, + + /// Path of the generated QLL file + #[arg(long)] + library: PathBuf, +} + +pub fn run(options: Options) -> std::io::Result<()> { + codeql_extractor::extractor::set_tracing_level("ql"); + + let languages = vec![Language { + name: "Swift".to_owned(), + node_types: tree_sitter_swift::NODE_TYPES, + desugar: None, + }]; + + generate(languages, options.dbscheme, options.library, "run ql/unified/scripts/create-extractor-pack.sh") +} diff --git a/unified/extractor/src/main.rs b/unified/extractor/src/main.rs new file mode 100644 index 00000000000..e6721d4e224 --- /dev/null +++ b/unified/extractor/src/main.rs @@ -0,0 +1,23 @@ +use clap::Parser; + +mod autobuilder; +mod extractor; +mod generator; + +#[derive(Parser)] +#[command(author, version, about)] +enum Cli { + Extract(extractor::Options), + Generate(generator::Options), + Autobuild(autobuilder::Options), +} + +fn main() -> std::io::Result<()> { + let cli = Cli::parse(); + + match cli { + Cli::Extract(options) => extractor::run(options), + Cli::Generate(options) => generator::run(options), + Cli::Autobuild(options) => autobuilder::run(options), + } +} diff --git a/unified/ql/lib/BUILD.bazel b/unified/ql/lib/BUILD.bazel new file mode 100644 index 00000000000..3636225ba53 --- /dev/null +++ b/unified/ql/lib/BUILD.bazel @@ -0,0 +1,13 @@ +load("@rules_pkg//pkg:mappings.bzl", "pkg_files") + +package(default_visibility = ["//unified:__pkg__"]) + +pkg_files( + name = "dbscheme", + srcs = ["unified.dbscheme"], +) + +pkg_files( + name = "dbscheme-stats", + srcs = ["unified.dbscheme.stats"], +) diff --git a/unified/ql/lib/codeql/Locations.qll b/unified/ql/lib/codeql/Locations.qll new file mode 100644 index 00000000000..df52d6822a2 --- /dev/null +++ b/unified/ql/lib/codeql/Locations.qll @@ -0,0 +1,70 @@ +/** Provides classes for working with locations. */ +overlay[local] +module; + +import files.FileSystem + +/** + * A location as given by a file, a start line, a start column, + * an end line, and an end column. + * + * For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +class Location extends @location_default { + /** Gets the file for this location. */ + File getFile() { locations_default(this, result, _, _, _, _) } + + /** Gets the 1-based line number (inclusive) where this location starts. */ + int getStartLine() { locations_default(this, _, result, _, _, _) } + + /** Gets the 1-based column number (inclusive) where this location starts. */ + int getStartColumn() { locations_default(this, _, _, result, _, _) } + + /** Gets the 1-based line number (inclusive) where this location ends. */ + int getEndLine() { locations_default(this, _, _, _, result, _) } + + /** Gets the 1-based column number (inclusive) where this location ends. */ + int getEndColumn() { locations_default(this, _, _, _, _, result) } + + /** Gets the number of lines covered by this location. */ + int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 } + + /** Gets a textual representation of this element. */ + bindingset[this] + pragma[inline_late] + string toString() { + exists(string filepath, int startline, int startcolumn, int endline, int endcolumn | + this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and + result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn + ) + } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + exists(File f | + locations_default(this, f, startline, startcolumn, endline, endcolumn) and + filepath = f.getAbsolutePath() + ) + } + + /** Holds if this location starts strictly before the specified location. */ + pragma[inline] + predicate strictlyBefore(Location other) { + this.getStartLine() < other.getStartLine() + or + this.getStartLine() = other.getStartLine() and this.getStartColumn() < other.getStartColumn() + } +} + +/** An entity representing an empty location. */ +class EmptyLocation extends Location { + EmptyLocation() { empty_location(this) } +} diff --git a/unified/ql/lib/codeql/files/FileSystem.qll b/unified/ql/lib/codeql/files/FileSystem.qll new file mode 100644 index 00000000000..6cc771fad9d --- /dev/null +++ b/unified/ql/lib/codeql/files/FileSystem.qll @@ -0,0 +1,38 @@ +/** Provides classes for working with files and folders. */ +overlay[local] +module; + +private import codeql.Locations +private import codeql.util.FileSystem + +private module Input implements InputSig { + abstract class ContainerBase extends @container { + abstract string getAbsolutePath(); + + ContainerBase getParentContainer() { containerparent(result, this) } + + string toString() { result = this.getAbsolutePath() } + } + + class FolderBase extends ContainerBase, @folder { + override string getAbsolutePath() { folders(this, result) } + } + + class FileBase extends ContainerBase, @file { + override string getAbsolutePath() { files(this, result) } + } + + predicate hasSourceLocationPrefix = sourceLocationPrefix/1; +} + +private module Impl = Make; + +class Container = Impl::Container; + +class Folder = Impl::Folder; + +/** A file. */ +class File extends Container, Impl::File { + /** Holds if this file was extracted from ordinary source code. */ + predicate fromSource() { any() } +} diff --git a/unified/ql/lib/codeql/unified/Ast.qll b/unified/ql/lib/codeql/unified/Ast.qll new file mode 100644 index 00000000000..54c1caceaf4 --- /dev/null +++ b/unified/ql/lib/codeql/unified/Ast.qll @@ -0,0 +1,2842 @@ +/** + * CodeQL library for Swift + * Automatically generated from the tree-sitter grammar; do not edit + */ + +import codeql.Locations as L + +/** Holds if the database is an overlay. */ +overlay[local] +private predicate isOverlay() { databaseMetadata("isOverlay", "true") } + +/** Holds if `loc` is in the `file` and is part of the overlay base database. */ +overlay[local] +private predicate discardableLocation(@file file, @location_default loc) { + not isOverlay() and locations_default(loc, file, _, _, _, _) +} + +/** Holds if `loc` 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 discardLocation(@location_default loc) { + exists(@file file, string path | files(file, path) | + discardableLocation(file, loc) and overlayChangedFiles(path) + ) +} + +overlay[local] +module Swift { + /** The base class for all AST nodes */ + class AstNode extends @swift_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) } + + /** Gets the parent of this element. */ + final AstNode getParent() { swift_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) } + + /** Gets a field or child node of this node. */ + AstNode getAFieldOrChild() { none() } + + /** Gets the name of the primary QL class for this element. */ + string getAPrimaryQlClass() { result = "???" } + + /** Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs. */ + string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") } + } + + /** A token. */ + class Token extends @swift_token, AstNode { + /** Gets the value of this token. */ + final string getValue() { swift_tokeninfo(this, _, result) } + + /** Gets a string representation of this element. */ + final override string toString() { result = this.getValue() } + + /** Gets the name of the primary QL class for this element. */ + 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) | + 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) { + 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) { + exists(@file file, string path | files(file, path) | + discardableAstNode(file, node) and overlayChangedFiles(path) + ) + } + + /** A class representing `_expression` tokens. */ + class UnderscoreExpression extends @swift_token__expression, Token { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "UnderscoreExpression" } + } + + /** A class representing `additive_expression` nodes. */ + class AdditiveExpression extends @swift_additive_expression, 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 AstNode getLhs(int i) { swift_additive_expression_lhs(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 AstNode getRhs(int i) { swift_additive_expression_rhs(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_additive_expression_lhs(this, _, result) or + swift_additive_expression_rhs(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 AstNode 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 AstNode getElement(int i) { swift_array_type_element(this, i, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName() { swift_array_type_def(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_array_type_element(this, _, result) or 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 AstNode getExpr(int i) { swift_as_expression_expr(this, i, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName() { swift_as_expression_def(this, result, _) } + + /** Gets the node corresponding to the field `type`. */ + final AstNode getType(int i) { swift_as_expression_type(this, i, 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_expr(this, _, result) or + swift_as_expression_def(this, result, _) or + swift_as_expression_type(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 AstNode getResult(int i) { swift_assignment_result(this, i, 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_result(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 AstNode getDefaultValue(int i) { + swift_associatedtype_declaration_default_value(this, i, result) + } + + /** Gets the node corresponding to the field `must_inherit`. */ + final AstNode getMustInherit(int i) { + swift_associatedtype_declaration_must_inherit(this, i, result) + } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_associatedtype_declaration_name(this, i, result) } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { swift_associatedtype_declaration_child(this, i, 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_name(this, _, result) or + swift_associatedtype_declaration_child(this, _, result) + } + } + + /** 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 a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_attribute_child(this, _, result) } + } + + /** A class representing `availability_condition` nodes. */ + class AvailabilityCondition extends @swift_availability_condition, AstNode { + /** 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 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 AstNode getExpr(int i) { swift_await_expression_expr(this, i, result) } + + /** Gets the child of this node. */ + final AstNode 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 AstNode getLhs(int i) { swift_bitwise_operation_lhs(this, i, 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 AstNode getRhs(int i) { swift_bitwise_operation_rhs(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_bitwise_operation_lhs(this, _, result) or swift_bitwise_operation_rhs(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 AstNode getValue(int i) { swift_capture_list_item_value(this, i, 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 `name`. */ + final AstNode getName() { swift_check_expression_def(this, result, _) } + + /** 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 AstNode getTarget(int i) { swift_check_expression_target(this, i, result) } + + /** Gets the node corresponding to the field `type`. */ + final AstNode getType(int i) { swift_check_expression_type(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_check_expression_def(this, result, _) or + swift_check_expression_target(this, _, result) or + swift_check_expression_type(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 AstNode getLhs(int i) { swift_comparison_expression_lhs(this, i, 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 AstNode getRhs(int i) { swift_comparison_expression_rhs(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_comparison_expression_lhs(this, _, result) or + swift_comparison_expression_rhs(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 AstNode getLhs(int i) { swift_conjunction_expression_lhs(this, i, 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 AstNode getRhs(int i) { swift_conjunction_expression_rhs(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_conjunction_expression_lhs(this, _, result) or + swift_conjunction_expression_rhs(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 AstNode getResult(int i) { swift_control_transfer_statement_result(this, i, 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 AstNode getKey(int i) { swift_dictionary_literal_key(this, i, result) } + + /** Gets the node corresponding to the field `value`. */ + final AstNode 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 AstNode getKey(int i) { swift_dictionary_type_key(this, i, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_dictionary_type_name(this, i, result) } + + /** Gets the node corresponding to the field `value`. */ + final AstNode getValue(int i) { swift_dictionary_type_value(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_dictionary_type_key(this, _, result) or + swift_dictionary_type_name(this, _, result) or + swift_dictionary_type_value(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 AstNode getChild() { swift_directly_assignable_expression_child(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_directly_assignable_expression_child(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 AstNode getLhs(int i) { swift_disjunction_expression_lhs(this, i, 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 AstNode getRhs(int i) { swift_disjunction_expression_rhs(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_disjunction_expression_lhs(this, _, result) or + swift_disjunction_expression_rhs(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 AstNode 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 node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_enum_type_parameters_name(this, i, result) } + + /** 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_name(this, _, result) or + 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(int i) { + swift_equality_constraint_constrained_type(this, i, result) + } + + /** Gets the node corresponding to the field `must_equal`. */ + final AstNode getMustEqual(int i) { swift_equality_constraint_must_equal(this, i, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName() { 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_constrained_type(this, _, result) or + swift_equality_constraint_must_equal(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 AstNode getLhs(int i) { swift_equality_expression_lhs(this, i, 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 AstNode getRhs(int i) { swift_equality_expression_rhs(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_equality_expression_lhs(this, _, result) or + swift_equality_expression_rhs(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 AstNode 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) } + } + + /** 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 AstNode getCollection(int i) { swift_for_statement_collection(this, i, 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_collection(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 AstNode getDefaultValue(int i) { + swift_function_declaration_default_value(this, i, result) + } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_function_declaration_name(this, i, result) } + + /** Gets the node corresponding to the field `return_type`. */ + final AstNode getReturnType(int i) { swift_function_declaration_return_type(this, i, 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_name(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 `name`. */ + final AstNode getName() { swift_function_type_def(this, result, _) } + + /** Gets the node corresponding to the field `params`. */ + final AstNode getParams() { swift_function_type_def(this, _, result) } + + /** Gets the node corresponding to the field `return_type`. */ + final AstNode getReturnType(int i) { swift_function_type_return_type(this, i, 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_return_type(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) } + } + + /** 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 `bound_identifier`. */ + final SimpleIdentifier getBoundIdentifier(int i) { + swift_guard_statement_bound_identifier(this, i, result) + } + + /** Gets the node corresponding to the field `condition`. */ + final AstNode getCondition(int i) { swift_guard_statement_condition(this, i, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_guard_statement_name(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_bound_identifier(this, _, result) or + swift_guard_statement_condition(this, _, result) or + swift_guard_statement_name(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_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 `bound_identifier`. */ + final SimpleIdentifier getBoundIdentifier(int i) { + swift_if_statement_bound_identifier(this, i, result) + } + + /** Gets the node corresponding to the field `condition`. */ + final AstNode getCondition(int i) { swift_if_statement_condition(this, i, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_if_statement_name(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_bound_identifier(this, _, result) or + swift_if_statement_condition(this, _, result) or + swift_if_statement_name(this, _, result) or + swift_if_statement_child(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 AstNode getLhs(int i) { swift_infix_expression_lhs(this, i, 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 AstNode getRhs(int i) { swift_infix_expression_rhs(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_infix_expression_lhs(this, _, result) or + swift_infix_expression_def(this, result) or + swift_infix_expression_rhs(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(int i) { + swift_inheritance_constraint_constrained_type(this, i, result) + } + + /** Gets the node corresponding to the field `inherits_from`. */ + final AstNode getInheritsFrom(int i) { + swift_inheritance_constraint_inherits_from(this, i, result) + } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName() { 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_constrained_type(this, _, result) or + swift_inheritance_constraint_inherits_from(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 AstNode 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 AstNode getValue(int i) { swift_interpolated_expression_value(this, i, 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 AstNode getChild() { swift_key_path_string_expression_child(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_key_path_string_expression_child(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 `name`. */ + final AstNode getName() { swift_lambda_function_type_name(this, result) } + + /** Gets the node corresponding to the field `return_type`. */ + final AstNode getReturnType(int i) { swift_lambda_function_type_return_type(this, i, 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_name(this, result) or + 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 AstNode getName(int i) { swift_lambda_parameter_name(this, i, result) } + + /** Gets the node corresponding to the field `type`. */ + final AstNode getType(int i) { swift_lambda_parameter_type(this, i, 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) + } + } + + /** 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 AstNode 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(int i) { swift_macro_definition_body(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_macro_definition_body(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 AstNode 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 AstNode getLhs(int i) { swift_multiplicative_expression_lhs(this, i, 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 AstNode getRhs(int i) { swift_multiplicative_expression_rhs(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_multiplicative_expression_lhs(this, _, result) or + swift_multiplicative_expression_rhs(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 `element`. */ + final AstNode getElement() { swift_navigation_expression_element(this, result) } + + /** 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_element(this, result) or + 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 `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 AstNode getIfNil(int i) { swift_nil_coalescing_expression_if_nil(this, i, result) } + + /** Gets the node corresponding to the field `value`. */ + final AstNode getValue(int i) { swift_nil_coalescing_expression_value(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_nil_coalescing_expression_if_nil(this, _, result) or + swift_nil_coalescing_expression_value(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 AstNode 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 AstNode getStart(int i) { swift_open_end_range_expression_start(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_open_end_range_expression_start(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 AstNode getEnd(int i) { swift_open_start_range_expression_end(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_open_start_range_expression_end(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_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 AstNode getName(int i) { swift_parameter_name(this, i, result) } + + /** Gets the node corresponding to the field `type`. */ + final AstNode getType(int i) { swift_parameter_type(this, i, 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_name(this, _, result) or + swift_parameter_type(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 node corresponding to the field `name`. */ + final AstNode getName() { swift_pattern_name(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_name(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 AstNode 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 AstNode getTarget(int i) { swift_postfix_expression_target(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_postfix_expression_def(this, result) or swift_postfix_expression_target(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 AstNode getTarget(int i) { swift_prefix_expression_target(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_prefix_expression_def(this, result) or swift_prefix_expression_target(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 AstNode 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 node corresponding to the field `body`. */ + final ProtocolFunctionDeclaration getBody(int i) { swift_protocol_body_body(this, i, result) } + + /** Gets the `i`th child of this node. */ + final AstNode 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_body(this, _, result) or 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 AstNode 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 `default_value`. */ + final AstNode getDefaultValue(int i) { + swift_protocol_function_declaration_default_value(this, i, result) + } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_protocol_function_declaration_name(this, i, result) } + + /** Gets the node corresponding to the field `return_type`. */ + final AstNode getReturnType(int i) { + swift_protocol_function_declaration_return_type(this, i, 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_default_value(this, _, result) or + swift_protocol_function_declaration_name(this, _, result) or + swift_protocol_function_declaration_return_type(this, _, result) or + swift_protocol_function_declaration_child(this, _, result) + } + } + + /** 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 AstNode getEnd(int i) { swift_range_expression_end(this, i, 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 AstNode getStart(int i) { swift_range_expression_start(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_range_expression_end(this, _, result) or swift_range_expression_start(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 `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 `bound_identifier`. */ + final SimpleIdentifier getBoundIdentifier(int i) { + swift_repeat_while_statement_bound_identifier(this, i, result) + } + + /** Gets the node corresponding to the field `condition`. */ + final AstNode getCondition(int i) { swift_repeat_while_statement_condition(this, i, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_repeat_while_statement_name(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_bound_identifier(this, _, result) or + swift_repeat_while_statement_condition(this, _, result) or + swift_repeat_while_statement_name(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 AstNode getChild() { swift_selector_expression_child(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_selector_expression_child(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 AstNode getDefaultValue(int i) { + swift_subscript_declaration_default_value(this, i, result) + } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName() { swift_subscript_declaration_name(this, result) } + + /** Gets the node corresponding to the field `return_type`. */ + final AstNode getReturnType(int i) { swift_subscript_declaration_return_type(this, i, 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_name(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 AstNode getExpr(int i) { swift_switch_statement_expr(this, i, 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_expr(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 AstNode getCondition(int i) { swift_ternary_expression_condition(this, i, result) } + + /** Gets the node corresponding to the field `if_false`. */ + final AstNode getIfFalse(int i) { swift_ternary_expression_if_false(this, i, result) } + + /** Gets the node corresponding to the field `if_true`. */ + final AstNode getIfTrue(int i) { swift_ternary_expression_if_true(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_ternary_expression_condition(this, _, result) or + swift_ternary_expression_if_false(this, _, result) or + swift_ternary_expression_if_true(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 AstNode 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 AstNode getExpr(int i) { swift_try_expression_expr(this, i, 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_expr(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 AstNode 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 `element`. */ + final AstNode getElement() { swift_tuple_type_item_element(this, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_tuple_type_item_name(this, i, result) } + + /** Gets the node corresponding to the field `type`. */ + final AstNode getType(int i) { swift_tuple_type_item_type(this, i, 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_element(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) + } + } + + /** 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 `name`. */ + final AstNode getName() { swift_type_annotation_def(this, result) } + + /** Gets the node corresponding to the field `type`. */ + final AstNode getType(int i) { swift_type_annotation_type(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { + swift_type_annotation_def(this, result) or swift_type_annotation_type(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 `name`. */ + final AstNode getName(int i) { swift_type_arguments_name(this, i, result) } + + /** Gets the `i`th child of this node. */ + final TypeModifiers 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_name(this, _, result) or 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" } + } + + /** 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 AstNode 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 node corresponding to the field `name`. */ + final AstNode getName() { swift_type_parameter_name(this, result) } + + /** 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_name(this, result) or 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 AstNode 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 AstNode getName(int i) { swift_typealias_declaration_name(this, i, result) } + + /** Gets the node corresponding to the field `value`. */ + final AstNode getValue(int i) { swift_typealias_declaration_value(this, i, 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_name(this, _, result) or + swift_typealias_declaration_value(this, _, result) or + swift_typealias_declaration_child(this, _, result) + } + } + + /** 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 AstNode getValue(int i) { swift_value_argument_value(this, i, 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 AstNode getChild() { swift_value_pack_expansion_child(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_value_pack_expansion_child(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 AstNode getChild() { swift_value_parameter_pack_child(this, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_value_parameter_pack_child(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) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { swift_where_clause_child(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 `bound_identifier`. */ + final SimpleIdentifier getBoundIdentifier(int i) { + swift_while_statement_bound_identifier(this, i, result) + } + + /** Gets the node corresponding to the field `condition`. */ + final AstNode getCondition(int i) { swift_while_statement_condition(this, i, result) } + + /** Gets the node corresponding to the field `name`. */ + final AstNode getName(int i) { swift_while_statement_name(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_bound_identifier(this, _, result) or + swift_while_statement_condition(this, _, result) or + swift_while_statement_name(this, _, result) or + swift_while_statement_child(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 `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) } + } +} diff --git a/unified/ql/lib/qlpack.lock.yml b/unified/ql/lib/qlpack.lock.yml new file mode 100644 index 00000000000..06dd07fc7dc --- /dev/null +++ b/unified/ql/lib/qlpack.lock.yml @@ -0,0 +1,4 @@ +--- +dependencies: {} +compiled: false +lockVersion: 1.0.0 diff --git a/unified/ql/lib/qlpack.yml b/unified/ql/lib/qlpack.yml new file mode 100644 index 00000000000..896bf37ac5e --- /dev/null +++ b/unified/ql/lib/qlpack.yml @@ -0,0 +1,11 @@ +name: codeql/unified-all +version: 0.0.1-dev +groups: unified +dbscheme: unified.dbscheme +extractor: unified +library: true +upgrades: upgrades +dependencies: + codeql/util: ${workspace} +warnOnImplicitThis: true +compileForOverlayEval: true diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme new file mode 100644 index 00000000000..026d4add415 --- /dev/null +++ b/unified/ql/lib/unified.dbscheme @@ -0,0 +1,2741 @@ +// CodeQL database schema for Swift +// Automatically generated from the tree-sitter grammar; do not edit +// To regenerate, run ql/unified/scripts/create-extractor-pack.sh + +/*- 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 +); + +/*- Swift dbscheme -*/ +@swift_additive_expression_lhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_additive_expression, index] +swift_additive_expression_lhs( + int swift_additive_expression: @swift_additive_expression ref, + int index: int ref, + unique int lhs: @swift_additive_expression_lhs_type ref +); + +case @swift_additive_expression.op of + 0 = @swift_additive_expression_plus +| 1 = @swift_additive_expression_minus +; + + +@swift_additive_expression_rhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_additive_expression, index] +swift_additive_expression_rhs( + int swift_additive_expression: @swift_additive_expression ref, + int index: int ref, + unique int rhs: @swift_additive_expression_rhs_type ref +); + +swift_additive_expression_def( + unique int id: @swift_additive_expression, + int op: int ref +); + +@swift_array_literal_element_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_array_literal_element_type ref +); + +swift_array_literal_def( + unique int id: @swift_array_literal +); + +@swift_array_type_element_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_array_type, index] +swift_array_type_element( + int swift_array_type: @swift_array_type ref, + int index: int ref, + unique int element: @swift_array_type_element_type ref +); + +@swift_array_type_name_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_array_type_def( + unique int id: @swift_array_type, + int name: @swift_array_type_name_type ref +); + +@swift_as_expression_expr_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_as_expression, index] +swift_as_expression_expr( + int swift_as_expression: @swift_as_expression ref, + int index: int ref, + unique int expr: @swift_as_expression_expr_type ref +); + +@swift_as_expression_name_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_as_expression_type_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_as_expression, index] +swift_as_expression_type( + int swift_as_expression: @swift_as_expression ref, + int index: int ref, + unique int type__: @swift_as_expression_type_type ref +); + +swift_as_expression_def( + unique int id: @swift_as_expression, + int name: @swift_as_expression_name_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_result_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_assignment, index] +swift_assignment_result( + int swift_assignment: @swift_assignment ref, + int index: int ref, + unique int result: @swift_assignment_result_type ref +); + +swift_assignment_def( + unique int id: @swift_assignment, + int operator: int ref, + int target: @swift_directly_assignable_expression ref +); + +@swift_associatedtype_declaration_default_value_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_associatedtype_declaration, index] +swift_associatedtype_declaration_default_value( + int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, + int index: int ref, + unique int default_value: @swift_associatedtype_declaration_default_value_type ref +); + +@swift_associatedtype_declaration_must_inherit_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_associatedtype_declaration, index] +swift_associatedtype_declaration_must_inherit( + int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, + int index: int ref, + unique int must_inherit: @swift_associatedtype_declaration_must_inherit_type ref +); + +@swift_associatedtype_declaration_name_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_token_type_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_associatedtype_declaration, index] +swift_associatedtype_declaration_name( + int swift_associatedtype_declaration: @swift_associatedtype_declaration ref, + int index: int ref, + unique int name: @swift_associatedtype_declaration_name_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 +); + +@swift_attribute_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_user_type | @swift_value_pack_expansion | @swift_value_parameter_pack + +#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_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_await_expression, index] +swift_await_expression_expr( + int swift_await_expression: @swift_await_expression ref, + int index: int ref, + unique int expr: @swift_await_expression_expr_type ref +); + +@swift_await_expression_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_await_expression_child( + unique int swift_await_expression: @swift_await_expression ref, + unique int child: @swift_await_expression_child_type ref +); + +swift_await_expression_def( + unique int id: @swift_await_expression +); + +@swift_bitwise_operation_lhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_bitwise_operation, index] +swift_bitwise_operation_lhs( + int swift_bitwise_operation: @swift_bitwise_operation ref, + int index: int ref, + unique int lhs: @swift_bitwise_operation_lhs_type 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_rhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_bitwise_operation, index] +swift_bitwise_operation_rhs( + int swift_bitwise_operation: @swift_bitwise_operation ref, + int index: int ref, + unique int rhs: @swift_bitwise_operation_rhs_type ref +); + +swift_bitwise_operation_def( + unique int id: @swift_bitwise_operation, + int op: int ref +); + +@swift_call_expression_child_type = @swift_additive_expression | @swift_array_literal | @swift_as_expression | @swift_assignment | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_call_suffix | @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_capture_list_item, index] +swift_capture_list_item_value( + int swift_capture_list_item: @swift_capture_list_item ref, + int index: int ref, + unique int value: @swift_capture_list_item_value_type 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 +); + +@swift_check_expression_name_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 + +case @swift_check_expression.op of + 0 = @swift_check_expression_is +; + + +@swift_check_expression_target_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_check_expression, index] +swift_check_expression_target( + int swift_check_expression: @swift_check_expression ref, + int index: int ref, + unique int target: @swift_check_expression_target_type ref +); + +@swift_check_expression_type_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_check_expression, index] +swift_check_expression_type( + int swift_check_expression: @swift_check_expression ref, + int index: int ref, + unique int type__: @swift_check_expression_type_type ref +); + +swift_check_expression_def( + unique int id: @swift_check_expression, + int name: @swift_check_expression_name_type ref, + int op: int ref +); + +@swift_class_body_child_type = @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_token_multiline_comment | @swift_typealias_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_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_token_type_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_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 +); + +@swift_comparison_expression_lhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_comparison_expression, index] +swift_comparison_expression_lhs( + int swift_comparison_expression: @swift_comparison_expression ref, + int index: int ref, + unique int lhs: @swift_comparison_expression_lhs_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_rhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_comparison_expression, index] +swift_comparison_expression_rhs( + int swift_comparison_expression: @swift_comparison_expression ref, + int index: int ref, + unique int rhs: @swift_comparison_expression_rhs_type ref +); + +swift_comparison_expression_def( + unique int id: @swift_comparison_expression, + int op: int 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 +); + +@swift_conjunction_expression_lhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_conjunction_expression, index] +swift_conjunction_expression_lhs( + int swift_conjunction_expression: @swift_conjunction_expression ref, + int index: int ref, + unique int lhs: @swift_conjunction_expression_lhs_type ref +); + +case @swift_conjunction_expression.op of + 0 = @swift_conjunction_expression_ampersandampersand +; + + +@swift_conjunction_expression_rhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_conjunction_expression, index] +swift_conjunction_expression_rhs( + int swift_conjunction_expression: @swift_conjunction_expression ref, + int index: int ref, + unique int rhs: @swift_conjunction_expression_rhs_type ref +); + +swift_conjunction_expression_def( + unique int id: @swift_conjunction_expression, + int op: int 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_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_control_transfer_statement, index] +swift_control_transfer_statement_result( + int swift_control_transfer_statement: @swift_control_transfer_statement ref, + int index: int ref, + unique int result: @swift_control_transfer_statement_result_type ref +); + +@swift_control_transfer_statement_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_token_throw_keyword | @swift_try_expression | @swift_tuple_expression | @swift_value_pack_expansion | @swift_value_parameter_pack + +#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 +); + +@swift_dictionary_literal_key_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_dictionary_literal_key_type ref +); + +@swift_dictionary_literal_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_dictionary_literal_value_type ref +); + +swift_dictionary_literal_def( + unique int id: @swift_dictionary_literal +); + +@swift_dictionary_type_key_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_dictionary_type, index] +swift_dictionary_type_key( + int swift_dictionary_type: @swift_dictionary_type ref, + int index: int ref, + unique int key__: @swift_dictionary_type_key_type ref +); + +@swift_dictionary_type_name_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_dictionary_type, index] +swift_dictionary_type_name( + int swift_dictionary_type: @swift_dictionary_type ref, + int index: int ref, + unique int name: @swift_dictionary_type_name_type ref +); + +@swift_dictionary_type_value_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_dictionary_type, index] +swift_dictionary_type_value( + int swift_dictionary_type: @swift_dictionary_type ref, + int index: int ref, + unique int value: @swift_dictionary_type_value_type ref +); + +swift_dictionary_type_def( + unique int id: @swift_dictionary_type +); + +@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_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_directly_assignable_expression_child( + unique int swift_directly_assignable_expression: @swift_directly_assignable_expression ref, + unique int child: @swift_directly_assignable_expression_child_type ref +); + +swift_directly_assignable_expression_def( + unique int id: @swift_directly_assignable_expression +); + +@swift_disjunction_expression_lhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_disjunction_expression, index] +swift_disjunction_expression_lhs( + int swift_disjunction_expression: @swift_disjunction_expression ref, + int index: int ref, + unique int lhs: @swift_disjunction_expression_lhs_type ref +); + +case @swift_disjunction_expression.op of + 0 = @swift_disjunction_expression_pipepipe +; + + +@swift_disjunction_expression_rhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_disjunction_expression, index] +swift_disjunction_expression_rhs( + int swift_disjunction_expression: @swift_disjunction_expression ref, + int index: int ref, + unique int rhs: @swift_disjunction_expression_rhs_type ref +); + +swift_disjunction_expression_def( + unique int id: @swift_disjunction_expression, + int op: int 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_associatedtype_declaration | @swift_class_declaration | @swift_deinit_declaration | @swift_enum_entry | @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_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 +); + +@swift_enum_entry_raw_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_enum_entry_raw_value_type 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_name_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_enum_type_parameters, index] +swift_enum_type_parameters_name( + int swift_enum_type_parameters: @swift_enum_type_parameters ref, + int index: int ref, + unique int name: @swift_enum_type_parameters_name_type ref +); + +@swift_enum_type_parameters_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_token_wildcard_pattern | @swift_try_expression | @swift_tuple_expression | @swift_type_modifiers | @swift_value_pack_expansion | @swift_value_parameter_pack + +#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_array_type | @swift_dictionary_type | @swift_existential_type | @swift_function_type | @swift_identifier | @swift_metatype | @swift_opaque_type | @swift_optional_type | @swift_protocol_composition_type | @swift_reserved_word | @swift_suppressed_constraint | @swift_token_simple_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_equality_constraint, index] +swift_equality_constraint_constrained_type( + int swift_equality_constraint: @swift_equality_constraint ref, + int index: int ref, + unique int constrained_type: @swift_equality_constraint_constrained_type_type ref +); + +@swift_equality_constraint_must_equal_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_equality_constraint, index] +swift_equality_constraint_must_equal( + int swift_equality_constraint: @swift_equality_constraint ref, + int index: int ref, + unique int must_equal: @swift_equality_constraint_must_equal_type ref +); + +@swift_equality_constraint_name_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_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 name: @swift_equality_constraint_name_type ref +); + +@swift_equality_expression_lhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_equality_expression, index] +swift_equality_expression_lhs( + int swift_equality_expression: @swift_equality_expression ref, + int index: int ref, + unique int lhs: @swift_equality_expression_lhs_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_rhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_equality_expression, index] +swift_equality_expression_rhs( + int swift_equality_expression: @swift_equality_expression ref, + int index: int ref, + unique int rhs: @swift_equality_expression_rhs_type ref +); + +swift_equality_expression_def( + unique int id: @swift_equality_expression, + int op: int ref +); + +@swift_existential_type_child_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_existential_type_def( + unique int id: @swift_existential_type, + int child: @swift_existential_type_child_type ref +); + +swift_external_macro_definition_def( + unique int id: @swift_external_macro_definition, + int child: @swift_value_arguments ref +); + +@swift_for_statement_collection_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_for_statement, index] +swift_for_statement_collection( + int swift_for_statement: @swift_for_statement ref, + int index: int ref, + unique int collection: @swift_for_statement_collection_type 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 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 +); + +@swift_function_declaration_default_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_function_declaration_default_value_type ref +); + +@swift_function_declaration_name_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_reserved_word | @swift_suppressed_constraint | @swift_token_bang | @swift_token_custom_operator | @swift_token_simple_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_function_declaration, index] +swift_function_declaration_name( + int swift_function_declaration: @swift_function_declaration ref, + int index: int ref, + unique int name: @swift_function_declaration_name_type ref +); + +@swift_function_declaration_return_type_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_reserved_word | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_function_declaration, index] +swift_function_declaration_return_type( + int swift_function_declaration: @swift_function_declaration ref, + int index: int 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 +); + +@swift_function_type_name_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_function_type_params_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_function_type_return_type_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_function_type, index] +swift_function_type_return_type( + int swift_function_type: @swift_function_type ref, + int index: int ref, + unique int return_type: @swift_function_type_return_type_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 name: @swift_function_type_name_type ref, + int params: @swift_function_type_params_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 +); + +#keyset[swift_guard_statement, index] +swift_guard_statement_bound_identifier( + int swift_guard_statement: @swift_guard_statement ref, + int index: int ref, + unique int bound_identifier: @swift_token_simple_identifier ref +); + +@swift_guard_statement_condition_type = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_availability_condition | @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_dictionary_type | @swift_directive | @swift_disjunction_expression | @swift_equality_expression | @swift_existential_type | @swift_function_type | @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_metatype | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_optional_type | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_protocol_composition_type | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_suppressed_constraint | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_token_wildcard_pattern | @swift_try_expression | @swift_tuple_expression | @swift_tuple_type | @swift_type_annotation | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause + +#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_guard_statement_condition_type ref +); + +@swift_guard_statement_name_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_guard_statement, index] +swift_guard_statement_name( + int swift_guard_statement: @swift_guard_statement ref, + int index: int ref, + unique int name: @swift_guard_statement_name_type 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 +); + +#keyset[swift_if_statement, index] +swift_if_statement_bound_identifier( + int swift_if_statement: @swift_if_statement ref, + int index: int ref, + unique int bound_identifier: @swift_token_simple_identifier ref +); + +@swift_if_statement_condition_type = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_availability_condition | @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_dictionary_type | @swift_directive | @swift_disjunction_expression | @swift_equality_expression | @swift_existential_type | @swift_function_type | @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_metatype | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_optional_type | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_protocol_composition_type | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_suppressed_constraint | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_token_wildcard_pattern | @swift_try_expression | @swift_tuple_expression | @swift_tuple_type | @swift_type_annotation | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause + +#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_statement_condition_type ref +); + +@swift_if_statement_name_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_if_statement, index] +swift_if_statement_name( + int swift_if_statement: @swift_if_statement ref, + int index: int ref, + unique int name: @swift_if_statement_name_type 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_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_lhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_infix_expression, index] +swift_infix_expression_lhs( + int swift_infix_expression: @swift_infix_expression ref, + int index: int ref, + unique int lhs: @swift_infix_expression_lhs_type ref +); + +@swift_infix_expression_rhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_infix_expression, index] +swift_infix_expression_rhs( + int swift_infix_expression: @swift_infix_expression ref, + int index: int ref, + unique int rhs: @swift_infix_expression_rhs_type ref +); + +swift_infix_expression_def( + unique int id: @swift_infix_expression, + int op: @swift_token_custom_operator ref +); + +@swift_inheritance_constraint_constrained_type_type = @swift_array_type | @swift_dictionary_type | @swift_existential_type | @swift_function_type | @swift_identifier | @swift_metatype | @swift_opaque_type | @swift_optional_type | @swift_protocol_composition_type | @swift_reserved_word | @swift_suppressed_constraint | @swift_token_simple_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_inheritance_constraint, index] +swift_inheritance_constraint_constrained_type( + int swift_inheritance_constraint: @swift_inheritance_constraint ref, + int index: int ref, + unique int constrained_type: @swift_inheritance_constraint_constrained_type_type ref +); + +@swift_inheritance_constraint_inherits_from_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_reserved_word | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_inheritance_constraint, index] +swift_inheritance_constraint_inherits_from( + int swift_inheritance_constraint: @swift_inheritance_constraint ref, + int index: int ref, + unique int inherits_from: @swift_inheritance_constraint_inherits_from_type ref +); + +@swift_inheritance_constraint_name_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_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 name: @swift_inheritance_constraint_name_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 +); + +@swift_init_declaration_default_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_init_declaration_default_value_type 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_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_interpolated_expression, index] +swift_interpolated_expression_value( + int swift_interpolated_expression: @swift_interpolated_expression ref, + int index: int ref, + unique int value: @swift_interpolated_expression_value_type 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_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_key_path_string_expression_child( + unique int swift_key_path_string_expression: @swift_key_path_string_expression ref, + unique int child: @swift_key_path_string_expression_child_type ref +); + +swift_key_path_string_expression_def( + unique int id: @swift_key_path_string_expression +); + +@swift_lambda_function_type_name_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_lambda_function_type_name( + unique int swift_lambda_function_type: @swift_lambda_function_type ref, + unique int name: @swift_lambda_function_type_name_type ref +); + +@swift_lambda_function_type_return_type_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_reserved_word | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_lambda_function_type, index] +swift_lambda_function_type_return_type( + int swift_lambda_function_type: @swift_lambda_function_type ref, + int index: int 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_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_token_simple_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_lambda_parameter, index] +swift_lambda_parameter_name( + int swift_lambda_parameter: @swift_lambda_parameter ref, + int index: int ref, + unique int name: @swift_lambda_parameter_name_type ref +); + +@swift_lambda_parameter_type_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_reserved_word | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_lambda_parameter, index] +swift_lambda_parameter_type( + int swift_lambda_parameter: @swift_lambda_parameter ref, + int index: int 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_macro_declaration_default_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_macro_declaration_default_value_type 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_array_type | @swift_attribute | @swift_dictionary_type | @swift_existential_type | @swift_function_type | @swift_metatype | @swift_modifiers | @swift_opaque_type | @swift_optional_type | @swift_parameter | @swift_protocol_composition_type | @swift_suppressed_constraint | @swift_token_simple_identifier | @swift_tuple_type | @swift_type_constraints | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_type_parameters | @swift_user_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_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_external_macro_definition | @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_macro_definition, index] +swift_macro_definition_body( + int swift_macro_definition: @swift_macro_definition ref, + int index: int ref, + unique int body: @swift_macro_definition_body_type ref +); + +swift_macro_definition_def( + unique int id: @swift_macro_definition +); + +@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_child_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_metatype_def( + unique int id: @swift_metatype, + int child: @swift_metatype_child_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 +); + +@swift_multiplicative_expression_lhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_multiplicative_expression, index] +swift_multiplicative_expression_lhs( + int swift_multiplicative_expression: @swift_multiplicative_expression ref, + int index: int ref, + unique int lhs: @swift_multiplicative_expression_lhs_type ref +); + +case @swift_multiplicative_expression.op of + 0 = @swift_multiplicative_expression_percent +| 1 = @swift_multiplicative_expression_star +| 2 = @swift_multiplicative_expression_slash +; + + +@swift_multiplicative_expression_rhs_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_multiplicative_expression, index] +swift_multiplicative_expression_rhs( + int swift_multiplicative_expression: @swift_multiplicative_expression ref, + int index: int ref, + unique int rhs: @swift_multiplicative_expression_rhs_type ref +); + +swift_multiplicative_expression_def( + unique int id: @swift_multiplicative_expression, + int op: int ref +); + +@swift_navigation_expression_element_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type + +swift_navigation_expression_element( + unique int swift_navigation_expression: @swift_navigation_expression ref, + unique int element: @swift_navigation_expression_element_type ref +); + +@swift_navigation_expression_target_type = @swift_additive_expression | @swift_array_literal | @swift_array_type | @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_dictionary_type | @swift_directive | @swift_disjunction_expression | @swift_equality_expression | @swift_existential_type | @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_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_user_type | @swift_value_pack_expansion | @swift_value_parameter_pack + +#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_nil_coalescing_expression_if_nil_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_nil_coalescing_expression, index] +swift_nil_coalescing_expression_if_nil( + int swift_nil_coalescing_expression: @swift_nil_coalescing_expression ref, + int index: int ref, + unique int if_nil: @swift_nil_coalescing_expression_if_nil_type ref +); + +@swift_nil_coalescing_expression_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_nil_coalescing_expression, index] +swift_nil_coalescing_expression_value( + int swift_nil_coalescing_expression: @swift_nil_coalescing_expression ref, + int index: int ref, + unique int value: @swift_nil_coalescing_expression_value_type ref +); + +swift_nil_coalescing_expression_def( + unique int id: @swift_nil_coalescing_expression +); + +@swift_opaque_type_child_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_opaque_type_def( + unique int id: @swift_opaque_type, + int child: @swift_opaque_type_child_type ref +); + +@swift_open_end_range_expression_start_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_open_end_range_expression, index] +swift_open_end_range_expression_start( + int swift_open_end_range_expression: @swift_open_end_range_expression ref, + int index: int ref, + unique int start: @swift_open_end_range_expression_start_type ref +); + +swift_open_end_range_expression_def( + unique int id: @swift_open_end_range_expression +); + +@swift_open_start_range_expression_end_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_open_start_range_expression, index] +swift_open_start_range_expression_end( + int swift_open_start_range_expression: @swift_open_start_range_expression ref, + int index: int ref, + unique int end: @swift_open_start_range_expression_end_type ref +); + +swift_open_start_range_expression_def( + unique int id: @swift_open_start_range_expression +); + +@swift_operator_declaration_child_type = @swift_deprecated_operator_declaration_body | @swift_token_bang | @swift_token_custom_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_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_name_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_token_simple_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_parameter, index] +swift_parameter_name( + int swift_parameter: @swift_parameter ref, + int index: int ref, + unique int name: @swift_parameter_name_type ref +); + +@swift_parameter_type_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_reserved_word | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_parameter, index] +swift_parameter_type( + int swift_parameter: @swift_parameter ref, + int index: int ref, + unique int type__: @swift_parameter_type_type ref +); + +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 +); + +#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_name_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_pattern_name( + unique int swift_pattern: @swift_pattern ref, + unique int name: @swift_pattern_name_type ref +); + +@swift_pattern_child_type = @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_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_token_wildcard_pattern | @swift_try_expression | @swift_tuple_expression | @swift_type_modifiers | @swift_user_type | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack + +#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 +); + +@swift_playground_literal_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_playground_literal_child_type 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_target_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_postfix_expression, index] +swift_postfix_expression_target( + int swift_postfix_expression: @swift_postfix_expression ref, + int index: int ref, + unique int target: @swift_postfix_expression_target_type ref +); + +swift_postfix_expression_def( + unique int id: @swift_postfix_expression, + int operation: @swift_postfix_expression_operation_type 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_target_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token__expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_prefix_expression, index] +swift_prefix_expression_target( + int swift_prefix_expression: @swift_prefix_expression ref, + int index: int ref, + unique int target: @swift_prefix_expression_target_type ref +); + +swift_prefix_expression_def( + unique int id: @swift_prefix_expression, + int operation: @swift_prefix_expression_operation_type 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 +); + +@swift_property_declaration_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_property_declaration_value_type 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_body( + int swift_protocol_body: @swift_protocol_body ref, + int index: int ref, + unique int body: @swift_protocol_function_declaration ref +); + +@swift_protocol_body_child_type = @swift_associatedtype_declaration | @swift_deinit_declaration | @swift_init_declaration | @swift_protocol_function_declaration | @swift_protocol_property_declaration | @swift_subscript_declaration | @swift_typealias_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_body_child_type ref +); + +swift_protocol_body_def( + unique int id: @swift_protocol_body +); + +@swift_protocol_composition_type_child_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_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_protocol_composition_type_child_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_default_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_protocol_function_declaration_default_value_type ref +); + +@swift_protocol_function_declaration_name_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_reserved_word | @swift_suppressed_constraint | @swift_token_bang | @swift_token_custom_operator | @swift_token_simple_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_protocol_function_declaration, index] +swift_protocol_function_declaration_name( + int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, + int index: int ref, + unique int name: @swift_protocol_function_declaration_name_type ref +); + +@swift_protocol_function_declaration_return_type_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_reserved_word | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_protocol_function_declaration, index] +swift_protocol_function_declaration_return_type( + int swift_protocol_function_declaration: @swift_protocol_function_declaration ref, + int index: int 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_statements | @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 +); + +@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 +); + +@swift_range_expression_end_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_range_expression, index] +swift_range_expression_end( + int swift_range_expression: @swift_range_expression ref, + int index: int ref, + unique int end: @swift_range_expression_end_type ref +); + +case @swift_range_expression.op of + 0 = @swift_range_expression_dotdotdot +| 1 = @swift_range_expression_dotdotlangle +; + + +@swift_range_expression_start_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_range_expression, index] +swift_range_expression_start( + int swift_range_expression: @swift_range_expression ref, + int index: int ref, + unique int start: @swift_range_expression_start_type ref +); + +swift_range_expression_def( + unique int id: @swift_range_expression, + int op: int 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 +); + +#keyset[swift_repeat_while_statement, index] +swift_repeat_while_statement_bound_identifier( + int swift_repeat_while_statement: @swift_repeat_while_statement ref, + int index: int ref, + unique int bound_identifier: @swift_token_simple_identifier ref +); + +@swift_repeat_while_statement_condition_type = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_availability_condition | @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_dictionary_type | @swift_directive | @swift_disjunction_expression | @swift_equality_expression | @swift_existential_type | @swift_function_type | @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_metatype | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_optional_type | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_protocol_composition_type | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_suppressed_constraint | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_token_wildcard_pattern | @swift_try_expression | @swift_tuple_expression | @swift_tuple_type | @swift_type_annotation | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @swift_where_clause + +#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_repeat_while_statement_condition_type ref +); + +@swift_repeat_while_statement_name_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_repeat_while_statement, index] +swift_repeat_while_statement_name( + int swift_repeat_while_statement: @swift_repeat_while_statement ref, + int index: int ref, + unique int name: @swift_repeat_while_statement_name_type 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_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_selector_expression_child( + unique int swift_selector_expression: @swift_selector_expression ref, + unique int child: @swift_selector_expression_child_type ref +); + +swift_selector_expression_def( + unique int id: @swift_selector_expression +); + +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_additive_expression | @swift_array_literal | @swift_as_expression | @swift_assignment | @swift_associatedtype_declaration | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_check_expression | @swift_class_declaration | @swift_comparison_expression | @swift_conjunction_expression | @swift_constructor_expression | @swift_dictionary_literal | @swift_directive | @swift_disjunction_expression | @swift_do_statement | @swift_equality_expression | @swift_for_statement | @swift_function_declaration | @swift_guard_statement | @swift_if_statement | @swift_import_declaration | @swift_infix_expression | @swift_init_declaration | @swift_key_path_expression | @swift_key_path_string_expression | @swift_lambda_literal | @swift_line_string_literal | @swift_macro_declaration | @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_operator_declaration | @swift_playground_literal | @swift_postfix_expression | @swift_precedence_group_declaration | @swift_prefix_expression | @swift_property_declaration | @swift_protocol_declaration | @swift_range_expression | @swift_raw_string_literal | @swift_repeat_while_statement | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_shebang_line | @swift_token_simple_identifier | @swift_token_special_literal | @swift_token_statement_label | @swift_token_super_expression | @swift_token_throw_keyword | @swift_try_expression | @swift_tuple_expression | @swift_typealias_declaration | @swift_value_pack_expansion | @swift_value_parameter_pack | @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_additive_expression | @swift_array_literal | @swift_as_expression | @swift_assignment | @swift_await_expression | @swift_bitwise_operation | @swift_call_expression | @swift_check_expression | @swift_class_declaration | @swift_comparison_expression | @swift_conjunction_expression | @swift_constructor_expression | @swift_control_transfer_statement | @swift_dictionary_literal | @swift_directive | @swift_disjunction_expression | @swift_do_statement | @swift_equality_expression | @swift_for_statement | @swift_function_declaration | @swift_guard_statement | @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_property_declaration | @swift_range_expression | @swift_raw_string_literal | @swift_repeat_while_statement | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_statement_label | @swift_token_super_expression | @swift_try_expression | @swift_tuple_expression | @swift_typealias_declaration | @swift_value_pack_expansion | @swift_value_parameter_pack | @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 +); + +@swift_subscript_declaration_default_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_subscript_declaration_default_value_type ref +); + +@swift_subscript_declaration_name_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_subscript_declaration_name( + unique int swift_subscript_declaration: @swift_subscript_declaration ref, + unique int name: @swift_subscript_declaration_name_type ref +); + +@swift_subscript_declaration_return_type_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_reserved_word | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_subscript_declaration, index] +swift_subscript_declaration_return_type( + int swift_subscript_declaration: @swift_subscript_declaration ref, + int index: int 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_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_modifiers | @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_statements | @swift_switch_pattern | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @swift_token_default_keyword | @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_token_where_keyword | @swift_try_expression | @swift_tuple_expression | @swift_value_pack_expansion | @swift_value_parameter_pack + +#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 +); + +@swift_switch_statement_expr_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_switch_statement, index] +swift_switch_statement_expr( + int swift_switch_statement: @swift_switch_statement ref, + int index: int ref, + unique int expr: @swift_switch_statement_expr_type 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 +); + +@swift_ternary_expression_condition_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_ternary_expression, index] +swift_ternary_expression_condition( + int swift_ternary_expression: @swift_ternary_expression ref, + int index: int ref, + unique int condition: @swift_ternary_expression_condition_type ref +); + +@swift_ternary_expression_if_false_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_ternary_expression, index] +swift_ternary_expression_if_false( + int swift_ternary_expression: @swift_ternary_expression ref, + int index: int ref, + unique int if_false: @swift_ternary_expression_if_false_type ref +); + +@swift_ternary_expression_if_true_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_ternary_expression, index] +swift_ternary_expression_if_true( + int swift_ternary_expression: @swift_ternary_expression ref, + int index: int ref, + unique int if_true: @swift_ternary_expression_if_true_type ref +); + +swift_ternary_expression_def( + unique int id: @swift_ternary_expression +); + +@swift_throws_clause_type_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_throws_clause_def( + unique int id: @swift_throws_clause, + int type__: @swift_throws_clause_type_type ref +); + +@swift_try_expression_expr_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_try_expression, index] +swift_try_expression_expr( + int swift_try_expression: @swift_try_expression ref, + int index: int ref, + unique int expr: @swift_try_expression_expr_type ref +); + +swift_try_expression_def( + unique int id: @swift_try_expression, + 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 +); + +@swift_tuple_expression_value_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#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_tuple_expression_value_type 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_element_type = @swift_dictionary_type | @swift_existential_type | @swift_opaque_type + +swift_tuple_type_item_element( + unique int swift_tuple_type_item: @swift_tuple_type_item ref, + unique int element: @swift_tuple_type_item_element_type ref +); + +@swift_tuple_type_item_name_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_token_simple_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_tuple_type_item, index] +swift_tuple_type_item_name( + int swift_tuple_type_item: @swift_tuple_type_item ref, + int index: int ref, + unique int name: @swift_tuple_type_item_name_type ref +); + +@swift_tuple_type_item_type_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_tuple_type_item, index] +swift_tuple_type_item_type( + int swift_tuple_type_item: @swift_tuple_type_item ref, + int index: int ref, + unique int type__: @swift_tuple_type_item_type_type ref +); + +@swift_tuple_type_item_child_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_annotation_name_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_type_annotation_type_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_reserved_word | @swift_suppressed_constraint | @swift_tuple_type | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_type_annotation, index] +swift_type_annotation_type( + int swift_type_annotation: @swift_type_annotation ref, + int index: int ref, + unique int type__: @swift_type_annotation_type_type ref +); + +swift_type_annotation_def( + unique int id: @swift_type_annotation, + int name: @swift_type_annotation_name_type ref +); + +@swift_type_arguments_name_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_type_arguments, index] +swift_type_arguments_name( + int swift_type_arguments: @swift_type_arguments ref, + int index: int ref, + unique int name: @swift_type_arguments_name_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_modifiers 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 +); + +#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_child_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_type_pack_expansion_def( + unique int id: @swift_type_pack_expansion, + int child: @swift_type_pack_expansion_child_type ref +); + +@swift_type_parameter_name_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_type_parameter_name( + unique int swift_type_parameter: @swift_type_parameter ref, + unique int name: @swift_type_parameter_name_type ref +); + +@swift_type_parameter_child_type = @swift_token_type_identifier | @swift_type_modifiers | @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_child_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_type_parameter_pack_def( + unique int id: @swift_type_parameter_pack, + int child: @swift_type_parameter_pack_child_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_name_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_token_type_identifier | @swift_tuple_type | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_typealias_declaration, index] +swift_typealias_declaration_name( + int swift_typealias_declaration: @swift_typealias_declaration ref, + int index: int ref, + unique int name: @swift_typealias_declaration_name_type ref +); + +@swift_typealias_declaration_value_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_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type + +#keyset[swift_typealias_declaration, index] +swift_typealias_declaration_value( + int swift_typealias_declaration: @swift_typealias_declaration ref, + int index: int ref, + unique int value: @swift_typealias_declaration_value_type ref +); + +@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 +); + +@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_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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 + +#keyset[swift_value_argument, index] +swift_value_argument_value( + int swift_value_argument: @swift_value_argument ref, + int index: int ref, + unique int value: @swift_value_argument_value_type 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_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_value_pack_expansion_child( + unique int swift_value_pack_expansion: @swift_value_pack_expansion ref, + unique int child: @swift_value_pack_expansion_child_type ref +); + +swift_value_pack_expansion_def( + unique int id: @swift_value_pack_expansion +); + +@swift_value_parameter_pack_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_value_parameter_pack_child( + unique int swift_value_parameter_pack: @swift_value_parameter_pack ref, + unique int child: @swift_value_parameter_pack_child_type ref +); + +swift_value_parameter_pack_def( + unique int id: @swift_value_parameter_pack +); + +@swift_where_clause_child_type = @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_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_range_expression | @swift_raw_string_literal | @swift_selector_expression | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_token_where_keyword | @swift_try_expression | @swift_tuple_expression | @swift_value_pack_expansion | @swift_value_parameter_pack + +#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_bound_identifier( + int swift_while_statement: @swift_while_statement ref, + int index: int ref, + unique int bound_identifier: @swift_token_simple_identifier ref +); + +@swift_while_statement_condition_type = @swift_additive_expression | @swift_array_literal | @swift_array_type | @swift_as_expression | @swift_assignment | @swift_availability_condition | @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_dictionary_type | @swift_directive | @swift_disjunction_expression | @swift_equality_expression | @swift_existential_type | @swift_function_type | @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_metatype | @swift_multi_line_string_literal | @swift_multiplicative_expression | @swift_navigation_expression | @swift_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_optional_type | @swift_pattern | @swift_playground_literal | @swift_postfix_expression | @swift_prefix_expression | @swift_protocol_composition_type | @swift_range_expression | @swift_raw_string_literal | @swift_reserved_word | @swift_selector_expression | @swift_suppressed_constraint | @swift_switch_statement | @swift_ternary_expression | @swift_token_bang | @swift_token_bin_literal | @swift_token_boolean_literal | @swift_token_custom_operator | @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_token_wildcard_pattern | @swift_try_expression | @swift_tuple_expression | @swift_tuple_type | @swift_type_annotation | @swift_type_modifiers | @swift_type_pack_expansion | @swift_type_parameter_pack | @swift_user_type | @swift_value_binding_pattern | @swift_value_pack_expansion | @swift_value_parameter_pack | @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_while_statement_condition_type ref +); + +@swift_while_statement_name_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_while_statement, index] +swift_while_statement_name( + int swift_while_statement: @swift_while_statement ref, + int index: int ref, + unique int name: @swift_while_statement_name_type 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 +); + +swift_willset_didset_block_def( + unique int id: @swift_willset_didset_block +); + +swift_tokeninfo( + unique int id: @swift_token, + int kind: int ref, + string value: string ref +); + +case @swift_token.kind of + 0 = @swift_reserved_word +| 1 = @swift_token__expression +| 2 = @swift_token_as_operator +| 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 +; + + +@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_statement | @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_nil_coalescing_expression | @swift_opaque_type | @swift_open_end_range_expression | @swift_open_start_range_expression | @swift_operator_declaration | @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_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_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_location( + unique int node: @swift_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, + int parent_index: int ref +); + diff --git a/unified/ql/lib/unified.dbscheme.stats b/unified/ql/lib/unified.dbscheme.stats new file mode 100644 index 00000000000..82714bfe1d0 --- /dev/null +++ b/unified/ql/lib/unified.dbscheme.stats @@ -0,0 +1,4 @@ + + + + diff --git a/unified/ql/src/qlpack.lock.yml b/unified/ql/src/qlpack.lock.yml new file mode 100644 index 00000000000..06dd07fc7dc --- /dev/null +++ b/unified/ql/src/qlpack.lock.yml @@ -0,0 +1,4 @@ +--- +dependencies: {} +compiled: false +lockVersion: 1.0.0 diff --git a/unified/ql/src/qlpack.yml b/unified/ql/src/qlpack.yml new file mode 100644 index 00000000000..2de97863dda --- /dev/null +++ b/unified/ql/src/qlpack.yml @@ -0,0 +1,11 @@ +name: codeql/unified-queries +version: 0.0.1-dev +groups: + - unified + - queries +suites: codeql-suites +dependencies: + codeql/unified-all: ${workspace} + codeql/suite-helpers: ${workspace} + codeql/util: ${workspace} +warnOnImplicitThis: true diff --git a/unified/ql/test/library-tests/BasicTest/test.expected b/unified/ql/test/library-tests/BasicTest/test.expected new file mode 100644 index 00000000000..c24fee85b68 --- /dev/null +++ b/unified/ql/test/library-tests/BasicTest/test.expected @@ -0,0 +1,100 @@ +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:27 | count | count | +| test.swift:76:21:76:21 | i | i | +| test.swift:76:31:76:31 | i | i | +| 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 | diff --git a/unified/ql/test/library-tests/BasicTest/test.ql b/unified/ql/test/library-tests/BasicTest/test.ql new file mode 100644 index 00000000000..a294e876881 --- /dev/null +++ b/unified/ql/test/library-tests/BasicTest/test.ql @@ -0,0 +1,5 @@ +import codeql.unified.Ast + +query predicate identifier(Swift::SimpleIdentifier node, string name) { name = node.getValue() } + +query predicate func(Swift::FunctionDeclaration node) { any() } diff --git a/unified/ql/test/library-tests/BasicTest/test.swift b/unified/ql/test/library-tests/BasicTest/test.swift new file mode 100644 index 00000000000..158ef26f598 --- /dev/null +++ b/unified/ql/test/library-tests/BasicTest/test.swift @@ -0,0 +1,88 @@ +import Foundation + +// Generic struct with type constraint +struct Container { + var items: [T] = [] + + mutating func add(_ item: T) { + items.append(item) + } + + func contains(_ item: T) -> Bool { + return items.contains(item) + } +} + +// Protocol with associated type +protocol DataSource { + associatedtype Element + var count: Int { get } + func item(at index: Int) -> Element? +} + +// Generic function with where clause +func merge(_ first: T, _ second: T) -> [T.Element] where T.Element: Equatable { + var result = Array(first) + for item in second { + if !result.contains(item) { + result.append(item) + } + } + return result +} + +// Class with inheritance and computed properties +class DataManager: DataSource { + typealias Element = T + private var data: [T] = [] + + var count: Int { + return data.count + } + + var isEmpty: Bool { + data.isEmpty + } + + func item(at index: Int) -> T? { + guard index >= 0 && index < data.count else { return nil } + return data[index] + } + + func add(_ item: T) { + data.append(item) + } +} + +// Enum with associated values +enum Result { + case success(Success) + case failure(Failure) + + func map(_ transform: (Success) -> U) -> Result { + switch self { + case .success(let value): + return .success(transform(value)) + case .failure(let error): + return .failure(error) + } + } +} + +// Extension with generic constraints +extension Array where Element: Comparable { + func isSorted() -> Bool { + for i in 0..<(count - 1) { + if self[i] > self[i + 1] { + return false + } + } + return true + } +} + +// Higher-order function +func combine(_ values: [T], transform: (T, T) -> T) -> T? { + guard !values.isEmpty else { return nil } + return values.dropFirst().reduce(values[0], transform) +} diff --git a/unified/ql/test/qlpack.lock.yml b/unified/ql/test/qlpack.lock.yml new file mode 100644 index 00000000000..06dd07fc7dc --- /dev/null +++ b/unified/ql/test/qlpack.lock.yml @@ -0,0 +1,4 @@ +--- +dependencies: {} +compiled: false +lockVersion: 1.0.0 diff --git a/unified/ql/test/qlpack.yml b/unified/ql/test/qlpack.yml new file mode 100644 index 00000000000..8c567d531c9 --- /dev/null +++ b/unified/ql/test/qlpack.yml @@ -0,0 +1,8 @@ +name: codeql/unified-tests +groups: [unified, test] +dependencies: + codeql/unified-queries: ${workspace} + codeql/unified-all: ${workspace} +extractor: unified +tests: . +warnOnImplicitThis: true diff --git a/unified/scripts/create-extractor-pack.sh b/unified/scripts/create-extractor-pack.sh new file mode 100755 index 00000000000..7a41092e4a7 --- /dev/null +++ b/unified/scripts/create-extractor-pack.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -eux +if [[ "$OSTYPE" == "linux-gnu"* ]]; then + platform="linux64" +elif [[ "$OSTYPE" == "darwin"* ]]; then + platform="osx64" +else + echo "Unknown OS" + exit 1 +fi +cd "$(dirname "$0")/.." + +(cd extractor && cargo build --release) + +# we are in a cargo workspace rooted at the git checkout +BIN_DIR=../target/release +"$BIN_DIR/codeql-extractor-unified" generate --dbscheme ql/lib/unified.dbscheme --library ql/lib/codeql/unified/Ast.qll + +codeql query format -i ql/lib/codeql/unified/Ast.qll + +rm -rf extractor-pack +mkdir -p extractor-pack +cp -r codeql-extractor.yml tools ql/lib/unified.dbscheme ql/lib/unified.dbscheme.stats extractor-pack/ +mkdir -p extractor-pack/tools/${platform} +cp "$BIN_DIR/codeql-extractor-unified" extractor-pack/tools/${platform}/extractor diff --git a/unified/tools/BUILD.bazel b/unified/tools/BUILD.bazel new file mode 100644 index 00000000000..a4b4baed225 --- /dev/null +++ b/unified/tools/BUILD.bazel @@ -0,0 +1,11 @@ +load("//misc/bazel:pkg.bzl", "codeql_pkg_files") + +codeql_pkg_files( + name = "tools", + excludes = [ + "BUILD.bazel", + ], + exes = glob(["**/*"]), + prefix = "tools", + visibility = ["//unified:__pkg__"], +) diff --git a/unified/tools/autobuild.cmd b/unified/tools/autobuild.cmd new file mode 100644 index 00000000000..05b59eca119 --- /dev/null +++ b/unified/tools/autobuild.cmd @@ -0,0 +1,5 @@ +@echo off + +type NUL && "%CODEQL_EXTRACTOR_UNIFIED_ROOT%\tools\%CODEQL_PLATFORM%\extractor" autobuild + +exit /b %ERRORLEVEL% diff --git a/unified/tools/autobuild.sh b/unified/tools/autobuild.sh new file mode 100755 index 00000000000..2b35f39e917 --- /dev/null +++ b/unified/tools/autobuild.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +exec "${CODEQL_EXTRACTOR_UNIFIED_ROOT}/tools/${CODEQL_PLATFORM}/extractor" autobuild diff --git a/unified/tools/index-files.cmd b/unified/tools/index-files.cmd new file mode 100644 index 00000000000..3b9fca08ea0 --- /dev/null +++ b/unified/tools/index-files.cmd @@ -0,0 +1,9 @@ +@echo off + +type NUL && "%CODEQL_EXTRACTOR_UNIFIED_ROOT%\tools\win64\extractor.exe" ^ + extract ^ + --file-list "%1" ^ + --source-archive-dir "%CODEQL_EXTRACTOR_UNIFIED_SOURCE_ARCHIVE_DIR%" ^ + --output-dir "%CODEQL_EXTRACTOR_UNIFIED_TRAP_DIR%" + +exit /b %ERRORLEVEL% diff --git a/unified/tools/index-files.sh b/unified/tools/index-files.sh new file mode 100755 index 00000000000..ddf98907e83 --- /dev/null +++ b/unified/tools/index-files.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -eu + +exec "${CODEQL_EXTRACTOR_UNIFIED_ROOT}/tools/${CODEQL_PLATFORM}/extractor" \ + extract \ + --file-list "$1" \ + --source-archive-dir "$CODEQL_EXTRACTOR_UNIFIED_SOURCE_ARCHIVE_DIR" \ + --output-dir "$CODEQL_EXTRACTOR_UNIFIED_TRAP_DIR" diff --git a/unified/tools/qltest.cmd b/unified/tools/qltest.cmd new file mode 100644 index 00000000000..3db89dcc1b9 --- /dev/null +++ b/unified/tools/qltest.cmd @@ -0,0 +1,14 @@ +@echo off + +type NUL && "%CODEQL_DIST%\codeql.exe" database index-files ^ + --prune=**/*.testproj ^ + --include-extension=.swift ^ + --include-extension=.swiftinterface ^ + --size-limit=5m ^ + --language=unified ^ + --working-dir=. ^ + "%CODEQL_EXTRACTOR_UNIFIED_WIP_DATABASE%" + +IF %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% + +exit /b %ERRORLEVEL% diff --git a/unified/tools/qltest.sh b/unified/tools/qltest.sh new file mode 100755 index 00000000000..7dcbb9e81f4 --- /dev/null +++ b/unified/tools/qltest.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +set -eu + +"${CODEQL_DIST}/codeql" database index-files \ + --prune="**/*.testproj" \ + --include-extension=.swift \ + --include-extension=.swiftinterface \ + --size-limit=5m \ + --language=unified \ + --working-dir=.\ + "$CODEQL_EXTRACTOR_UNIFIED_WIP_DATABASE" From 4e12a8c8d28ee22c060f17f2f9ed022677508694 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 6 May 2026 16:23:46 +0200 Subject: [PATCH 36/43] Add basic YEAST dependency and rule --- Cargo.lock | 1 + unified/extractor/BUILD.bazel | 1 + unified/extractor/Cargo.toml | 1 + unified/extractor/src/extractor.rs | 15 ++++++++++++++- .../ql/test/library-tests/BasicTest/test.expected | 5 +++-- unified/ql/test/library-tests/BasicTest/test.ql | 4 ++++ 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 895349ca6e3..856e6fb42e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -454,6 +454,7 @@ dependencies = [ "tree-sitter", "tree-sitter-embedded-template", "tree-sitter-swift", + "yeast", ] [[package]] diff --git a/unified/extractor/BUILD.bazel b/unified/extractor/BUILD.bazel index 8c22b4775f2..c5860edc51a 100644 --- a/unified/extractor/BUILD.bazel +++ b/unified/extractor/BUILD.bazel @@ -15,5 +15,6 @@ codeql_rust_binary( normal = True, ) + [ "//shared/tree-sitter-extractor", + "//shared/yeast", ], ) diff --git a/unified/extractor/Cargo.toml b/unified/extractor/Cargo.toml index fb377a995e7..3877ec2e106 100644 --- a/unified/extractor/Cargo.toml +++ b/unified/extractor/Cargo.toml @@ -20,3 +20,4 @@ lazy_static = "1.5.0" serde_json = "1.0.145" codeql-extractor = { path = "../../shared/tree-sitter-extractor" } +yeast = { path = "../../shared/yeast" } diff --git a/unified/extractor/src/extractor.rs b/unified/extractor/src/extractor.rs index ae9e538a5ec..5a250257c84 100644 --- a/unified/extractor/src/extractor.rs +++ b/unified/extractor/src/extractor.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; use codeql_extractor::extractor::simple; use codeql_extractor::trap; +use yeast::{rule, DesugaringConfig}; #[derive(Args)] pub struct Options { @@ -19,9 +20,21 @@ pub struct Options { file_list: PathBuf, } +fn swift_desugaring_rules() -> Vec { + vec![ + rule!( + (additive_expression) + => + (simple_identifier "blah") + ), + ] +} + pub fn run(options: Options) -> std::io::Result<()> { codeql_extractor::extractor::set_tracing_level("ql"); + let swift_desugar = DesugaringConfig::new(swift_desugaring_rules()); + let extractor = simple::Extractor { prefix: "unified".to_string(), languages: vec![ @@ -30,7 +43,7 @@ pub fn run(options: Options) -> std::io::Result<()> { ts_language: tree_sitter_swift::LANGUAGE.into(), node_types: tree_sitter_swift::NODE_TYPES, file_globs: vec!["*.swift".into(), "*.swiftinterface".into()], - desugar: None, + desugar: Some(swift_desugar), }, ], trap_dir: options.output_dir, diff --git a/unified/ql/test/library-tests/BasicTest/test.expected b/unified/ql/test/library-tests/BasicTest/test.expected index c24fee85b68..62b8146bf04 100644 --- a/unified/ql/test/library-tests/BasicTest/test.expected +++ b/unified/ql/test/library-tests/BasicTest/test.expected @@ -75,9 +75,9 @@ identifier | 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:27 | count | count | +| test.swift:75:23:75:31 | blah | blah | | test.swift:76:21:76:21 | i | i | -| test.swift:76:31:76:31 | 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 | @@ -98,3 +98,4 @@ func | test.swift:62:5:69:5 | FunctionDeclaration | | test.swift:74:5:81:5 | FunctionDeclaration | | test.swift:85:1:88:1 | FunctionDeclaration | +add diff --git a/unified/ql/test/library-tests/BasicTest/test.ql b/unified/ql/test/library-tests/BasicTest/test.ql index a294e876881..3a5ee2f1c15 100644 --- a/unified/ql/test/library-tests/BasicTest/test.ql +++ b/unified/ql/test/library-tests/BasicTest/test.ql @@ -3,3 +3,7 @@ import codeql.unified.Ast query predicate identifier(Swift::SimpleIdentifier node, string name) { name = 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) +} From cd457a7d6bced5a117b9ac73bdb16a1c61c66af1 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 7 May 2026 09:47:27 +0200 Subject: [PATCH 37/43] Move Swift language into its own module --- unified/extractor/src/extractor.rs | 24 ++++--------------- .../extractor/src/languages/swift/swift.rs | 23 ++++++++++++++++++ 2 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 unified/extractor/src/languages/swift/swift.rs diff --git a/unified/extractor/src/extractor.rs b/unified/extractor/src/extractor.rs index 5a250257c84..137b2f3c0e4 100644 --- a/unified/extractor/src/extractor.rs +++ b/unified/extractor/src/extractor.rs @@ -3,7 +3,9 @@ use std::path::PathBuf; use codeql_extractor::extractor::simple; use codeql_extractor::trap; -use yeast::{rule, DesugaringConfig}; + +#[path = "languages/swift/swift.rs"] +mod swift; #[derive(Args)] pub struct Options { @@ -20,31 +22,13 @@ pub struct Options { file_list: PathBuf, } -fn swift_desugaring_rules() -> Vec { - vec![ - rule!( - (additive_expression) - => - (simple_identifier "blah") - ), - ] -} - pub fn run(options: Options) -> std::io::Result<()> { codeql_extractor::extractor::set_tracing_level("ql"); - let swift_desugar = DesugaringConfig::new(swift_desugaring_rules()); - let extractor = simple::Extractor { prefix: "unified".to_string(), languages: vec![ - simple::LanguageSpec { - prefix: "swift", - ts_language: tree_sitter_swift::LANGUAGE.into(), - node_types: tree_sitter_swift::NODE_TYPES, - file_globs: vec!["*.swift".into(), "*.swiftinterface".into()], - desugar: Some(swift_desugar), - }, + swift::language_spec(), ], trap_dir: options.output_dir, trap_compression: trap::Compression::from_env("CODEQL_QL_TRAP_COMPRESSION"), diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs new file mode 100644 index 00000000000..5b21473874c --- /dev/null +++ b/unified/extractor/src/languages/swift/swift.rs @@ -0,0 +1,23 @@ +use codeql_extractor::extractor::simple; +use yeast::{rule, DesugaringConfig}; + +fn desugaring_rules() -> Vec { + vec![ + rule!( + (additive_expression) + => + (simple_identifier "blah") + ), + ] +} + +pub fn language_spec() -> simple::LanguageSpec { + let desugar = DesugaringConfig::new(desugaring_rules()); + simple::LanguageSpec { + prefix: "swift", + ts_language: tree_sitter_swift::LANGUAGE.into(), + node_types: tree_sitter_swift::NODE_TYPES, + file_globs: vec!["*.swift".into(), "*.swiftinterface".into()], + desugar: Some(desugar), + } +} From a1447075e8e26b629f660c7d3efd800eacd7f9e8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 7 May 2026 10:48:22 +0200 Subject: [PATCH 38/43] Add AGENTS.md with build/test instructions --- unified/AGENTS.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 unified/AGENTS.md diff --git a/unified/AGENTS.md b/unified/AGENTS.md new file mode 100644 index 00000000000..44cb7437288 --- /dev/null +++ b/unified/AGENTS.md @@ -0,0 +1,15 @@ +# Agent instructions + +This is a CodeQL extractor based on tree-sitter. + +## Building +To build the extractor, run `scripts/create-extractor-pack.sh` + +## Testing +- If you changed the extractor code, always rebuild it before running tests. + +- To run all 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. + +- To run a specific test, pass the specific directory to the `codeql test run` command instead of `ql/test`. From 28028191702733ba96465a2d28303454fcb7380c Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 7 May 2026 21:37:42 +0200 Subject: [PATCH 39/43] Use new YEAST API after rebasing --- unified/extractor/src/languages/swift/swift.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index 5b21473874c..c3843a5979c 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -12,7 +12,7 @@ fn desugaring_rules() -> Vec { } pub fn language_spec() -> simple::LanguageSpec { - let desugar = DesugaringConfig::new(desugaring_rules()); + let desugar = DesugaringConfig::new().add_phase("desugar", desugaring_rules()); simple::LanguageSpec { prefix: "swift", ts_language: tree_sitter_swift::LANGUAGE.into(), From 048411e168c1bb3c6cb2d497419192f10a98c129 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 8 May 2026 08:11:32 +0200 Subject: [PATCH 40/43] Apply suggestions from code review Co-authored-by: Anders Schack-Mulligen --- shared/controlflow/codeql/controlflow/ControlFlowGraph.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index 17a01b7e371..7a6b6318ed1 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -490,11 +490,11 @@ module Make0 Ast> { */ default Parameter callableGetParameter(Callable c, CallableContext ctx, int index) { none() } - /** Holds if this catch clause catches all exceptions. */ + /** Holds if catch clause `catch` catches all exceptions. */ default predicate catchAll(CatchClause catch) { none() } /** - * Holds if this case matches all possible values, for example, if it is a + * Holds if case `c` matches all possible values, for example, if it is a * `default` case or a match-all pattern like `Object o` or if it is the * final case in a switch that is known to be exhaustive. * From 9a2b7bac8f0210200e829fa21d407fd74d7527b3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 8 May 2026 08:56:40 +0200 Subject: [PATCH 41/43] Fix Bazel glob to include subdirectories Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- unified/extractor/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unified/extractor/BUILD.bazel b/unified/extractor/BUILD.bazel index c5860edc51a..5a53d7cc3e0 100644 --- a/unified/extractor/BUILD.bazel +++ b/unified/extractor/BUILD.bazel @@ -5,7 +5,7 @@ exports_files(["Cargo.toml"]) codeql_rust_binary( name = "extractor", - srcs = glob(["src/*.rs"]), + srcs = glob(["src/**/*.rs"]), aliases = aliases(), proc_macro_deps = all_crate_deps( proc_macro = True, From 33e89ea1237157da58f9c38124fb3978864d1f5a Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 8 May 2026 09:03:18 +0200 Subject: [PATCH 42/43] Address review comments --- unified/extractor/src/extractor.rs | 6 +++--- unified/extractor/src/generator.rs | 4 ++-- unified/ql/lib/unified.dbscheme | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/unified/extractor/src/extractor.rs b/unified/extractor/src/extractor.rs index 137b2f3c0e4..eb6f06eb259 100644 --- a/unified/extractor/src/extractor.rs +++ b/unified/extractor/src/extractor.rs @@ -9,7 +9,7 @@ mod swift; #[derive(Args)] pub struct Options { - /// Sets a custom source achive folder + /// Sets a custom source archive folder #[arg(long)] source_archive_dir: PathBuf, @@ -23,7 +23,7 @@ pub struct Options { } pub fn run(options: Options) -> std::io::Result<()> { - codeql_extractor::extractor::set_tracing_level("ql"); + codeql_extractor::extractor::set_tracing_level("unified"); let extractor = simple::Extractor { prefix: "unified".to_string(), @@ -31,7 +31,7 @@ pub fn run(options: Options) -> std::io::Result<()> { swift::language_spec(), ], trap_dir: options.output_dir, - trap_compression: trap::Compression::from_env("CODEQL_QL_TRAP_COMPRESSION"), + trap_compression: trap::Compression::from_env("CODEQL_EXTRACTOR_UNIFIED_OPTION_TRAP_COMPRESSION"), source_archive_dir: options.source_archive_dir, file_lists: vec![options.file_list], }; diff --git a/unified/extractor/src/generator.rs b/unified/extractor/src/generator.rs index ee65da7a600..ce1f37144a4 100644 --- a/unified/extractor/src/generator.rs +++ b/unified/extractor/src/generator.rs @@ -15,7 +15,7 @@ pub struct Options { } pub fn run(options: Options) -> std::io::Result<()> { - codeql_extractor::extractor::set_tracing_level("ql"); + codeql_extractor::extractor::set_tracing_level("unified"); let languages = vec![Language { name: "Swift".to_owned(), @@ -23,5 +23,5 @@ pub fn run(options: Options) -> std::io::Result<()> { desugar: None, }]; - generate(languages, options.dbscheme, options.library, "run ql/unified/scripts/create-extractor-pack.sh") + generate(languages, options.dbscheme, options.library, "run unified/scripts/create-extractor-pack.sh") } diff --git a/unified/ql/lib/unified.dbscheme b/unified/ql/lib/unified.dbscheme index 026d4add415..c580e8e6927 100644 --- a/unified/ql/lib/unified.dbscheme +++ b/unified/ql/lib/unified.dbscheme @@ -1,6 +1,6 @@ // CodeQL database schema for Swift // Automatically generated from the tree-sitter grammar; do not edit -// To regenerate, run ql/unified/scripts/create-extractor-pack.sh +// To regenerate, run unified/scripts/create-extractor-pack.sh /*- Files and folders -*/ From 26e13055c8b9377823c856daa52f3397779223aa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 8 May 2026 09:24:10 +0000 Subject: [PATCH 43/43] update codeql documentation --- .../codeql-changelog/codeql-cli-2.25.3.rst | 2 +- .../codeql-changelog/codeql-cli-2.25.4.rst | 147 ++++++++++++++++++ .../codeql-changelog/index.rst | 1 + 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.4.rst diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.3.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.3.rst index 88130515732..b14905f6eb6 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.3.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.3.rst @@ -1,7 +1,7 @@ .. _codeql-cli-2.25.3: ========================== -CodeQL 2.25.3 (2026-05-01) +CodeQL 2.25.3 (2026-04-30) ========================== .. contents:: Contents diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.4.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.4.rst new file mode 100644 index 00000000000..649c6f26f6a --- /dev/null +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.25.4.rst @@ -0,0 +1,147 @@ +.. _codeql-cli-2.25.4: + +========================== +CodeQL 2.25.4 (2026-05-05) +========================== + +.. 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.4 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 +---------- + +There are no user-facing CLI changes in this release. + +Language Libraries +------------------ + +Breaking Changes +~~~~~~~~~~~~~~~~ + +C# +"" + +* The C# control flow graph (CFG) implementation has been completely rewritten. The CFG now includes additional nodes to more accurately represent certain constructs. This also means that any existing code that implicitly relies on very specific details about the CFG may need to be updated. + The CFG no longer uses splitting, which means that AST nodes now have a unique CFG node representation. + Additionally, the following breaking changes have been made: + + * :code:`ControlFlow::Node` has been renamed to :code:`ControlFlowNode`. + * :code:`ControlFlow::Nodes` has been renamed to :code:`ControlFlowNodes`. + * :code:`BasicBlock.getCallable` has been renamed to :code:`BasicBlock.getEnclosingCallable`. + * :code:`BasicBlocks.qll` has been deleted. + * :code:`ControlFlowNode.getAstNode` has changed its meaning. The AST-to-CFG mapping remains one-to-many, but now for a different reason. It used to be because of splitting, but now it's because of additional "helper" CFG nodes. To get the (now canonical) CFG node for a given AST node, use + :code:`ControlFlowNode.asExpr()` or :code:`ControlFlowNode.asStmt()` or + :code:`ControlFlowElement.getControlFlowNode()` instead. + +Major Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C# +"" + +* When resolving dependencies in :code:`build-mode: none`, :code:`dotnet restore` now explicitly receives reachable NuGet feeds configured in :code:`nuget.config` when feed responsiveness checking is enabled (the default), and any private registries directly, improving reliability when default feeds are unavailable or restricted. + +Swift +""""" + +* Upgraded to allow analysis of Swift 6.3.1. + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* Added taint flow models for the :code:`Strsafe.h` header from the Windows SDK. + +C# +"" + +* Expanded ASP and ASP.NET remote source modeling to cover additional sources, including fields of tainted parameters as well as properties and fields that become tainted transitively. +* C# 14: Added support for user-defined compound assignment operators. + +Java/Kotlin +""""""""""" + +* Added :code:`sql-injection` sink models for the Hibernate :code:`org.hibernate.query.QueryProducer` methods :code:`createNativeMutationQuery`, :code:`createMutationQuery`, and :code:`createSelectionQuery`. +* The :code:`java/partial-path-traversal` and :code:`java/partial-path-traversal-from-remote` queries now correctly recognize file separator appends using :code:`+=`. +* The :code:`java/path-injection` and :code:`java/zipslip` queries now recognize :code:`Path.toRealPath()` as a path normalization sanitizer, consistent with the existing treatment of :code:`Path.normalize()` and :code:`File.getCanonicalPath()`. This reduces false positives for code that uses the NIO.2 API for path canonicalization. +* The :code:`java/sensitive-log` query now excludes additional common variable naming patterns that do not hold sensitive data, reducing false positives. This includes pagination/iteration tokens (:code:`nextToken`, :code:`pageToken`, :code:`continuationToken`), token metadata (:code:`tokenType`, :code:`tokenEndpoint`, :code:`tokenCount`), and secret metadata (:code:`secretName`, :code:`secretId`, :code:`secretVersion`). +* The :code:`java/sensitive-log` query now treats method calls whose names contain "encrypt", "hash", or "digest" as sanitizers, consistent with the existing treatment in :code:`java/cleartext-storage-in-log`. This reduces false positives when sensitive data is hashed or encrypted before logging. +* The :code:`java/trust-boundary-violation` query now recognizes regular expression checks (including :code:`String.matches()` guards and :code:`@javax.validation.constraints.Pattern` annotations) as sanitizers, consistent with the existing treatment of ESAPI validators. This reduces false positives when input is validated against a pattern before being stored in a session. + +Python +"""""" + +* The Python extractor now supports unpacking in comprehensions, e.g. :code:`[*x for x in nested]` (as defined in `PEP-798 `__) that will be part of Python 3.15. + +Deprecated APIs +~~~~~~~~~~~~~~~ + +C# +"" + +* The QL classes in the C# SSA library have been renamed to improve consistency between languages. Any custom QL code that makes use of SSA needs to be updated. The old classes have been deprecated and include more detailed migration instructions in their qldoc. + +New Features +~~~~~~~~~~~~ + +C/C++ +""""" + +* A new predicate :code:`getSwitchCase` was added to the :code:`SwitchStmt` class, which yields the :code:`n`\ th :code:`case` statement from a :code:`switch` statement. +* Data flow barriers and barrier guards can now be added using data extensions. For more information see `Customizing library models for C and C++ `__. + +C# +"" + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see `Customizing library models for C# `__. + +Golang +"""""" + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see `Customizing library models for Go `__. + +Java/Kotlin +""""""""""" + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see `Customizing library models for Java and Kotlin `__. + +JavaScript/TypeScript +""""""""""""""""""""" + +* Added support for |link-code-vercel-node-1|_ Vercel serverless functions. Handlers are recognized via the :code:`VercelRequest`\ /\ :code:`VercelResponse` TypeScript parameter types, and standard security queries (:code:`js/reflected-xss`, :code:`js/request-forgery`, :code:`js/sql-injection`, :code:`js/command-line-injection`, etc.) now detect vulnerabilities in Vercel API route files. +* Data flow barriers and barrier guards can now be added using data extensions. For more information see `Customizing library models for JavaScript `__. + +Python +"""""" + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see `Customizing library models for Python `__. + +Ruby +"""" + +* Data flow barriers and barrier guards can now be added using data extensions. For more information see `Customizing library models for Ruby `__. + +Swift +""""" + +* The :code:`BuiltinFixedArrayType` class now defines the predicates :code:`getSize` and :code:`getElementType`, which yield the size of the array and the type of elements stored in the array, respectively. + +Rust +"""" + +* Data flow barriers and barrier guards can now be added using data extensions. + +.. |link-code-vercel-node-1| replace:: :code:`@vercel/node`\ +.. _link-code-vercel-node-1: https://www.npmjs.com/package/@vercel/node + diff --git a/docs/codeql/codeql-overview/codeql-changelog/index.rst b/docs/codeql/codeql-overview/codeql-changelog/index.rst index 5835176a93f..c5d4fee4576 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