Swift: Manual changes after running code generator

This commit is contained in:
Tom Hvitved
2024-09-13 14:32:28 +02:00
parent c785cd9d7b
commit d2f633b3b4
164 changed files with 2362 additions and 1974 deletions

View File

@@ -5,80 +5,82 @@ private import codeql.swift.elements.expr.ClosureExpr
private import codeql.swift.elements.Callable private import codeql.swift.elements.Callable
private import codeql.swift.generated.ParentChild private import codeql.swift.generated.ParentChild
private module Cached { module Impl {
private Element getEnclosingDeclStep(Element e) { private module Cached {
not e instanceof Decl and private Element getEnclosingDeclStep(Element e) {
result = getImmediateParent(e) not e instanceof Decl and
result = getImmediateParent(e)
}
cached
Decl getEnclosingDecl(AstNode ast) { result = getEnclosingDeclStep*(getImmediateParent(ast)) }
private Element getEnclosingFunctionStep(Element e) {
not e instanceof Function and
result = getEnclosingDecl(e)
}
cached
Function getEnclosingFunction(AstNode ast) {
result = getEnclosingFunctionStep*(getEnclosingDecl(ast))
}
private Element getEnclosingClosureStep(Element e) {
not e instanceof Callable and
result = getImmediateParent(e)
}
cached
ClosureExpr getEnclosingClosure(AstNode ast) {
result = getEnclosingClosureStep*(getImmediateParent(ast))
}
} }
cached /**
Decl getEnclosingDecl(AstNode ast) { result = getEnclosingDeclStep*(getImmediateParent(ast)) } * A node in the abstract syntax tree.
*/
class AstNode extends Generated::AstNode {
/**
* Gets the nearest function definition that contains this AST node, if any.
* This includes functions, methods, (de)initializers, and accessors, but not closures.
*
* For example, in the following code, the AST node for `n + 1` has `foo` as its
* enclosing function (via `getEnclosingFunction`), whereas its enclosing callable is
* the closure `{(n : Int) in n + 1 }` (via `getEnclosingCallable`):
*
* ```swift
* func foo() {
* var f = { (n : Int) in n + 1 }
* }
* ```
*/
final Function getEnclosingFunction() { result = Cached::getEnclosingFunction(this) }
private Element getEnclosingFunctionStep(Element e) { /**
not e instanceof Function and * Gets the nearest declaration that contains this AST node, if any.
result = getEnclosingDecl(e) *
} * Note that the nearest declaration may be an extension of a type declaration. If you always
* want the type declaration and not the extension, use `getEnclosingDecl().asNominalTypeDecl()`.
*/
final Decl getEnclosingDecl() { result = Cached::getEnclosingDecl(this) }
cached /**
Function getEnclosingFunction(AstNode ast) { * Gets the nearest `Callable` that contains this AST node, if any.
result = getEnclosingFunctionStep*(getEnclosingDecl(ast)) * This includes (auto)closures, functions, methods, (de)initializers, and accessors.
} *
* For example, in the following code, the AST node for `n + 1` has the closure
private Element getEnclosingClosureStep(Element e) { * `{(n : Int) in n + 1 }` as its enclosing callable.
not e instanceof Callable and *
result = getImmediateParent(e) * ```swift
} * func foo() {
* var f = { (n : Int) in n + 1 }
cached * }
ClosureExpr getEnclosingClosure(AstNode ast) { * ```
result = getEnclosingClosureStep*(getImmediateParent(ast)) */
} final Callable getEnclosingCallable() {
} if exists(Cached::getEnclosingClosure(this))
then result = Cached::getEnclosingClosure(this)
/** else result = Cached::getEnclosingFunction(this)
* A node in the abstract syntax tree. }
*/
class AstNode extends Generated::AstNode {
/**
* Gets the nearest function definition that contains this AST node, if any.
* This includes functions, methods, (de)initializers, and accessors, but not closures.
*
* For example, in the following code, the AST node for `n + 1` has `foo` as its
* enclosing function (via `getEnclosingFunction`), whereas its enclosing callable is
* the closure `{(n : Int) in n + 1 }` (via `getEnclosingCallable`):
*
* ```swift
* func foo() {
* var f = { (n : Int) in n + 1 }
* }
* ```
*/
final Function getEnclosingFunction() { result = Cached::getEnclosingFunction(this) }
/**
* Gets the nearest declaration that contains this AST node, if any.
*
* Note that the nearest declaration may be an extension of a type declaration. If you always
* want the type declaration and not the extension, use `getEnclosingDecl().asNominalTypeDecl()`.
*/
final Decl getEnclosingDecl() { result = Cached::getEnclosingDecl(this) }
/**
* Gets the nearest `Callable` that contains this AST node, if any.
* This includes (auto)closures, functions, methods, (de)initializers, and accessors.
*
* For example, in the following code, the AST node for `n + 1` has the closure
* `{(n : Int) in n + 1 }` as its enclosing callable.
*
* ```swift
* func foo() {
* var f = { (n : Int) in n + 1 }
* }
* ```
*/
final Callable getEnclosingCallable() {
if exists(Cached::getEnclosingClosure(this))
then result = Cached::getEnclosingClosure(this)
else result = Cached::getEnclosingFunction(this)
} }
} }

View File

@@ -1,25 +1,27 @@
private import codeql.swift.generated.AvailabilityInfo private import codeql.swift.generated.AvailabilityInfo
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* An availability condition of an `if`, `while`, or `guard` statements. /**
* * An availability condition of an `if`, `while`, or `guard` statements.
* Examples: *
* ``` * Examples:
* if #available(iOS 12, *) { * ```
* // Runs on iOS 12 and above * if #available(iOS 12, *) {
* } else { * // Runs on iOS 12 and above
* // Runs only anything below iOS 12 * } else {
* } * // Runs only anything below iOS 12
* if #unavailable(macOS 10.14, *) { * }
* // Runs only on macOS 10 and below * if #unavailable(macOS 10.14, *) {
* } * // Runs only on macOS 10 and below
* ``` * }
*/ * ```
class AvailabilityInfo extends Generated::AvailabilityInfo { */
override string toString() { class AvailabilityInfo extends Generated::AvailabilityInfo {
result = "#available" and not this.isUnavailable() override string toString() {
or result = "#available" and not this.isUnavailable()
result = "#unavailable" and this.isUnavailable() or
result = "#unavailable" and this.isUnavailable()
}
} }
} }

View File

@@ -2,18 +2,20 @@ private import codeql.swift.generated.Callable
private import codeql.swift.elements.AstNode private import codeql.swift.elements.AstNode
private import codeql.swift.elements.decl.Decl private import codeql.swift.elements.decl.Decl
class Callable extends Generated::Callable { module Impl {
/** class Callable extends Generated::Callable {
* Holds if this Callable is a function named `funcName`. /**
*/ * Holds if this Callable is a function named `funcName`.
predicate hasName(string funcName) { this.getName() = funcName } */
predicate hasName(string funcName) { this.getName() = funcName }
/** /**
* Holds if this Callable is a function named `funcName` defined in a module * Holds if this Callable is a function named `funcName` defined in a module
* called `moduleName`. * called `moduleName`.
*/ */
predicate hasName(string moduleName, string funcName) { predicate hasName(string moduleName, string funcName) {
this.hasName(funcName) and this.hasName(funcName) and
this.(Decl).getModule().getFullName() = moduleName this.(Decl).getModule().getFullName() = moduleName
}
} }
} }

View File

@@ -1,35 +1,8 @@
private import codeql.swift.generated.Comment private import codeql.swift.generated.Comment
class Comment extends Generated::Comment { module Impl {
/** toString */ class Comment extends Generated::Comment {
override string toString() { result = this.getText() } /** toString */
} override string toString() { result = this.getText() }
class SingleLineComment extends Comment {
SingleLineComment() {
this.getText().matches("//%") and
not this instanceof SingleLineDocComment
} }
} }
class MultiLineComment extends Comment {
MultiLineComment() {
this.getText().matches("/*%") and
not this instanceof MultiLineDocComment
}
}
class DocComment extends Comment {
DocComment() {
this instanceof SingleLineDocComment or
this instanceof MultiLineDocComment
}
}
class SingleLineDocComment extends Comment {
SingleLineDocComment() { this.getText().matches("///%") }
}
class MultiLineDocComment extends Comment {
MultiLineDocComment() { this.getText().matches("/**%") }
}

View File

@@ -0,0 +1,27 @@
import Comment
final class SingleLineComment extends Comment {
SingleLineComment() {
this.getText().matches("//%") and
not this instanceof SingleLineDocComment
}
}
final class MultiLineComment extends Comment {
MultiLineComment() {
this.getText().matches("/*%") and
not this instanceof MultiLineDocComment
}
}
abstract private class DocCommentImpl extends Comment { }
final class DocComment = DocCommentImpl;
final class SingleLineDocComment extends DocCommentImpl {
SingleLineDocComment() { this.getText().matches("///%") }
}
final class MultiLineDocComment extends DocCommentImpl {
MultiLineDocComment() { this.getText().matches("/**%") }
}

View File

@@ -0,0 +1,29 @@
import Diagnostics
/**
* A compiler error message.
*/
final class CompilerError extends Diagnostics {
CompilerError() { this.getSeverity() = "error" }
}
/**
* A compiler-generated warning.
*/
final class CompilerWarning extends Diagnostics {
CompilerWarning() { this.getSeverity() = "warning" }
}
/**
* A compiler-generated note (typically attached to an error or warning).
*/
final class CompilerNote extends Diagnostics {
CompilerNote() { this.getSeverity() = "note" }
}
/**
* A compiler-generated remark (milder than a warning, this does not indicate an issue).
*/
final class CompilerRemark extends Diagnostics {
CompilerRemark() { this.getSeverity() = "remark" }
}

View File

@@ -1,49 +1,23 @@
private import codeql.swift.generated.Diagnostics private import codeql.swift.generated.Diagnostics
/** module Impl {
* A compiler-generated error, warning, note or remark.
*/
class Diagnostics extends Generated::Diagnostics {
override string toString() { result = this.getSeverity() + ": " + this.getText() }
/** /**
* Gets a string representing the severity of this compiler diagnostic. * A compiler-generated error, warning, note or remark.
*/ */
string getSeverity() { class Diagnostics extends Generated::Diagnostics {
this.getKind() = 1 and result = "error" override string toString() { result = this.getSeverity() + ": " + this.getText() }
or
this.getKind() = 2 and result = "warning" /**
or * Gets a string representing the severity of this compiler diagnostic.
this.getKind() = 3 and result = "note" */
or string getSeverity() {
this.getKind() = 4 and result = "remark" this.getKind() = 1 and result = "error"
or
this.getKind() = 2 and result = "warning"
or
this.getKind() = 3 and result = "note"
or
this.getKind() = 4 and result = "remark"
}
} }
} }
/**
* A compiler error message.
*/
class CompilerError extends Diagnostics {
CompilerError() { this.getSeverity() = "error" }
}
/**
* A compiler-generated warning.
*/
class CompilerWarning extends Diagnostics {
CompilerWarning() { this.getSeverity() = "warning" }
}
/**
* A compiler-generated note (typically attached to an error or warning).
*/
class CompilerNote extends Diagnostics {
CompilerNote() { this.getSeverity() = "note" }
}
/**
* A compiler-generated remark (milder than a warning, this does not indicate an issue).
*/
class CompilerRemark extends Diagnostics {
CompilerRemark() { this.getSeverity() = "remark" }
}

View File

@@ -1,20 +1,22 @@
private import codeql.swift.generated.Element private import codeql.swift.generated.Element
class Element extends Generated::Element { module Impl {
private predicate resolvesFrom(Element e) { e.getResolveStep() = this } class Element extends Generated::Element {
private predicate resolvesFrom(Element e) { e.getResolveStep() = this }
override string toString() { result = this.getPrimaryQlClasses() } override string toString() { result = this.getPrimaryQlClasses() }
Element getFullyUnresolved() { Element getFullyUnresolved() {
not this.resolvesFrom(_) and result = this not this.resolvesFrom(_) and result = this
or or
exists(Element e | exists(Element e |
this.resolvesFrom(e) and this.resolvesFrom(e) and
result = e.getFullyUnresolved() result = e.getFullyUnresolved()
) )
}
}
class UnknownElement extends Element {
UnknownElement() { this.isUnknown() }
} }
} }
class UnknownElement extends Element {
UnknownElement() { this.isUnknown() }
}

View File

@@ -2,106 +2,110 @@ private import codeql.swift.generated.File
private import codeql.swift.elements.Location private import codeql.swift.elements.Location
private import codeql.swift.elements.UnknownLocation private import codeql.swift.elements.UnknownLocation
class File extends Generated::File { module Impl {
/** toString */ class File extends Generated::File {
override string toString() { result = this.getAbsolutePath() } /** toString */
override string toString() { result = this.getAbsolutePath() }
/** Gets the absolute path of this file. */ /** Gets the absolute path of this file. */
string getAbsolutePath() { result = this.getName() } string getAbsolutePath() { result = this.getName() }
/** Gets the full name of this file. */ /** Gets the full name of this file. */
string getFullName() { result = this.getAbsolutePath() } string getFullName() { result = this.getAbsolutePath() }
/** Gets the URL of this file. */ /** Gets the URL of this file. */
string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
/** /**
* Holds if either, * Holds if either,
* - `part` is the base name of this container and `i = 1`, or * - `part` is the base name of this container and `i = 1`, or
* - `part` is the stem of this container and `i = 2`, or * - `part` is the stem of this container and `i = 2`, or
* - `part` is the extension of this container and `i = 3`. * - `part` is the extension of this container and `i = 3`.
*/ */
cached cached
private predicate splitAbsolutePath(string part, int i) { private predicate splitAbsolutePath(string part, int i) {
part = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", i) part = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", i)
} }
/** Gets the base name of this file. */ /** Gets the base name of this file. */
string getBaseName() { this.splitAbsolutePath(result, 1) } string getBaseName() { this.splitAbsolutePath(result, 1) }
/** /**
* Gets the extension of this container, that is, the suffix of its base name * Gets the extension of this container, that is, the suffix of its base name
* after the last dot character, if any. * after the last dot character, if any.
* *
* In particular, * In particular,
* *
* - if the name does not include a dot, there is no extension, so this * - if the name does not include a dot, there is no extension, so this
* predicate has no result; * predicate has no result;
* - if the name ends in a dot, the extension is the empty string; * - if the name ends in a dot, the extension is the empty string;
* - if the name contains multiple dots, the extension follows the last dot. * - if the name contains multiple dots, the extension follows the last dot.
* *
* Here are some examples of absolute paths and the corresponding extensions * Here are some examples of absolute paths and the corresponding extensions
* (surrounded with quotes to avoid ambiguity): * (surrounded with quotes to avoid ambiguity):
* *
* <table border="1"> * <table border="1">
* <tr><th>Absolute path</th><th>Extension</th></tr> * <tr><th>Absolute path</th><th>Extension</th></tr>
* <tr><td>"/tmp/tst.txt"</td><td>"txt"</td></tr> * <tr><td>"/tmp/tst.txt"</td><td>"txt"</td></tr>
* <tr><td>"/tmp/.classpath"</td><td>"classpath"</td></tr> * <tr><td>"/tmp/.classpath"</td><td>"classpath"</td></tr>
* <tr><td>"/bin/bash"</td><td>not defined</td></tr> * <tr><td>"/bin/bash"</td><td>not defined</td></tr>
* <tr><td>"/tmp/tst2."</td><td>""</td></tr> * <tr><td>"/tmp/tst2."</td><td>""</td></tr>
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr> * <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
* </table> * </table>
*/ */
string getExtension() { this.splitAbsolutePath(result, 3) } string getExtension() { this.splitAbsolutePath(result, 3) }
/** /**
* Gets the stem of this container, that is, the prefix of its base name up to * Gets the stem of this container, that is, the prefix of its base name up to
* (but not including) the last dot character if there is one, or the entire * (but not including) the last dot character if there is one, or the entire
* base name if there is not. * base name if there is not.
* *
* Here are some examples of absolute paths and the corresponding stems * Here are some examples of absolute paths and the corresponding stems
* (surrounded with quotes to avoid ambiguity): * (surrounded with quotes to avoid ambiguity):
* *
* <table border="1"> * <table border="1">
* <tr><th>Absolute path</th><th>Stem</th></tr> * <tr><th>Absolute path</th><th>Stem</th></tr>
* <tr><td>"/tmp/tst.txt"</td><td>"tst"</td></tr> * <tr><td>"/tmp/tst.txt"</td><td>"tst"</td></tr>
* <tr><td>"/tmp/.classpath"</td><td>""</td></tr> * <tr><td>"/tmp/.classpath"</td><td>""</td></tr>
* <tr><td>"/bin/bash"</td><td>"bash"</td></tr> * <tr><td>"/bin/bash"</td><td>"bash"</td></tr>
* <tr><td>"/tmp/tst2."</td><td>"tst2"</td></tr> * <tr><td>"/tmp/tst2."</td><td>"tst2"</td></tr>
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr> * <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
* </table> * </table>
*/ */
string getStem() { this.splitAbsolutePath(result, 2) } string getStem() { this.splitAbsolutePath(result, 2) }
/** /**
* Gets the number of lines containing code in this file. This value * Gets the number of lines containing code in this file. This value
* is approximate. * is approximate.
*/ */
int getNumberOfLinesOfCode() { int getNumberOfLinesOfCode() {
result = result =
count(int line | count(int line |
exists(Location loc | exists(Location loc |
not loc instanceof UnknownLocation and loc.getFile() = this and loc.getStartLine() = line not loc instanceof UnknownLocation and
loc.getFile() = this and
loc.getStartLine() = line
)
) )
) }
}
/** /**
* Gets the relative path of this file from the root folder of the * Gets the relative path of this file from the root folder of the
* analyzed source location. The relative path of the root folder itself * analyzed source location. The relative path of the root folder itself
* would be the empty string. * would be the empty string.
* *
* This has no result if the file is outside the source root, that is, * This has no result if the file is outside the source root, that is,
* if the root folder is not a reflexive, transitive parent of this file. * if the root folder is not a reflexive, transitive parent of this file.
*/ */
string getRelativePath() { string getRelativePath() {
exists(string absPath, string pref | exists(string absPath, string pref |
absPath = this.getAbsolutePath() and sourceLocationPrefix(pref) absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
| |
absPath = pref and result = "" absPath = pref and result = ""
or or
absPath = pref.regexpReplaceAll("/$", "") + "/" + result and absPath = pref.regexpReplaceAll("/$", "") + "/" + result and
not result.matches("/%") not result.matches("/%")
) )
}
} }
} }

View File

@@ -1,62 +1,64 @@
private import codeql.swift.generated.KeyPathComponent private import codeql.swift.generated.KeyPathComponent
private import swift private import swift
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* A component of a `KeyPathExpr`.
*/
class KeyPathComponent extends Generated::KeyPathComponent {
/** /**
* Property access like `.bar` in `\Foo.bar`. * A component of a `KeyPathExpr`.
*/ */
predicate isProperty() { this.getKind() = 3 } class KeyPathComponent extends Generated::KeyPathComponent {
/**
* Property access like `.bar` in `\Foo.bar`.
*/
predicate isProperty() { this.getKind() = 3 }
/** /**
* Array or dictionary subscript like `[1]` or `["a", "b"]`. * Array or dictionary subscript like `[1]` or `["a", "b"]`.
*/ */
predicate isSubscript() { this.getKind() = 4 } predicate isSubscript() { this.getKind() = 4 }
/** /**
* Optional forcing `!`. * Optional forcing `!`.
*/ */
predicate isOptionalForcing() { this.getKind() = 5 } predicate isOptionalForcing() { this.getKind() = 5 }
/** /**
* Optional chaining `?`. * Optional chaining `?`.
*/ */
predicate isOptionalChaining() { this.getKind() = 6 } predicate isOptionalChaining() { this.getKind() = 6 }
/** /**
* Implicit optional wrapping component inserted by the compiler when an optional chain ends in a non-optional value. * Implicit optional wrapping component inserted by the compiler when an optional chain ends in a non-optional value.
*/ */
predicate isOptionalWrapping() { this.getKind() = 7 } predicate isOptionalWrapping() { this.getKind() = 7 }
/** /**
* Reference to the entire object; the `self` in `\Foo.self`. * Reference to the entire object; the `self` in `\Foo.self`.
*/ */
predicate isSelf() { this.getKind() = 8 } predicate isSelf() { this.getKind() = 8 }
/** /**
* Tuple indexing like `.1`. * Tuple indexing like `.1`.
*/ */
predicate isTupleIndexing() { this.getKind() = 9 } predicate isTupleIndexing() { this.getKind() = 9 }
/** Gets the underlying key-path expression which this is a component of. */ /** Gets the underlying key-path expression which this is a component of. */
KeyPathExpr getKeyPathExpr() { result.getAComponent() = this } KeyPathExpr getKeyPathExpr() { result.getAComponent() = this }
/** Holds if this component is the i'th component of the underling key-path expression. */ /** Holds if this component is the i'th component of the underling key-path expression. */
predicate hasIndex(int i) { any(KeyPathExpr e).getComponent(i) = this } predicate hasIndex(int i) { any(KeyPathExpr e).getComponent(i) = this }
/** Gets the next component of the underlying key-path expression. */ /** Gets the next component of the underlying key-path expression. */
KeyPathComponent getNextComponent() { KeyPathComponent getNextComponent() {
exists(int i, KeyPathExpr e | exists(int i, KeyPathExpr e |
hasKeyPathExprAndIndex(e, i, this) and hasKeyPathExprAndIndex(e, i, this) and
hasKeyPathExprAndIndex(e, i + 1, result) hasKeyPathExprAndIndex(e, i + 1, result)
) )
}
}
pragma[nomagic]
private predicate hasKeyPathExprAndIndex(KeyPathExpr e, int i, KeyPathComponent c) {
e.getComponent(i) = c
} }
} }
pragma[nomagic]
private predicate hasKeyPathExprAndIndex(KeyPathExpr e, int i, KeyPathComponent c) {
e.getComponent(i) = c
}

View File

@@ -2,17 +2,19 @@ private import codeql.swift.generated.Locatable
private import codeql.swift.elements.File private import codeql.swift.elements.File
private import codeql.swift.elements.UnknownLocation private import codeql.swift.elements.UnknownLocation
class Locatable extends Generated::Locatable { module Impl {
pragma[nomagic] class Locatable extends Generated::Locatable {
override Location getLocation() { pragma[nomagic]
result = Generated::Locatable.super.getLocation() override Location getLocation() {
or result = Generated::Locatable.super.getLocation()
not exists(Generated::Locatable.super.getLocation()) and or
result instanceof UnknownLocation not exists(Generated::Locatable.super.getLocation()) and
} result instanceof UnknownLocation
}
/** /**
* Gets the primary file where this element occurs. * Gets the primary file where this element occurs.
*/ */
File getFile() { result = this.getLocation().getFile() } File getFile() { result = this.getLocation().getFile() }
}
} }

View File

@@ -1,28 +1,32 @@
private import codeql.swift.generated.Location private import codeql.swift.generated.Location
/** module Impl {
* A location of a program element.
*/
class Location extends Generated::Location {
/** /**
* Holds if this location is described by `path`, `startLine`, `startColumn`, `endLine` and `endColumn`. * A location of a program element.
*/ */
predicate hasLocationInfo(string path, int startLine, int startColumn, int endLine, int endColumn) { class Location extends Generated::Location {
path = this.getFile().getFullName() and /**
startLine = this.getStartLine() and * Holds if this location is described by `path`, `startLine`, `startColumn`, `endLine` and `endColumn`.
startColumn = this.getStartColumn() and */
endLine = this.getEndLine() and predicate hasLocationInfo(
endColumn = this.getEndColumn() string path, int startLine, int startColumn, int endLine, int endColumn
} ) {
path = this.getFile().getFullName() and
startLine = this.getStartLine() and
startColumn = this.getStartColumn() and
endLine = this.getEndLine() and
endColumn = this.getEndColumn()
}
/** /**
* Gets a textual representation of this location. * Gets a textual representation of this location.
*/ */
override string toString() { override string toString() {
exists(string filePath, int startLine, int startColumn, int endLine, int endColumn | exists(string filePath, int startLine, int startColumn, int endLine, int endColumn |
this.hasLocationInfo(filePath, startLine, startColumn, endLine, endColumn) this.hasLocationInfo(filePath, startLine, startColumn, endLine, endColumn)
| |
toUrl(filePath, startLine, startColumn, endLine, endColumn, result) toUrl(filePath, startLine, startColumn, endLine, endColumn, result)
) )
}
} }
} }

View File

@@ -4,97 +4,101 @@
private import codeql.swift.generated.MacroRole private import codeql.swift.generated.MacroRole
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* The role of a macro, for example #freestanding(declaration) or @attached(member).
*/
class MacroRole extends Generated::MacroRole {
/** /**
* String representation of the role kind. * The role of a macro, for example #freestanding(declaration) or @attached(member).
*/ */
string getKindName() { class MacroRole extends Generated::MacroRole {
this.isExpressionKind() and result = "expression" /**
or * String representation of the role kind.
this.isDeclarationKind() and result = "declaration" */
or string getKindName() {
this.isAccessorKind() and result = "accessor" this.isExpressionKind() and result = "expression"
or or
this.isMemberAttributeKind() and result = "memberAttribute" this.isDeclarationKind() and result = "declaration"
or or
this.isMemberKind() and result = "member" this.isAccessorKind() and result = "accessor"
or or
this.isPeerKind() and result = "peer" this.isMemberAttributeKind() and result = "memberAttribute"
or or
this.isConformanceKind() and result = "conformance" this.isMemberKind() and result = "member"
or or
this.isCodeItemKind() and result = "codeItem" this.isPeerKind() and result = "peer"
or or
this.isExtensionKind() and result = "extension" this.isConformanceKind() and result = "conformance"
or
this.isCodeItemKind() and result = "codeItem"
or
this.isExtensionKind() and result = "extension"
}
/**
* Holds for `expression` roles.
*/
predicate isExpressionKind() { this.getKind() = 1 }
/**
* Holds for `declaration` roles.
*/
predicate isDeclarationKind() { this.getKind() = 2 }
/**
* Holds for `accessor` roles.
*/
predicate isAccessorKind() { this.getKind() = 4 }
/**
* Holds for `memberAttribute` roles.
*/
predicate isMemberAttributeKind() { this.getKind() = 8 }
/**
* Holds for `member` roles.
*/
predicate isMemberKind() { this.getKind() = 16 }
/**
* Holds for `peer` roles.
*/
predicate isPeerKind() { this.getKind() = 32 }
/**
* Holds for `conformance` roles.
*/
predicate isConformanceKind() { this.getKind() = 64 }
/**
* Holds for `codeItem` roles.
*/
predicate isCodeItemKind() { this.getKind() = 128 }
/**
* Holds for `extension` roles.
*/
predicate isExtensionKind() { this.getKind() = 256 }
/**
* String representation of the macro syntax.
*/
string getMacroSyntaxName() {
this.isFreestandingMacroSyntax() and result = "#freestanding"
or
this.isAttachedMacroSyntax() and result = "@attached"
}
/**
* Holds for #freestanding macros.
*/
predicate isFreestandingMacroSyntax() { this.getMacroSyntax() = 0 }
/**
* Holds for @attached macros.
*/
predicate isAttachedMacroSyntax() { this.getMacroSyntax() = 1 }
override string toString() {
result = this.getMacroSyntaxName() + "(" + this.getKindName() + ")"
}
} }
/**
* Holds for `expression` roles.
*/
predicate isExpressionKind() { this.getKind() = 1 }
/**
* Holds for `declaration` roles.
*/
predicate isDeclarationKind() { this.getKind() = 2 }
/**
* Holds for `accessor` roles.
*/
predicate isAccessorKind() { this.getKind() = 4 }
/**
* Holds for `memberAttribute` roles.
*/
predicate isMemberAttributeKind() { this.getKind() = 8 }
/**
* Holds for `member` roles.
*/
predicate isMemberKind() { this.getKind() = 16 }
/**
* Holds for `peer` roles.
*/
predicate isPeerKind() { this.getKind() = 32 }
/**
* Holds for `conformance` roles.
*/
predicate isConformanceKind() { this.getKind() = 64 }
/**
* Holds for `codeItem` roles.
*/
predicate isCodeItemKind() { this.getKind() = 128 }
/**
* Holds for `extension` roles.
*/
predicate isExtensionKind() { this.getKind() = 256 }
/**
* String representation of the macro syntax.
*/
string getMacroSyntaxName() {
this.isFreestandingMacroSyntax() and result = "#freestanding"
or
this.isAttachedMacroSyntax() and result = "@attached"
}
/**
* Holds for #freestanding macros.
*/
predicate isFreestandingMacroSyntax() { this.getMacroSyntax() = 0 }
/**
* Holds for @attached macros.
*/
predicate isAttachedMacroSyntax() { this.getMacroSyntax() = 1 }
override string toString() { result = this.getMacroSyntaxName() + "(" + this.getKindName() + ")" }
} }

View File

@@ -1,9 +1,11 @@
private import codeql.swift.generated.OtherAvailabilitySpec private import codeql.swift.generated.OtherAvailabilitySpec
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* A wildcard availability spec `*` /**
*/ * A wildcard availability spec `*`
class OtherAvailabilitySpec extends Generated::OtherAvailabilitySpec { */
override string toString() { result = "*" } class OtherAvailabilitySpec extends Generated::OtherAvailabilitySpec {
override string toString() { result = "*" }
}
} }

View File

@@ -1,9 +1,11 @@
private import codeql.swift.generated.PlatformVersionAvailabilitySpec private import codeql.swift.generated.PlatformVersionAvailabilitySpec
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* An availability spec based on platform and version, for example `macOS 12` or `watchOS 14` /**
*/ * An availability spec based on platform and version, for example `macOS 12` or `watchOS 14`
class PlatformVersionAvailabilitySpec extends Generated::PlatformVersionAvailabilitySpec { */
override string toString() { result = this.getPlatform() + " " + this.getVersion() } class PlatformVersionAvailabilitySpec extends Generated::PlatformVersionAvailabilitySpec {
override string toString() { result = this.getPlatform() + " " + this.getVersion() }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.UnknownFile private import codeql.swift.generated.UnknownFile
class UnknownFile extends Generated::UnknownFile { module Impl {
override string getName() { result = "" } class UnknownFile extends Generated::UnknownFile {
override string getName() { result = "" }
}
} }

View File

@@ -2,19 +2,21 @@ private import codeql.swift.generated.UnknownLocation
private import codeql.swift.elements.UnknownFile private import codeql.swift.elements.UnknownFile
private import codeql.swift.elements.File private import codeql.swift.elements.File
/** module Impl {
* A `Location` that is given to something that is not associated with any position in the source code. /**
*/ * A `Location` that is given to something that is not associated with any position in the source code.
class UnknownLocation extends Generated::UnknownLocation { */
override File getFile() { result instanceof UnknownFile } class UnknownLocation extends Generated::UnknownLocation {
override File getFile() { result instanceof UnknownFile }
override int getStartLine() { result = 0 } override int getStartLine() { result = 0 }
override int getStartColumn() { result = 0 } override int getStartColumn() { result = 0 }
override int getEndLine() { result = 0 } override int getEndLine() { result = 0 }
override int getEndColumn() { result = 0 } override int getEndColumn() { result = 0 }
override string toString() { result = "UnknownLocation" } override string toString() { result = "UnknownLocation" }
}
} }

View File

@@ -2,22 +2,24 @@ private import codeql.swift.generated.UnspecifiedElement
import codeql.swift.elements.Location import codeql.swift.elements.Location
import codeql.swift.elements.Locatable import codeql.swift.elements.Locatable
class UnspecifiedElement extends Generated::UnspecifiedElement { module Impl {
override string toString() { class UnspecifiedElement extends Generated::UnspecifiedElement {
exists(string source, string index | override string toString() {
( exists(string source, string index |
source = " from " + this.getParent().getPrimaryQlClasses() (
or source = " from " + this.getParent().getPrimaryQlClasses()
not this.hasParent() and source = "" or
) and not this.hasParent() and source = ""
( ) and
index = "[" + this.getIndex() + "]" (
or index = "[" + this.getIndex() + "]"
not this.hasIndex() and index = "" or
) and not this.hasIndex() and index = ""
result = "missing " + this.getProperty() + index + source ) and
) result = "missing " + this.getProperty() + index + source
} )
}
override Location getLocation() { result = this.getParent().(Locatable).getLocation() } override Location getLocation() { result = this.getParent().(Locatable).getLocation() }
}
} }

View File

@@ -1,40 +1,35 @@
private import codeql.swift.generated.decl.Accessor private import codeql.swift.generated.decl.Accessor
private import SetObserver
private predicate isKnownAccessorKind(Accessor decl, string kind) { module Impl {
decl.isGetter() and kind = "get" private predicate isKnownAccessorKind(Accessor decl, string kind) {
or decl.isGetter() and kind = "get"
decl.isSetter() and kind = "set"
or
decl.isWillSet() and kind = "willSet"
or
decl.isDidSet() and kind = "didSet"
or
decl.isRead() and kind = "_read"
or
decl.isModify() and kind = "_modify"
or
decl.isUnsafeAddress() and kind = "unsafeAddress"
or
decl.isUnsafeMutableAddress() and kind = "unsafeMutableAddress"
}
class Accessor extends Generated::Accessor {
predicate isPropertyObserver() {
this instanceof WillSetObserver or this instanceof DidSetObserver
}
override string toString() {
isKnownAccessorKind(this, result)
or or
not isKnownAccessorKind(this, _) and decl.isSetter() and kind = "set"
result = super.toString() or
decl.isWillSet() and kind = "willSet"
or
decl.isDidSet() and kind = "didSet"
or
decl.isRead() and kind = "_read"
or
decl.isModify() and kind = "_modify"
or
decl.isUnsafeAddress() and kind = "unsafeAddress"
or
decl.isUnsafeMutableAddress() and kind = "unsafeMutableAddress"
}
class Accessor extends Generated::Accessor {
predicate isPropertyObserver() {
this instanceof WillSetObserver or this instanceof DidSetObserver
}
override string toString() {
isKnownAccessorKind(this, result)
or
not isKnownAccessorKind(this, _) and
result = super.toString()
}
} }
} }
class WillSetObserver extends Accessor {
WillSetObserver() { this.isWillSet() }
}
class DidSetObserver extends Accessor {
DidSetObserver() { this.isDidSet() }
}

View File

@@ -2,22 +2,24 @@ private import codeql.swift.generated.decl.CapturedDecl
private import codeql.swift.elements.Callable private import codeql.swift.elements.Callable
private import codeql.swift.elements.expr.DeclRefExpr private import codeql.swift.elements.expr.DeclRefExpr
/** module Impl {
* A captured variable or function parameter in the scope of a closure.
*/
class CapturedDecl extends Generated::CapturedDecl {
override string toString() { result = this.getDecl().toString() }
/** /**
* Gets the closure or function that captures this variable. * A captured variable or function parameter in the scope of a closure.
*/ */
Callable getScope() { result.getACapture() = this } class CapturedDecl extends Generated::CapturedDecl {
override string toString() { result = this.getDecl().toString() }
/** /**
* Get an access to this capture within the scope of its closure. * Gets the closure or function that captures this variable.
*/ */
DeclRefExpr getAnAccess() { Callable getScope() { result.getACapture() = this }
result.getEnclosingCallable() = this.getScope() and
result.getDecl() = this.getDecl() /**
* Get an access to this capture within the scope of its closure.
*/
DeclRefExpr getAnAccess() {
result.getEnclosingCallable() = this.getScope() and
result.getDecl() = this.getDecl()
}
} }
} }

View File

@@ -2,21 +2,23 @@ private import codeql.swift.generated.decl.Decl
private import codeql.swift.elements.decl.NominalTypeDecl private import codeql.swift.elements.decl.NominalTypeDecl
private import codeql.swift.elements.decl.ExtensionDecl private import codeql.swift.elements.decl.ExtensionDecl
class Decl extends Generated::Decl { module Impl {
override string toString() { result = super.toString() } class Decl extends Generated::Decl {
override string toString() { result = super.toString() }
/** /**
* Gets the `NominalTypeDecl` corresponding to this `Decl`, if any. This * Gets the `NominalTypeDecl` corresponding to this `Decl`, if any. This
* resolves an `ExtensionDecl` to the `NominalTypeDecl` that it extends. * resolves an `ExtensionDecl` to the `NominalTypeDecl` that it extends.
*/ */
NominalTypeDecl asNominalTypeDecl() { NominalTypeDecl asNominalTypeDecl() {
result = this result = this
or or
result = this.(ExtensionDecl).getExtendedTypeDecl() result = this.(ExtensionDecl).getExtendedTypeDecl()
}
/**
* Gets the declaration that declares this declaration as a member, if any.
*/
Decl getDeclaringDecl() { this = result.getAMember() }
} }
/**
* Gets the declaration that declares this declaration as a member, if any.
*/
Decl getDeclaringDecl() { this = result.getAMember() }
} }

View File

@@ -1,9 +1,11 @@
private import codeql.swift.generated.decl.Deinitializer private import codeql.swift.generated.decl.Deinitializer
private import codeql.swift.elements.decl.Method private import codeql.swift.elements.decl.Method
/** module Impl {
* A deinitializer of a class. /**
*/ * A deinitializer of a class.
class Deinitializer extends Generated::Deinitializer, Method { */
override string toString() { result = this.getSelfParam().getType() + "." + super.toString() } class Deinitializer extends Generated::Deinitializer {
override string toString() { result = this.getSelfParam().getType() + "." + super.toString() }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.decl.EnumCaseDecl private import codeql.swift.generated.decl.EnumCaseDecl
class EnumCaseDecl extends Generated::EnumCaseDecl { module Impl {
override string toString() { result = "case ..." } class EnumCaseDecl extends Generated::EnumCaseDecl {
override string toString() { result = "case ..." }
}
} }

View File

@@ -3,34 +3,36 @@ private import codeql.swift.elements.decl.EnumCaseDecl
private import codeql.swift.elements.decl.EnumElementDecl private import codeql.swift.elements.decl.EnumElementDecl
private import codeql.swift.elements.decl.Decl private import codeql.swift.elements.decl.Decl
/** module Impl {
* An enumeration declaration, for example:
* ```
* enum MyColours {
* case red
* case green
* case blue
* }
* ```
*/
class EnumDecl extends Generated::EnumDecl {
/** /**
* Gets the `index`th enumeration element of this enumeration (0-based). * An enumeration declaration, for example:
* ```
* enum MyColours {
* case red
* case green
* case blue
* }
* ```
*/ */
final EnumElementDecl getEnumElement(int index) { class EnumDecl extends Generated::EnumDecl {
result = /**
rank[index + 1](int memberIndex, Decl d | * Gets the `index`th enumeration element of this enumeration (0-based).
d = this.getMember(memberIndex) and */
d instanceof EnumElementDecl final EnumElementDecl getEnumElement(int index) {
| result =
d order by memberIndex rank[index + 1](int memberIndex, Decl d |
) d = this.getMember(memberIndex) and
} d instanceof EnumElementDecl
|
d order by memberIndex
)
}
/** /**
* Gets an enumeration element of this enumeration. * Gets an enumeration element of this enumeration.
*/ */
final EnumElementDecl getAnEnumElement() { final EnumElementDecl getAnEnumElement() {
result = this.getMember(_).(EnumCaseDecl).getElement(_) result = this.getMember(_).(EnumCaseDecl).getElement(_)
}
} }
} }

View File

@@ -1,37 +1,39 @@
private import codeql.swift.generated.decl.EnumElementDecl private import codeql.swift.generated.decl.EnumElementDecl
private import codeql.swift.elements.decl.EnumDecl private import codeql.swift.elements.decl.EnumDecl
/** module Impl {
* An enum element declaration, for example `enumElement` and `anotherEnumElement` in:
* ```
* enum MyEnum {
* case enumElement
* case anotherEnumElement(Int)
* }
* ```
*/
class EnumElementDecl extends Generated::EnumElementDecl {
override string toString() { result = this.getName() }
/** /**
* Holds if this enum element declaration is called `enumElementName` and is a member of an * An enum element declaration, for example `enumElement` and `anotherEnumElement` in:
* enum called `enumName`. * ```
* enum MyEnum {
* case enumElement
* case anotherEnumElement(Int)
* }
* ```
*/ */
cached class EnumElementDecl extends Generated::EnumElementDecl {
predicate hasQualifiedName(string enumName, string enumElementName) { override string toString() { result = this.getName() }
this.getName() = enumElementName and
exists(EnumDecl d |
d.getFullName() = enumName and
d.getAMember() = this
)
}
/** /**
* Holds if this enum element declaration is called `enumElementName` and is a member of an * Holds if this enum element declaration is called `enumElementName` and is a member of an
* enumcalled `enumName` in a module called `moduleName`. * enum called `enumName`.
*/ */
predicate hasQualifiedName(string moduleName, string enumName, string enumElementName) { cached
this.hasQualifiedName(enumName, enumElementName) and predicate hasQualifiedName(string enumName, string enumElementName) {
this.getModule().getFullName() = moduleName this.getName() = enumElementName and
exists(EnumDecl d |
d.getFullName() = enumName and
d.getAMember() = this
)
}
/**
* Holds if this enum element declaration is called `enumElementName` and is a member of an
* enumcalled `enumName` in a module called `moduleName`.
*/
predicate hasQualifiedName(string moduleName, string enumName, string enumElementName) {
this.hasQualifiedName(enumName, enumElementName) and
this.getModule().getFullName() = moduleName
}
} }
} }

View File

@@ -1,11 +1,13 @@
private import codeql.swift.generated.decl.ExtensionDecl private import codeql.swift.generated.decl.ExtensionDecl
class ExtensionDecl extends Generated::ExtensionDecl { module Impl {
override string toString() { class ExtensionDecl extends Generated::ExtensionDecl {
result = override string toString() {
"extension of " + unique(NominalTypeDecl td | td = this.getExtendedTypeDecl()).toString() result =
or "extension of " + unique(NominalTypeDecl td | td = this.getExtendedTypeDecl()).toString()
count(this.getExtendedTypeDecl()) != 1 and or
result = "extension" count(this.getExtendedTypeDecl()) != 1 and
result = "extension"
}
} }
} }

View File

@@ -0,0 +1,32 @@
private import VarDecl
/**
* A field declaration. That is, a variable declaration that is a member of a
* class, struct, enum or protocol.
*/
final class FieldDecl extends VarDecl {
FieldDecl() { this = any(Decl ctx).getAMember() }
/**
* Holds if this field is called `fieldName` and is a member of a
* class, struct, extension, enum or protocol called `typeName`.
*/
cached
predicate hasQualifiedName(string typeName, string fieldName) {
this.getName() = fieldName and
exists(Decl d |
d.asNominalTypeDecl().getFullName() = typeName and
d.getAMember() = this
)
}
/**
* Holds if this field is called `fieldName` and is a member of a
* class, struct, extension, enum or protocol called `typeName` in a module
* called `moduleName`.
*/
predicate hasQualifiedName(string moduleName, string typeName, string fieldName) {
this.hasQualifiedName(typeName, fieldName) and
this.getModule().getFullName() = moduleName
}
}

View File

@@ -0,0 +1,9 @@
private import Function
private import Method
/**
* A free (non-member) function.
*/
final class FreeFunction extends Function {
FreeFunction() { not this instanceof Method }
}

View File

@@ -1,26 +1,28 @@
private import codeql.swift.generated.decl.Function private import codeql.swift.generated.decl.Function
private import codeql.swift.elements.decl.Method private import codeql.swift.elements.decl.Method
/** module Impl {
* A function. /**
*/ * A function.
class Function extends Generated::Function, Callable { */
override string toString() { result = this.getName() } class Function extends Generated::Function {
override string toString() { result = this.getName() }
/**
* Gets the name of this function, without the argument list. For example
* a function with name `myFunction(arg:)` has short name `myFunction`.
*/
string getShortName() {
// match as many characters as possible that are not `(`.
// (`*+` is possessive matching)
result = this.getName().regexpCapture("([^(]*+).*", 1)
}
}
/** /**
* Gets the name of this function, without the argument list. For example * A free (non-member) function.
* a function with name `myFunction(arg:)` has short name `myFunction`.
*/ */
string getShortName() { class FreeFunction extends Function {
// match as many characters as possible that are not `(`. FreeFunction() { not this instanceof Method }
// (`*+` is possessive matching)
result = this.getName().regexpCapture("([^(]*+).*", 1)
} }
} }
/**
* A free (non-member) function.
*/
class FreeFunction extends Function {
FreeFunction() { not this instanceof Method }
}

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.decl.IfConfigDecl private import codeql.swift.generated.decl.IfConfigDecl
class IfConfigDecl extends Generated::IfConfigDecl { module Impl {
override string toString() { result = "#if ..." } class IfConfigDecl extends Generated::IfConfigDecl {
override string toString() { result = "#if ..." }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.decl.ImportDecl private import codeql.swift.generated.decl.ImportDecl
class ImportDecl extends Generated::ImportDecl { module Impl {
override string toString() { result = "import ..." } class ImportDecl extends Generated::ImportDecl {
override string toString() { result = "import ..." }
}
} }

View File

@@ -1,17 +1,20 @@
private import codeql.swift.generated.decl.Initializer private import codeql.swift.generated.decl.Initializer
private import codeql.swift.elements.decl.Method private import codeql.swift.elements.decl.Method
private import codeql.swift.elements.decl.MethodImpl::Impl as MethodImpl
private import codeql.swift.elements.type.FunctionType private import codeql.swift.elements.type.FunctionType
private import codeql.swift.elements.type.OptionalType private import codeql.swift.elements.type.OptionalType
/** module Impl {
* An initializer of a class, struct, enum or protocol. /**
*/ * An initializer of a class, struct, enum or protocol.
class Initializer extends Generated::Initializer, Method { */
override string toString() { result = this.getSelfParam().getType() + "." + super.toString() } class Initializer extends Generated::Initializer, MethodImpl::Method {
override string toString() { result = this.getSelfParam().getType() + "." + super.toString() }
/** Holds if this initializer returns an optional type. Failable initializers are written as `init?`. */ /** Holds if this initializer returns an optional type. Failable initializers are written as `init?`. */
predicate isFailable() { predicate isFailable() {
this.getInterfaceType().(FunctionType).getResult().(FunctionType).getResult() instanceof this.getInterfaceType().(FunctionType).getResult().(FunctionType).getResult() instanceof
OptionalType OptionalType
}
} }
} }

View File

@@ -1,60 +1,3 @@
private import swift private import MethodImpl
private Decl getAMember(Decl ctx) { final class Method = Impl::Method;
ctx.getAMember() = result
or
exists(VarDecl var |
ctx.getAMember() = var and
var.getAnAccessor() = result
)
}
/**
* A function that is a member of a class, struct, enum or protocol.
*/
final class Method extends Function {
Method() {
this = getAMember(any(ClassDecl c))
or
this = getAMember(any(StructDecl c))
or
this = getAMember(any(ExtensionDecl c))
or
this = getAMember(any(EnumDecl c))
or
this = getAMember(any(ProtocolDecl c))
}
/**
* Holds if this function is called `funcName` and is a member of a
* class, struct, extension, enum or protocol called `typeName`.
*/
cached
predicate hasQualifiedName(string typeName, string funcName) {
this.getName() = funcName and
exists(Decl d |
d.asNominalTypeDecl().getFullName() = typeName and
d.getAMember() = this
)
}
/**
* Holds if this function is called `funcName` and is a member of a
* class, struct, extension, enum or protocol called `typeName` in a module
* called `moduleName`.
*/
predicate hasQualifiedName(string moduleName, string typeName, string funcName) {
this.hasQualifiedName(typeName, funcName) and
this.getModule().getFullName() = moduleName
}
/**
* Holds if this function is a `static` or `class` method, as opposed to an instance method.
*/
predicate isStaticOrClassMethod() { this.getSelfParam().getType() instanceof MetatypeType }
/**
* Holds if this function is an instance method, as opposed to a `static` or `class` method.
*/
predicate isInstanceMethod() { not this.isStaticOrClassMethod() }
}

View File

@@ -0,0 +1,63 @@
private import swift
private import codeql.swift.elements.decl.FunctionImpl::Impl as FunctionImpl
module Impl {
private Decl getAMember(Decl ctx) {
ctx.getAMember() = result
or
exists(VarDecl var |
ctx.getAMember() = var and
var.getAnAccessor() = result
)
}
/**
* A function that is a member of a class, struct, enum or protocol.
*/
class Method extends FunctionImpl::Function {
Method() {
this = getAMember(any(ClassDecl c))
or
this = getAMember(any(StructDecl c))
or
this = getAMember(any(ExtensionDecl c))
or
this = getAMember(any(EnumDecl c))
or
this = getAMember(any(ProtocolDecl c))
}
/**
* Holds if this function is called `funcName` and is a member of a
* class, struct, extension, enum or protocol called `typeName`.
*/
cached
predicate hasQualifiedName(string typeName, string funcName) {
this.getName() = funcName and
exists(Decl d |
d.asNominalTypeDecl().getFullName() = typeName and
d.getAMember() = this
)
}
/**
* Holds if this function is called `funcName` and is a member of a
* class, struct, extension, enum or protocol called `typeName` in a module
* called `moduleName`.
*/
predicate hasQualifiedName(string moduleName, string typeName, string funcName) {
this.hasQualifiedName(typeName, funcName) and
this.getModule().getFullName() = moduleName
}
/**
* Holds if this function is a `static` or `class` method, as opposed to an instance method.
*/
predicate isStaticOrClassMethod() { this.getSelfParam().getType() instanceof MetatypeType }
/**
* Holds if this function is an instance method, as opposed to a `static` or `class` method.
*/
predicate isInstanceMethod() { not this.isStaticOrClassMethod() }
}
}

View File

@@ -1,9 +1,11 @@
private import codeql.swift.generated.decl.MissingMemberDecl private import codeql.swift.generated.decl.MissingMemberDecl
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* A placeholder for missing declarations that can arise on object deserialization. /**
*/ * A placeholder for missing declarations that can arise on object deserialization.
class MissingMemberDecl extends Generated::MissingMemberDecl { */
override string toString() { result = this.getName() + " (missing)" } class MissingMemberDecl extends Generated::MissingMemberDecl {
override string toString() { result = this.getName() + " (missing)" }
}
} }

View File

@@ -1,6 +1,8 @@
private import codeql.swift.generated.decl.NominalTypeDecl private import codeql.swift.generated.decl.NominalTypeDecl
/** module Impl {
* A class, struct, enum or protocol. /**
*/ * A class, struct, enum or protocol.
class NominalTypeDecl extends Generated::NominalTypeDecl { } */
class NominalTypeDecl extends Generated::NominalTypeDecl { }
}

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.decl.OperatorDecl private import codeql.swift.generated.decl.OperatorDecl
class OperatorDecl extends Generated::OperatorDecl { module Impl {
override string toString() { result = this.getName() } class OperatorDecl extends Generated::OperatorDecl {
override string toString() { result = this.getName() }
}
} }

View File

@@ -1,24 +1,26 @@
private import codeql.swift.generated.decl.ParamDecl private import codeql.swift.generated.decl.ParamDecl
private import codeql.swift.elements.Callable private import codeql.swift.elements.Callable
class ParamDecl extends Generated::ParamDecl { module Impl {
/** Gets the function which declares this parameter. */ class ParamDecl extends Generated::ParamDecl {
Callable getDeclaringFunction() { result.getAParam() = this } /** Gets the function which declares this parameter. */
Callable getDeclaringFunction() { result.getAParam() = this }
/** /**
* Gets the index of this parameter in its declaring function's parameter list, * Gets the index of this parameter in its declaring function's parameter list,
* or -1 if this is `self`. * or -1 if this is `self`.
*/ */
int getIndex() { exists(Callable func | func.getParam(result) = this) } int getIndex() { exists(Callable func | func.getParam(result) = this) }
} }
/** A `self` parameter. */ /** A `self` parameter. */
class SelfParamDecl extends ParamDecl { class SelfParamDecl extends ParamDecl {
Callable call; Callable call;
SelfParamDecl() { call.getSelfParam() = this } SelfParamDecl() { call.getSelfParam() = this }
override Callable getDeclaringFunction() { result = call } override Callable getDeclaringFunction() { result = call }
override int getIndex() { result = -1 } override int getIndex() { result = -1 }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.decl.PatternBindingDecl private import codeql.swift.generated.decl.PatternBindingDecl
class PatternBindingDecl extends Generated::PatternBindingDecl { module Impl {
override string toString() { result = "var ... = ..." } class PatternBindingDecl extends Generated::PatternBindingDecl {
override string toString() { result = "var ... = ..." }
}
} }

View File

@@ -1,17 +1,19 @@
private import codeql.swift.generated.decl.PoundDiagnosticDecl private import codeql.swift.generated.decl.PoundDiagnosticDecl
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* A diagnostic directive, which is either `#error` or `#warning`. /**
*/ * A diagnostic directive, which is either `#error` or `#warning`.
class PoundDiagnosticDecl extends Generated::PoundDiagnosticDecl { */
override string toString() { class PoundDiagnosticDecl extends Generated::PoundDiagnosticDecl {
this.isError() and result = "#error(...)" override string toString() {
or this.isError() and result = "#error(...)"
this.isWarning() and result = "#warning(...)" or
this.isWarning() and result = "#warning(...)"
}
predicate isError() { this.getKind() = 1 }
predicate isWarning() { this.getKind() = 2 }
} }
predicate isError() { this.getKind() = 1 }
predicate isWarning() { this.getKind() = 2 }
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.decl.PrecedenceGroupDecl private import codeql.swift.generated.decl.PrecedenceGroupDecl
class PrecedenceGroupDecl extends Generated::PrecedenceGroupDecl { module Impl {
override string toString() { result = "precedencegroup ..." } class PrecedenceGroupDecl extends Generated::PrecedenceGroupDecl {
override string toString() { result = "precedencegroup ..." }
}
} }

View File

@@ -0,0 +1,3 @@
private import ParamDeclImpl
final class SelfParamDecl = Impl::SelfParamDecl;

View File

@@ -0,0 +1,9 @@
private import Accessor
final class WillSetObserver extends Accessor {
WillSetObserver() { this.isWillSet() }
}
class DidSetObserver extends Accessor {
DidSetObserver() { this.isDidSet() }
}

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.decl.SubscriptDecl private import codeql.swift.generated.decl.SubscriptDecl
class SubscriptDecl extends Generated::SubscriptDecl { module Impl {
override string toString() { result = "subscript ..." } class SubscriptDecl extends Generated::SubscriptDecl {
override string toString() { result = "subscript ..." }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.decl.TopLevelCodeDecl private import codeql.swift.generated.decl.TopLevelCodeDecl
class TopLevelCodeDecl extends Generated::TopLevelCodeDecl { module Impl {
override string toString() { result = this.getBody().toString() } class TopLevelCodeDecl extends Generated::TopLevelCodeDecl {
override string toString() { result = this.getBody().toString() }
}
} }

View File

@@ -1,10 +1,12 @@
private import codeql.swift.generated.decl.TypeAliasDecl private import codeql.swift.generated.decl.TypeAliasDecl
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* A declaration of a type alias to another type. For example: /**
* ``` * A declaration of a type alias to another type. For example:
* typealias MyInt = Int * ```
* ``` * typealias MyInt = Int
*/ * ```
class TypeAliasDecl extends Generated::TypeAliasDecl { } */
class TypeAliasDecl extends Generated::TypeAliasDecl { }
}

View File

@@ -2,113 +2,118 @@ private import codeql.swift.generated.decl.TypeDecl
private import codeql.swift.elements.type.AnyGenericType private import codeql.swift.elements.type.AnyGenericType
private import swift private import swift
/** module Impl {
* A Swift type declaration, for example a class, struct, enum or protocol
* declaration.
*
* Type declarations are distinct from types. A type declaration represents
* the code that declares a type, for example:
* ```
* class MyClass {
* ...
* }
* ```
* Not all types have type declarations, for example built-in types do not
* have type declarations.
*/
class TypeDecl extends Generated::TypeDecl {
override string toString() { result = this.getName() }
/** /**
* Gets the `index`th base type of this type declaration (0-based). * A Swift type declaration, for example a class, struct, enum or protocol
* declaration.
* *
* This is the same as `getImmediateInheritedType`. * Type declarations are distinct from types. A type declaration represents
* DEPRECATED: either use `getImmediateInheritedType` or unindexed `getABaseType`. * the code that declares a type, for example:
*/
deprecated Type getImmediateBaseType(int index) { result = this.getImmediateInheritedType(index) }
/**
* Gets the `index`th base type of this type declaration (0-based).
* This is the same as `getInheritedType`.
* DEPRECATED: use `getInheritedType` or unindexed `getABaseType`.
*/
deprecated Type getBaseType(int index) { result = this.getInheritedType(index) }
/**
* Gets any of the base types of this type declaration. Expands protocols added in
* extensions and expands type aliases. For example in the following code, `B` has
* base type `A`:
* ``` * ```
* typealias A_alias = A * class MyClass {
* * ...
* class B : A_alias {}
* ```
*/
Type getABaseType() {
// direct base type
result = this.getAnInheritedType().getUnderlyingType()
or
// protocol added in an extension of the type
exists(ExtensionDecl ed |
ed.getExtendedTypeDecl() = this and
ed.getAProtocol().getType() = result
)
}
/**
* Gets the declaration of the `index`th base type of this type declaration (0-based).
* DEPRECATED: The index is not very meaningful here. Use `getABaseTypeDecl`.
*/
deprecated TypeDecl getBaseTypeDecl(int i) {
result = this.getBaseType(i).(AnyGenericType).getDeclaration()
}
/**
* Gets the declaration of any of the base types of this type declaration. Expands
* protocols added in extensions and expands type aliases. For example in the following
* code, `B` has base type `A`.
* ```
* typealias A_alias = A
*
* class B : A_alias {}
* ```
*/
TypeDecl getABaseTypeDecl() { result = this.getABaseType().(AnyGenericType).getDeclaration() }
/**
* Gets the declaration of any type derived from this type declaration. Expands protocols
* added in extensions and expands type aliases. For example in the following code, `B`
* is derived from `A`.
* ```
* typealias A_alias = A
*
* class B : A_alias {}
* ```
*/
TypeDecl getADerivedTypeDecl() { result.getABaseTypeDecl() = this }
/**
* Gets the full name of this `TypeDecl`. For example in:
* ```swift
* struct A {
* struct B {
* // ...
* }
* } * }
* ``` * ```
* The name and full name of `A` is `A`. The name of `B` is `B`, but the * Not all types have type declarations, for example built-in types do not
* full name of `B` is `A.B`. * have type declarations.
*/ */
cached class TypeDecl extends Generated::TypeDecl {
string getFullName() { override string toString() { result = this.getName() }
not this.getEnclosingDecl() instanceof TypeDecl and
not count(this.getEnclosingDecl().(ExtensionDecl).getExtendedTypeDecl()) = 1 and /**
result = this.getName() * Gets the `index`th base type of this type declaration (0-based).
or *
result = this.getEnclosingDecl().(TypeDecl).getFullName() + "." + this.getName() * This is the same as `getImmediateInheritedType`.
or * DEPRECATED: either use `getImmediateInheritedType` or unindexed `getABaseType`.
result = */
unique(NominalTypeDecl td | td = this.getEnclosingDecl().(ExtensionDecl).getExtendedTypeDecl()) deprecated Type getImmediateBaseType(int index) {
.getFullName() + "." + this.getName() result = this.getImmediateInheritedType(index)
}
/**
* Gets the `index`th base type of this type declaration (0-based).
* This is the same as `getInheritedType`.
* DEPRECATED: use `getInheritedType` or unindexed `getABaseType`.
*/
deprecated Type getBaseType(int index) { result = this.getInheritedType(index) }
/**
* Gets any of the base types of this type declaration. Expands protocols added in
* extensions and expands type aliases. For example in the following code, `B` has
* base type `A`:
* ```
* typealias A_alias = A
*
* class B : A_alias {}
* ```
*/
Type getABaseType() {
// direct base type
result = this.getAnInheritedType().getUnderlyingType()
or
// protocol added in an extension of the type
exists(ExtensionDecl ed |
ed.getExtendedTypeDecl() = this and
ed.getAProtocol().getType() = result
)
}
/**
* Gets the declaration of the `index`th base type of this type declaration (0-based).
* DEPRECATED: The index is not very meaningful here. Use `getABaseTypeDecl`.
*/
deprecated TypeDecl getBaseTypeDecl(int i) {
result = this.getBaseType(i).(AnyGenericType).getDeclaration()
}
/**
* Gets the declaration of any of the base types of this type declaration. Expands
* protocols added in extensions and expands type aliases. For example in the following
* code, `B` has base type `A`.
* ```
* typealias A_alias = A
*
* class B : A_alias {}
* ```
*/
TypeDecl getABaseTypeDecl() { result = this.getABaseType().(AnyGenericType).getDeclaration() }
/**
* Gets the declaration of any type derived from this type declaration. Expands protocols
* added in extensions and expands type aliases. For example in the following code, `B`
* is derived from `A`.
* ```
* typealias A_alias = A
*
* class B : A_alias {}
* ```
*/
TypeDecl getADerivedTypeDecl() { result.getABaseTypeDecl() = this }
/**
* Gets the full name of this `TypeDecl`. For example in:
* ```swift
* struct A {
* struct B {
* // ...
* }
* }
* ```
* The name and full name of `A` is `A`. The name of `B` is `B`, but the
* full name of `B` is `A.B`.
*/
cached
string getFullName() {
not this.getEnclosingDecl() instanceof TypeDecl and
not count(this.getEnclosingDecl().(ExtensionDecl).getExtendedTypeDecl()) = 1 and
result = this.getName()
or
result = this.getEnclosingDecl().(TypeDecl).getFullName() + "." + this.getName()
or
result =
unique(NominalTypeDecl td |
td = this.getEnclosingDecl().(ExtensionDecl).getExtendedTypeDecl()
).getFullName() + "." + this.getName()
}
} }
} }

View File

@@ -2,22 +2,24 @@ private import codeql.swift.generated.decl.ValueDecl
private import codeql.swift.elements.decl.CapturedDecl private import codeql.swift.elements.decl.CapturedDecl
private import codeql.swift.elements.expr.DeclRefExpr private import codeql.swift.elements.expr.DeclRefExpr
/** module Impl {
* A declaration that introduces a value with a type.
*/
class ValueDecl extends Generated::ValueDecl {
/** /**
* Gets a capture of this declaration in the scope of a closure. * A declaration that introduces a value with a type.
*/ */
CapturedDecl asCapturedDecl() { result.getDecl() = this } class ValueDecl extends Generated::ValueDecl {
/**
* Gets a capture of this declaration in the scope of a closure.
*/
CapturedDecl asCapturedDecl() { result.getDecl() = this }
/** /**
* Holds if this declaration is captured by a closure. * Holds if this declaration is captured by a closure.
*/ */
predicate isCaptured() { exists(this.asCapturedDecl()) } predicate isCaptured() { exists(this.asCapturedDecl()) }
/** /**
* Gets an expression that references this declaration. * Gets an expression that references this declaration.
*/ */
DeclRefExpr getAnAccess() { result.getDecl() = this } DeclRefExpr getAnAccess() { result.getDecl() = this }
}
} }

View File

@@ -1,56 +1,58 @@
private import codeql.swift.generated.decl.VarDecl private import codeql.swift.generated.decl.VarDecl
private import codeql.swift.elements.decl.Decl private import codeql.swift.elements.decl.Decl
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* A declaration of a variable such as
* * a local variable in a function:
* ```
* func foo() {
* var x = 42 // <-
* let y = "hello" // <-
* ...
* }
* ```
* * a member of a `struct` or `class`:
* ```
* struct S {
* var size : Int // <-
* }
* ```
* * ...
*/
class VarDecl extends Generated::VarDecl {
override string toString() { result = this.getName() }
}
/**
* A field declaration. That is, a variable declaration that is a member of a
* class, struct, enum or protocol.
*/
class FieldDecl extends VarDecl {
FieldDecl() { this = any(Decl ctx).getAMember() }
/** /**
* Holds if this field is called `fieldName` and is a member of a * A declaration of a variable such as
* class, struct, extension, enum or protocol called `typeName`. * * a local variable in a function:
* ```
* func foo() {
* var x = 42 // <-
* let y = "hello" // <-
* ...
* }
* ```
* * a member of a `struct` or `class`:
* ```
* struct S {
* var size : Int // <-
* }
* ```
* * ...
*/ */
cached class VarDecl extends Generated::VarDecl {
predicate hasQualifiedName(string typeName, string fieldName) { override string toString() { result = this.getName() }
this.getName() = fieldName and
exists(Decl d |
d.asNominalTypeDecl().getFullName() = typeName and
d.getAMember() = this
)
} }
/** /**
* Holds if this field is called `fieldName` and is a member of a * A field declaration. That is, a variable declaration that is a member of a
* class, struct, extension, enum or protocol called `typeName` in a module * class, struct, enum or protocol.
* called `moduleName`.
*/ */
predicate hasQualifiedName(string moduleName, string typeName, string fieldName) { class FieldDecl extends VarDecl {
this.hasQualifiedName(typeName, fieldName) and FieldDecl() { this = any(Decl ctx).getAMember() }
this.getModule().getFullName() = moduleName
/**
* Holds if this field is called `fieldName` and is a member of a
* class, struct, extension, enum or protocol called `typeName`.
*/
cached
predicate hasQualifiedName(string typeName, string fieldName) {
this.getName() = fieldName and
exists(Decl d |
d.asNominalTypeDecl().getFullName() = typeName and
d.getAMember() = this
)
}
/**
* Holds if this field is called `fieldName` and is a member of a
* class, struct, extension, enum or protocol called `typeName` in a module
* called `moduleName`.
*/
predicate hasQualifiedName(string moduleName, string typeName, string fieldName) {
this.hasQualifiedName(typeName, fieldName) and
this.getModule().getFullName() = moduleName
}
} }
} }

View File

@@ -6,54 +6,56 @@ private import codeql.swift.elements.expr.DotSyntaxBaseIgnoredExpr
private import codeql.swift.elements.expr.AutoClosureExpr private import codeql.swift.elements.expr.AutoClosureExpr
private import codeql.swift.elements.decl.Method private import codeql.swift.elements.decl.Method
class ApplyExpr extends Generated::ApplyExpr { module Impl {
Callable getStaticTarget() { result = this.getFunction().(DeclRefExpr).getDecl() } class ApplyExpr extends Generated::ApplyExpr {
Callable getStaticTarget() { result = this.getFunction().(DeclRefExpr).getDecl() }
/** Gets the method qualifier, if this is applying a method */ /** Gets the method qualifier, if this is applying a method */
Expr getQualifier() { none() } Expr getQualifier() { none() }
/** /**
* Gets the argument of this `ApplyExpr` called `label` (if any). * Gets the argument of this `ApplyExpr` called `label` (if any).
*/ */
final Argument getArgumentWithLabel(string label) { final Argument getArgumentWithLabel(string label) {
result = this.getAnArgument() and result = this.getAnArgument() and
result.getLabel() = label result.getLabel() = label
}
override string toString() {
result = "call to " + this.getStaticTarget().toString()
or
not exists(this.getStaticTarget()) and
result = "call to ..."
}
} }
override string toString() { class MethodApplyExpr extends ApplyExpr {
result = "call to " + this.getStaticTarget().toString() private MethodLookupExpr method;
or
not exists(this.getStaticTarget()) and MethodApplyExpr() { method = this.getFunction() }
result = "call to ..."
override Method getStaticTarget() { result = method.getMethod() }
override Expr getQualifier() { result = method.getBase() }
}
private class PartialDotSyntaxBaseIgnoredApplyExpr extends ApplyExpr {
private DotSyntaxBaseIgnoredExpr expr;
PartialDotSyntaxBaseIgnoredApplyExpr() { expr = this.getFunction() }
override AutoClosureExpr getStaticTarget() { result = expr.getSubExpr() }
override Expr getQualifier() { result = expr.getQualifier() }
override string toString() { result = "call to " + expr }
}
private class FullDotSyntaxBaseIgnoredApplyExpr extends ApplyExpr {
private PartialDotSyntaxBaseIgnoredApplyExpr expr;
FullDotSyntaxBaseIgnoredApplyExpr() { expr = this.getFunction() }
override AutoClosureExpr getStaticTarget() { result = expr.getStaticTarget().getExpr() }
} }
} }
class MethodApplyExpr extends ApplyExpr {
private MethodLookupExpr method;
MethodApplyExpr() { method = this.getFunction() }
override Method getStaticTarget() { result = method.getMethod() }
override Expr getQualifier() { result = method.getBase() }
}
private class PartialDotSyntaxBaseIgnoredApplyExpr extends ApplyExpr {
private DotSyntaxBaseIgnoredExpr expr;
PartialDotSyntaxBaseIgnoredApplyExpr() { expr = this.getFunction() }
override AutoClosureExpr getStaticTarget() { result = expr.getSubExpr() }
override Expr getQualifier() { result = expr.getQualifier() }
override string toString() { result = "call to " + expr }
}
private class FullDotSyntaxBaseIgnoredApplyExpr extends ApplyExpr {
private PartialDotSyntaxBaseIgnoredApplyExpr expr;
FullDotSyntaxBaseIgnoredApplyExpr() { expr = this.getFunction() }
override AutoClosureExpr getStaticTarget() { result = expr.getStaticTarget().getExpr() }
}

View File

@@ -1,10 +1,12 @@
private import codeql.swift.generated.expr.Argument private import codeql.swift.generated.expr.Argument
private import codeql.swift.elements.expr.ApplyExpr private import codeql.swift.elements.expr.ApplyExpr
class Argument extends Generated::Argument { module Impl {
override string toString() { result = this.getLabel() + ": " + this.getExpr().toString() } class Argument extends Generated::Argument {
override string toString() { result = this.getLabel() + ": " + this.getExpr().toString() }
int getIndex() { any(ApplyExpr apply).getArgument(result) = this } int getIndex() { any(ApplyExpr apply).getArgument(result) = this }
ApplyExpr getApplyExpr() { result.getAnArgument() = this } ApplyExpr getApplyExpr() { result.getAnArgument() = this }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.ArrayExpr private import codeql.swift.generated.expr.ArrayExpr
class ArrayExpr extends Generated::ArrayExpr { module Impl {
override string toString() { result = "[...]" } class ArrayExpr extends Generated::ArrayExpr {
override string toString() { result = "[...]" }
}
} }

View File

@@ -1,254 +1,233 @@
private import codeql.swift.generated.expr.AssignExpr private import codeql.swift.generated.expr.AssignExpr
private import codeql.swift.elements.expr.BinaryExpr private import codeql.swift.elements.expr.BinaryExprImpl::Impl
private import codeql.swift.elements.expr.ExprImpl::Impl as ExprImpl
/** module Impl {
* An assignment expression. For example: /**
* ``` * An assignment expression. For example:
* x = 0 * ```
* y += 1 * x = 0
* z <<= 1 * y += 1
* ``` * z <<= 1
*/ * ```
class Assignment extends Expr { */
Assignment() { abstract class Assignment extends ExprImpl::Expr {
this instanceof AssignExpr or /**
this instanceof AssignArithmeticOperationEx or * Gets the destination of this assignment. For example `x` in:
this instanceof AssignBitwiseOperationEx or * ```
this instanceof AssignPointwiseOperationEx * x = y
* ```
*/
abstract Expr getDest();
/**
* Gets the source of this assignment. For example `y` in:
* ```
* x = y
* ```
*/
abstract Expr getSource();
/**
* Holds if this assignment expression uses an overflow operator, that is,
* an operator that truncates overflow rather than reporting an error.
* ```
* x &+= y
* ```
*/
predicate hasOverflowOperator() {
this.(AssignOperation).getOperator().getName() =
["&*=(_:_:)", "&+=(_:_:)", "&-=(_:_:)", "&<<=(_:_:)", "&>>=(_:_:)"]
}
} }
/** /**
* Gets the destination of this assignment. For example `x` in: * A simple assignment expression using the `=` operator:
* ``` * ```
* x = y * x = 0
* ``` * ```
*/ */
Expr getDest() { class AssignExpr extends Generated::AssignExpr {
result = this.(AssignExpr).getDest() or override string toString() { result = " ... = ..." }
result = this.(AssignOperation).getLeftOperand() }
private class AssignExprAssignment extends Assignment instanceof AssignExpr {
override Expr getDest() { result = AssignExpr.super.getDest() }
override Expr getSource() { result = AssignExpr.super.getSource() }
} }
/** /**
* Gets the source of this assignment. For example `y` in: * An assignment expression apart from `=`. For example:
* ``` * ```
* x = y * x += 1
* y &= z
* ``` * ```
*/ */
Expr getSource() { abstract class AssignOperation extends Assignment, BinaryExpr {
result = this.(AssignExpr).getSource() or override Expr getDest() { result = this.getLeftOperand() }
result = this.(AssignOperation).getRightOperand()
override Expr getSource() { result = this.getRightOperand() }
} }
/** /**
* Holds if this assignment expression uses an overflow operator, that is, * An arithmetic assignment expression. For example:
* an operator that truncates overflow rather than reporting an error.
* ``` * ```
* x &+= y * x += 1
* y *= z
* ``` * ```
*/ */
predicate hasOverflowOperator() { abstract class AssignArithmeticOperation extends AssignOperation { }
this.(AssignOperation).getOperator().getName() =
["&*=(_:_:)", "&+=(_:_:)", "&-=(_:_:)", "&<<=(_:_:)", "&>>=(_:_:)"] /**
* A bitwise assignment expression. For example:
* ```
* x &= y
* z <<= 1
* ```
*/
abstract class AssignBitwiseOperation extends AssignOperation { }
/**
* A pointwise assignment expression. For example:
* ```
* x .&= y
* ```
*/
abstract class AssignPointwiseOperation extends AssignOperation { }
/**
* An addition assignment expression:
* ```
* a += b
* a &+= b
* ```
*/
class AssignAddExpr extends AssignArithmeticOperation {
AssignAddExpr() { this.getOperator().getName() = ["+=(_:_:)", "&+=(_:_:)"] }
}
/**
* A subtraction assignment expression:
* ```
* a -= b
* a &-= b
* ```
*/
class AssignSubExpr extends AssignArithmeticOperation {
AssignSubExpr() { this.getOperator().getName() = ["-=(_:_:)", "&-=(_:_:)"] }
}
/**
* A multiplication assignment expression:
* ```
* a *= b
* a &*= b
* ```
*/
class AssignMulExpr extends AssignArithmeticOperation {
AssignMulExpr() { this.getOperator().getName() = ["*=(_:_:)", "&*=(_:_:)"] }
}
/**
* A division assignment expression:
* ```
* a /= b
* ```
*/
class AssignDivExpr extends AssignArithmeticOperation {
AssignDivExpr() { this.getOperator().getName() = "/=(_:_:)" }
}
/**
* A remainder assignment expression:
* ```
* a %= b
* ```
*/
class AssignRemExpr extends AssignArithmeticOperation {
AssignRemExpr() { this.getOperator().getName() = "%=(_:_:)" }
}
/**
* A left-shift assignment expression:
* ```
* a <<= b
* a &<<= b
* ```
*/
class AssignLShiftExpr extends AssignBitwiseOperation {
AssignLShiftExpr() { this.getOperator().getName() = ["<<=(_:_:)", "&<<=(_:_:)"] }
}
/**
* A right-shift assignment expression:
* ```
* a >>= b
* a &>>= b
* ```
*/
class AssignRShiftExpr extends AssignBitwiseOperation {
AssignRShiftExpr() { this.getOperator().getName() = [">>=(_:_:)", "&>>=(_:_:)"] }
}
/**
* A bitwise-and assignment expression:
* ```
* a &= b
* ```
*/
class AssignAndExpr extends AssignBitwiseOperation {
AssignAndExpr() { this.getOperator().getName() = "&=(_:_:)" }
}
/**
* A bitwise-or assignment expression:
* ```
* a |= b
* ```
*/
class AssignOrExpr extends AssignBitwiseOperation {
AssignOrExpr() { this.getOperator().getName() = "|=(_:_:)" }
}
/**
* A bitwise exclusive-or assignment expression:
* ```
* a ^= b
* ```
*/
class AssignXorExpr extends AssignBitwiseOperation {
AssignXorExpr() { this.getOperator().getName() = "^=(_:_:)" }
}
/**
* A pointwise bitwise-and assignment expression:
* ```
* a .&= b
* ```
*/
class AssignPointwiseAndExpr extends AssignPointwiseOperation {
AssignPointwiseAndExpr() { this.getOperator().getName() = ".&=(_:_:)" }
}
/**
* A pointwise bitwise-or assignment expression:
* ```
* a .|= b
* ```
*/
class AssignPointwiseOrExpr extends AssignPointwiseOperation {
AssignPointwiseOrExpr() { this.getOperator().getName() = ".|=(_:_:)" }
}
/**
* A pointwise bitwise exclusive-or assignment expression:
* ```
* a .^= b
* ```
*/
class AssignPointwiseXorExpr extends AssignPointwiseOperation {
AssignPointwiseXorExpr() { this.getOperator().getName() = ".^=(_:_:)" }
} }
} }
/**
* A simple assignment expression using the `=` operator:
* ```
* x = 0
* ```
*/
class AssignExpr extends Generated::AssignExpr {
override string toString() { result = " ... = ..." }
}
/**
* An assignment expression apart from `=`. For example:
* ```
* x += 1
* y &= z
* ```
*/
class AssignOperation extends Assignment, BinaryExpr {
AssignOperation() {
this instanceof AssignArithmeticOperationEx or
this instanceof AssignBitwiseOperationEx or
this instanceof AssignPointwiseOperationEx
}
}
/**
* An arithmetic assignment expression. For example:
* ```
* x += 1
* y *= z
* ```
*/
class AssignArithmeticOperation extends AssignOperation instanceof AssignArithmeticOperationEx { }
/**
* Private abstract class, extended to define the scope of `AssignArithmeticOperation`.
*/
abstract private class AssignArithmeticOperationEx extends BinaryExpr { }
/**
* A bitwise assignment expression. For example:
* ```
* x &= y
* z <<= 1
* ```
*/
class AssignBitwiseOperation extends AssignOperation instanceof AssignBitwiseOperationEx { }
/**
* Private abstract class, extended to define the scope of `AssignBitwiseOperation`.
*/
abstract private class AssignBitwiseOperationEx extends BinaryExpr { }
/**
* A pointwise assignment expression. For example:
* ```
* x .&= y
* ```
*/
class AssignPointwiseOperation extends AssignOperation instanceof AssignPointwiseOperationEx { }
/**
* Private abstract class, extended to define the scope of `AssignPointwiseOperation`.
*/
abstract private class AssignPointwiseOperationEx extends BinaryExpr { }
/**
* An addition assignment expression:
* ```
* a += b
* a &+= b
* ```
*/
class AssignAddExpr extends AssignArithmeticOperationEx {
AssignAddExpr() { this.getOperator().getName() = ["+=(_:_:)", "&+=(_:_:)"] }
}
/**
* A subtraction assignment expression:
* ```
* a -= b
* a &-= b
* ```
*/
class AssignSubExpr extends AssignArithmeticOperationEx {
AssignSubExpr() { this.getOperator().getName() = ["-=(_:_:)", "&-=(_:_:)"] }
}
/**
* A multiplication assignment expression:
* ```
* a *= b
* a &*= b
* ```
*/
class AssignMulExpr extends AssignArithmeticOperationEx {
AssignMulExpr() { this.getOperator().getName() = ["*=(_:_:)", "&*=(_:_:)"] }
}
/**
* A division assignment expression:
* ```
* a /= b
* ```
*/
class AssignDivExpr extends AssignArithmeticOperationEx {
AssignDivExpr() { this.getOperator().getName() = "/=(_:_:)" }
}
/**
* A remainder assignment expression:
* ```
* a %= b
* ```
*/
class AssignRemExpr extends AssignArithmeticOperationEx {
AssignRemExpr() { this.getOperator().getName() = "%=(_:_:)" }
}
/**
* A left-shift assignment expression:
* ```
* a <<= b
* a &<<= b
* ```
*/
class AssignLShiftExpr extends AssignBitwiseOperationEx {
AssignLShiftExpr() { this.getOperator().getName() = ["<<=(_:_:)", "&<<=(_:_:)"] }
}
/**
* A right-shift assignment expression:
* ```
* a >>= b
* a &>>= b
* ```
*/
class AssignRShiftExpr extends AssignBitwiseOperationEx {
AssignRShiftExpr() { this.getOperator().getName() = [">>=(_:_:)", "&>>=(_:_:)"] }
}
/**
* A bitwise-and assignment expression:
* ```
* a &= b
* ```
*/
class AssignAndExpr extends AssignBitwiseOperationEx {
AssignAndExpr() { this.getOperator().getName() = "&=(_:_:)" }
}
/**
* A bitwise-or assignment expression:
* ```
* a |= b
* ```
*/
class AssignOrExpr extends AssignBitwiseOperationEx {
AssignOrExpr() { this.getOperator().getName() = "|=(_:_:)" }
}
/**
* A bitwise exclusive-or assignment expression:
* ```
* a ^= b
* ```
*/
class AssignXorExpr extends AssignBitwiseOperationEx {
AssignXorExpr() { this.getOperator().getName() = "^=(_:_:)" }
}
/**
* A pointwise bitwise-and assignment expression:
* ```
* a .&= b
* ```
*/
class AssignPointwiseAndExpr extends AssignPointwiseOperationEx {
AssignPointwiseAndExpr() { this.getOperator().getName() = ".&=(_:_:)" }
}
/**
* A pointwise bitwise-or assignment expression:
* ```
* a .|= b
* ```
*/
class AssignPointwiseOrExpr extends AssignPointwiseOperationEx {
AssignPointwiseOrExpr() { this.getOperator().getName() = ".|=(_:_:)" }
}
/**
* A pointwise bitwise exclusive-or assignment expression:
* ```
* a .^= b
* ```
*/
class AssignPointwiseXorExpr extends AssignPointwiseOperationEx {
AssignPointwiseXorExpr() { this.getOperator().getName() = ".^=(_:_:)" }
}

View File

@@ -0,0 +1,37 @@
private import AssignExprImpl
final class Assignment = Impl::Assignment;
final class AssignOperation = Impl::AssignOperation;
final class AssignArithmeticOperation = Impl::AssignArithmeticOperation;
final class AssignBitwiseOperation = Impl::AssignBitwiseOperation;
final class AssignPointwiseOperation = Impl::AssignPointwiseOperation;
final class AssignAddExpr = Impl::AssignAddExpr;
final class AssignSubExpr = Impl::AssignSubExpr;
final class AssignMulExpr = Impl::AssignMulExpr;
final class AssignDivExpr = Impl::AssignDivExpr;
final class AssignRemExpr = Impl::AssignRemExpr;
final class AssignLShiftExpr = Impl::AssignLShiftExpr;
final class AssignRShiftExpr = Impl::AssignRShiftExpr;
final class AssignAndExpr = Impl::AssignAndExpr;
final class AssignOrExpr = Impl::AssignOrExpr;
final class AssignXorExpr = Impl::AssignXorExpr;
final class AssignPointwiseAndExpr = Impl::AssignPointwiseAndExpr;
final class AssignPointwiseOrExpr = Impl::AssignPointwiseOrExpr;
final class AssignPointwiseXorExpr = Impl::AssignPointwiseXorExpr;

View File

@@ -2,29 +2,31 @@ private import codeql.swift.generated.expr.AutoClosureExpr
private import codeql.swift.elements.stmt.ReturnStmt private import codeql.swift.elements.stmt.ReturnStmt
private import codeql.swift.elements.expr.Expr private import codeql.swift.elements.expr.Expr
/** module Impl {
* A Swift autoclosure expression, that is, a closure automatically generated
* around an argument when the parameter has the `@autoclosure` attribute or
* for the right-hand operand of short-circuiting logical operations. For
* example, there is an `AutoClosureExpr` around the value `0` in:
* ```
* func myFunction(_ expr: @autoclosure () -> Int) {
* ...
* }
*
* myFunction(0)
* ```
*/
class AutoClosureExpr extends Generated::AutoClosureExpr {
/** /**
* Gets the implicit return statement generated by this autoclosure expression. * A Swift autoclosure expression, that is, a closure automatically generated
* around an argument when the parameter has the `@autoclosure` attribute or
* for the right-hand operand of short-circuiting logical operations. For
* example, there is an `AutoClosureExpr` around the value `0` in:
* ```
* func myFunction(_ expr: @autoclosure () -> Int) {
* ...
* }
*
* myFunction(0)
* ```
*/ */
ReturnStmt getReturn() { result = unique( | | this.getBody().getAnElement()) } class AutoClosureExpr extends Generated::AutoClosureExpr {
/**
* Gets the implicit return statement generated by this autoclosure expression.
*/
ReturnStmt getReturn() { result = unique( | | this.getBody().getAnElement()) }
/** /**
* Gets the expression returned by this autoclosure expression. * Gets the expression returned by this autoclosure expression.
*/ */
Expr getExpr() { result = this.getReturn().getResult() } Expr getExpr() { result = this.getReturn().getResult() }
override string toString() { result = this.getBody().toString() } override string toString() { result = this.getBody().toString() }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.AwaitExpr private import codeql.swift.generated.expr.AwaitExpr
class AwaitExpr extends Generated::AwaitExpr { module Impl {
override string toString() { result = "await ..." } class AwaitExpr extends Generated::AwaitExpr {
override string toString() { result = "await ..." }
}
} }

View File

@@ -2,35 +2,37 @@ private import codeql.swift.generated.expr.BinaryExpr
private import codeql.swift.elements.expr.Expr private import codeql.swift.elements.expr.Expr
private import codeql.swift.elements.decl.Function private import codeql.swift.elements.decl.Function
/** module Impl {
* A Swift binary expression, that is, an expression that appears between its
* two operands. For example:
* ```
* x + y
* ```
*/
class BinaryExpr extends Generated::BinaryExpr {
/** /**
* Gets the left operand (left expression) of this binary expression. * A Swift binary expression, that is, an expression that appears between its
* two operands. For example:
* ```
* x + y
* ```
*/ */
Expr getLeftOperand() { result = this.getArgument(0).getExpr() } class BinaryExpr extends Generated::BinaryExpr {
/**
* Gets the left operand (left expression) of this binary expression.
*/
Expr getLeftOperand() { result = this.getArgument(0).getExpr() }
/** /**
* Gets the right operand (right expression) of this binary expression. * Gets the right operand (right expression) of this binary expression.
*/ */
Expr getRightOperand() { result = this.getArgument(1).getExpr() } Expr getRightOperand() { result = this.getArgument(1).getExpr() }
/** /**
* Gets the operator of this binary expression (the function that is called). * Gets the operator of this binary expression (the function that is called).
*/ */
Function getOperator() { result = this.getStaticTarget() } Function getOperator() { result = this.getStaticTarget() }
/** /**
* Gets an operand of this binary expression (left or right). * Gets an operand of this binary expression (left or right).
*/ */
Expr getAnOperand() { result = [this.getLeftOperand(), this.getRightOperand()] } Expr getAnOperand() { result = [this.getLeftOperand(), this.getRightOperand()] }
override string toString() { result = "... " + this.getFunction().toString() + " ..." } override string toString() { result = "... " + this.getFunction().toString() + " ..." }
override Function getStaticTarget() { result = super.getStaticTarget() } override Function getStaticTarget() { result = super.getStaticTarget() }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.BindOptionalExpr private import codeql.swift.generated.expr.BindOptionalExpr
class BindOptionalExpr extends Generated::BindOptionalExpr { module Impl {
override string toString() { result = "...?" } class BindOptionalExpr extends Generated::BindOptionalExpr {
override string toString() { result = "...?" }
}
} }

View File

@@ -1,13 +1,15 @@
private import codeql.swift.generated.expr.BooleanLiteralExpr private import codeql.swift.generated.expr.BooleanLiteralExpr
/** module Impl {
* A boolean literal. For example `true` in: /**
* ``` * A boolean literal. For example `true` in:
* let x = true * ```
* ``` * let x = true
*/ * ```
class BooleanLiteralExpr extends Generated::BooleanLiteralExpr { */
override string toString() { result = this.getValue().toString() } class BooleanLiteralExpr extends Generated::BooleanLiteralExpr {
override string toString() { result = this.getValue().toString() }
override string getValueString() { result = this.getValue().toString() } override string getValueString() { result = this.getValue().toString() }
}
} }

View File

@@ -4,12 +4,14 @@
private import codeql.swift.generated.expr.BuiltinLiteralExpr private import codeql.swift.generated.expr.BuiltinLiteralExpr
/** module Impl {
* A Swift literal of a kind that is built in to the Swift language.
*/
class BuiltinLiteralExpr extends Generated::BuiltinLiteralExpr {
/** /**
* Gets the value of this literal expression (as a string). * A Swift literal of a kind that is built in to the Swift language.
*/ */
string getValueString() { none() } class BuiltinLiteralExpr extends Generated::BuiltinLiteralExpr {
/**
* Gets the value of this literal expression (as a string).
*/
string getValueString() { none() }
}
} }

View File

@@ -1,11 +1,13 @@
private import codeql.swift.generated.expr.CaptureListExpr private import codeql.swift.generated.expr.CaptureListExpr
private import codeql.swift.elements.pattern.NamedPattern private import codeql.swift.elements.pattern.NamedPattern
class CaptureListExpr extends Generated::CaptureListExpr { module Impl {
override string toString() { result = this.getClosureBody().toString() } class CaptureListExpr extends Generated::CaptureListExpr {
override string toString() { result = this.getClosureBody().toString() }
override VarDecl getVariable(int index) { override VarDecl getVariable(int index) {
// all capture binding declarations consist of a single named pattern // all capture binding declarations consist of a single named pattern
result = this.getBindingDecl(index).getPattern(0).(NamedPattern).getVarDecl() result = this.getBindingDecl(index).getPattern(0).(NamedPattern).getVarDecl()
}
} }
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.ClosureExpr private import codeql.swift.generated.expr.ClosureExpr
class ClosureExpr extends Generated::ClosureExpr { module Impl {
override string toString() { result = "{ ... }" } class ClosureExpr extends Generated::ClosureExpr {
override string toString() { result = "{ ... }" }
}
} }

View File

@@ -1,23 +1,25 @@
private import codeql.swift.generated.expr.DeclRefExpr private import codeql.swift.generated.expr.DeclRefExpr
private import codeql.swift.elements.decl.CapturedDecl private import codeql.swift.elements.decl.CapturedDecl
/** module Impl {
* An expression that references or accesses a declaration. /**
*/ * An expression that references or accesses a declaration.
class DeclRefExpr extends Generated::DeclRefExpr { */
override string toString() { class DeclRefExpr extends Generated::DeclRefExpr {
if exists(this.getDecl().toString()) override string toString() {
then result = this.getDecl().toString() if exists(this.getDecl().toString())
else result = "(unknown declaration)" then result = this.getDecl().toString()
else result = "(unknown declaration)"
}
/**
* Gets the closure capture referenced by this expression, if any.
*/
CapturedDecl getCapturedDecl() { result.getAnAccess() = this }
/**
* Holds if this expression references a closure capture.
*/
predicate hasCapturedDecl() { exists(this.getCapturedDecl()) }
} }
/**
* Gets the closure capture referenced by this expression, if any.
*/
CapturedDecl getCapturedDecl() { result.getAnAccess() = this }
/**
* Holds if this expression references a closure capture.
*/
predicate hasCapturedDecl() { exists(this.getCapturedDecl()) }
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.DefaultArgumentExpr private import codeql.swift.generated.expr.DefaultArgumentExpr
class DefaultArgumentExpr extends Generated::DefaultArgumentExpr { module Impl {
override string toString() { result = "default " + this.getParamDecl().getName() } class DefaultArgumentExpr extends Generated::DefaultArgumentExpr {
override string toString() { result = "default " + this.getParamDecl().getName() }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.DictionaryExpr private import codeql.swift.generated.expr.DictionaryExpr
class DictionaryExpr extends Generated::DictionaryExpr { module Impl {
override string toString() { result = "[...]" } class DictionaryExpr extends Generated::DictionaryExpr {
override string toString() { result = "[...]" }
}
} }

View File

@@ -1,4 +1,6 @@
private import codeql.swift.generated.expr.DifferentiableFunctionExtractOriginalExpr private import codeql.swift.generated.expr.DifferentiableFunctionExtractOriginalExpr
class DifferentiableFunctionExtractOriginalExpr extends Generated::DifferentiableFunctionExtractOriginalExpr module Impl {
{ } class DifferentiableFunctionExtractOriginalExpr extends Generated::DifferentiableFunctionExtractOriginalExpr
{ }
}

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.DiscardAssignmentExpr private import codeql.swift.generated.expr.DiscardAssignmentExpr
class DiscardAssignmentExpr extends Generated::DiscardAssignmentExpr { module Impl {
override string toString() { result = "_" } class DiscardAssignmentExpr extends Generated::DiscardAssignmentExpr {
override string toString() { result = "_" }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.DotSelfExpr private import codeql.swift.generated.expr.DotSelfExpr
class DotSelfExpr extends Generated::DotSelfExpr { module Impl {
override string toString() { result = ".self" } class DotSelfExpr extends Generated::DotSelfExpr {
override string toString() { result = ".self" }
}
} }

View File

@@ -4,38 +4,40 @@ private import codeql.swift.elements.expr.CallExpr
private import codeql.swift.elements.expr.TypeExpr private import codeql.swift.elements.expr.TypeExpr
private import codeql.swift.elements.decl.Method private import codeql.swift.elements.decl.Method
/** module Impl {
* An expression representing a partially applied lookup of an instance property via the receiver's type object.
*
* An example is the sub-expression `SomeClass.instanceMethod` of
* `SomeClass.instanceMethod(someInstance)(arg, ...)`.
*
* Internally, the Swift compiler desugars this AST node type into a closure expression of the form
* `{ (someInstance: SomeClass) in { (arg, ...) in someInstance.instanceMethod(arg, ...) } }`,
* which in turn can be accessed using the `getSubExpr/0` predicate.
*/
class DotSyntaxBaseIgnoredExpr extends Generated::DotSyntaxBaseIgnoredExpr {
override string toString() {
result =
any(string base |
if exists(this.getQualifier().(TypeExpr).getTypeRepr().toString())
then base = this.getQualifier().(TypeExpr).getTypeRepr().toString() + "."
else base = "."
) + this.getMethod()
}
/** /**
* Gets the underlying instance method that is called when the result of this * An expression representing a partially applied lookup of an instance property via the receiver's type object.
* expression is fully applied. *
* An example is the sub-expression `SomeClass.instanceMethod` of
* `SomeClass.instanceMethod(someInstance)(arg, ...)`.
*
* Internally, the Swift compiler desugars this AST node type into a closure expression of the form
* `{ (someInstance: SomeClass) in { (arg, ...) in someInstance.instanceMethod(arg, ...) } }`,
* which in turn can be accessed using the `getSubExpr/0` predicate.
*/ */
Method getMethod() { class DotSyntaxBaseIgnoredExpr extends Generated::DotSyntaxBaseIgnoredExpr {
result = override string toString() {
this.getSubExpr() result =
.(AutoClosureExpr) any(string base |
.getExpr() if exists(this.getQualifier().(TypeExpr).getTypeRepr().toString())
.(AutoClosureExpr) then base = this.getQualifier().(TypeExpr).getTypeRepr().toString() + "."
.getExpr() else base = "."
.(CallExpr) ) + this.getMethod()
.getStaticTarget() }
/**
* Gets the underlying instance method that is called when the result of this
* expression is fully applied.
*/
Method getMethod() {
result =
this.getSubExpr()
.(AutoClosureExpr)
.getExpr()
.(AutoClosureExpr)
.getExpr()
.(CallExpr)
.getStaticTarget()
}
} }
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.DynamicMemberRefExpr private import codeql.swift.generated.expr.DynamicMemberRefExpr
class DynamicMemberRefExpr extends Generated::DynamicMemberRefExpr { module Impl {
override string toString() { result = "." + this.getMember().toString() } class DynamicMemberRefExpr extends Generated::DynamicMemberRefExpr {
override string toString() { result = "." + this.getMember().toString() }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.DynamicSubscriptExpr private import codeql.swift.generated.expr.DynamicSubscriptExpr
class DynamicSubscriptExpr extends Generated::DynamicSubscriptExpr { module Impl {
override string toString() { result = this.getMember().toString() + "[...]" } class DynamicSubscriptExpr extends Generated::DynamicSubscriptExpr {
override string toString() { result = this.getMember().toString() + "[...]" }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.DynamicTypeExpr private import codeql.swift.generated.expr.DynamicTypeExpr
class DynamicTypeExpr extends Generated::DynamicTypeExpr { module Impl {
override string toString() { result = "type(of: ...)" } class DynamicTypeExpr extends Generated::DynamicTypeExpr {
override string toString() { result = "type(of: ...)" }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.EnumIsCaseExpr private import codeql.swift.generated.expr.EnumIsCaseExpr
class EnumIsCaseExpr extends Generated::EnumIsCaseExpr { module Impl {
override string toString() { result = "... is " + this.getElement().toString() } class EnumIsCaseExpr extends Generated::EnumIsCaseExpr {
override string toString() { result = "... is " + this.getElement().toString() }
}
} }

View File

@@ -1,7 +1,9 @@
private import codeql.swift.generated.expr.ExplicitCastExpr private import codeql.swift.generated.expr.ExplicitCastExpr
class ExplicitCastExpr extends Generated::ExplicitCastExpr { module Impl {
override predicate convertsFrom(Expr e) { e = this.getImmediateSubExpr() } class ExplicitCastExpr extends Generated::ExplicitCastExpr {
override predicate convertsFrom(Expr e) { e = this.getImmediateSubExpr() }
override string toString() { result = "(" + this.getType() + ") ..." } override string toString() { result = "(" + this.getType() + ") ..." }
}
} }

View File

@@ -1,8 +1,10 @@
private import codeql.swift.generated.expr.ExplicitClosureExpr private import codeql.swift.generated.expr.ExplicitClosureExpr
/** module Impl {
* A Swift explicit closure expr, that is, a closure written using /**
* `{ ... -> ... in ... }` syntax rather than automatically generated by the * A Swift explicit closure expr, that is, a closure written using
* compiler. * `{ ... -> ... in ... }` syntax rather than automatically generated by the
*/ * compiler.
class ExplicitClosureExpr extends Generated::ExplicitClosureExpr { } */
class ExplicitClosureExpr extends Generated::ExplicitClosureExpr { }
}

View File

@@ -1,27 +1,29 @@
private import codeql.swift.generated.expr.Expr private import codeql.swift.generated.expr.Expr
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* The base class for all expressions in Swift. /**
*/ * The base class for all expressions in Swift.
class Expr extends Generated::Expr { */
final override Expr getResolveStep() { this.convertsFrom(result) } class Expr extends Generated::Expr {
final override Expr getResolveStep() { this.convertsFrom(result) }
predicate convertsFrom(Expr e) { none() } // overridden by subclasses predicate convertsFrom(Expr e) { none() } // overridden by subclasses
Expr getConversion() { result.convertsFrom(this) } Expr getConversion() { result.convertsFrom(this) }
Expr getConversion(int n) { Expr getConversion(int n) {
n = 0 and result = this.getConversion() n = 0 and result = this.getConversion()
or or
result = this.getConversion(n - 1).getConversion() result = this.getConversion(n - 1).getConversion()
}
predicate isConversion() { this.convertsFrom(_) }
predicate hasConversions() { exists(this.getConversion()) }
Expr getFullyConverted() { result = this.getFullyUnresolved() }
Expr getUnconverted() { result = this.resolve() }
} }
predicate isConversion() { this.convertsFrom(_) }
predicate hasConversions() { exists(this.getConversion()) }
Expr getFullyConverted() { result = this.getFullyUnresolved() }
Expr getUnconverted() { result = this.resolve() }
} }

View File

@@ -1,7 +1,9 @@
private import codeql.swift.generated.expr.FloatLiteralExpr private import codeql.swift.generated.expr.FloatLiteralExpr
class FloatLiteralExpr extends Generated::FloatLiteralExpr { module Impl {
override string toString() { result = this.getStringValue() } class FloatLiteralExpr extends Generated::FloatLiteralExpr {
override string toString() { result = this.getStringValue() }
override string getValueString() { result = this.getStringValue() } override string getValueString() { result = this.getStringValue() }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.ForceTryExpr private import codeql.swift.generated.expr.ForceTryExpr
class ForceTryExpr extends Generated::ForceTryExpr { module Impl {
override string toString() { result = "try! ..." } class ForceTryExpr extends Generated::ForceTryExpr {
override string toString() { result = "try! ..." }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.ForceValueExpr private import codeql.swift.generated.expr.ForceValueExpr
class ForceValueExpr extends Generated::ForceValueExpr { module Impl {
override string toString() { result = "...!" } class ForceValueExpr extends Generated::ForceValueExpr {
override string toString() { result = "...!" }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.IdentityExpr private import codeql.swift.generated.expr.IdentityExpr
class IdentityExpr extends Generated::IdentityExpr { module Impl {
override predicate convertsFrom(Expr e) { e = this.getImmediateSubExpr() } class IdentityExpr extends Generated::IdentityExpr {
override predicate convertsFrom(Expr e) { e = this.getImmediateSubExpr() }
}
} }

View File

@@ -1,13 +1,15 @@
private import codeql.swift.generated.expr.IfExpr private import codeql.swift.generated.expr.IfExpr
class IfExpr extends Generated::IfExpr { module Impl {
Expr getBranch(boolean b) { class IfExpr extends Generated::IfExpr {
b = true and Expr getBranch(boolean b) {
result = this.getThenExpr() b = true and
or result = this.getThenExpr()
b = false and or
result = this.getElseExpr() b = false and
} result = this.getElseExpr()
}
override string toString() { result = "... ? ... : ..." } override string toString() { result = "... ? ... : ..." }
}
} }

View File

@@ -1,7 +1,9 @@
private import codeql.swift.generated.expr.ImplicitConversionExpr private import codeql.swift.generated.expr.ImplicitConversionExpr
class ImplicitConversionExpr extends Generated::ImplicitConversionExpr { module Impl {
override predicate convertsFrom(Expr e) { e = this.getImmediateSubExpr() } class ImplicitConversionExpr extends Generated::ImplicitConversionExpr {
override predicate convertsFrom(Expr e) { e = this.getImmediateSubExpr() }
override string toString() { result = "(" + this.getType().toString() + ") ..." } override string toString() { result = "(" + this.getType().toString() + ") ..." }
}
} }

View File

@@ -1,7 +1,9 @@
private import codeql.swift.generated.expr.InOutExpr private import codeql.swift.generated.expr.InOutExpr
class InOutExpr extends Generated::InOutExpr { module Impl {
override string toString() { result = "&..." } class InOutExpr extends Generated::InOutExpr {
override string toString() { result = "&..." }
override predicate convertsFrom(Expr e) { e = this.getImmediateSubExpr() } override predicate convertsFrom(Expr e) { e = this.getImmediateSubExpr() }
}
} }

View File

@@ -1,13 +1,15 @@
private import codeql.swift.generated.expr.IntegerLiteralExpr private import codeql.swift.generated.expr.IntegerLiteralExpr
/** module Impl {
* An integer literal. For example `1` in: /**
* ``` * An integer literal. For example `1` in:
* let x = 1 * ```
* ``` * let x = 1
*/ * ```
class IntegerLiteralExpr extends Generated::IntegerLiteralExpr { */
override string toString() { result = this.getStringValue() } class IntegerLiteralExpr extends Generated::IntegerLiteralExpr {
override string toString() { result = this.getStringValue() }
override string getValueString() { result = this.getStringValue() } override string getValueString() { result = this.getStringValue() }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.InterpolatedStringLiteralExpr private import codeql.swift.generated.expr.InterpolatedStringLiteralExpr
class InterpolatedStringLiteralExpr extends Generated::InterpolatedStringLiteralExpr { module Impl {
override string toString() { result = "\"...\"" } class InterpolatedStringLiteralExpr extends Generated::InterpolatedStringLiteralExpr {
override string toString() { result = "\"...\"" }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.IsExpr private import codeql.swift.generated.expr.IsExpr
class IsExpr extends Generated::IsExpr { module Impl {
override string toString() { result = "... is ..." } class IsExpr extends Generated::IsExpr {
override string toString() { result = "... is ..." }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.KeyPathApplicationExpr private import codeql.swift.generated.expr.KeyPathApplicationExpr
class KeyPathApplicationExpr extends Generated::KeyPathApplicationExpr { module Impl {
override string toString() { result = "\\...[...]" } class KeyPathApplicationExpr extends Generated::KeyPathApplicationExpr {
override string toString() { result = "\\...[...]" }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.KeyPathDotExpr private import codeql.swift.generated.expr.KeyPathDotExpr
class KeyPathDotExpr extends Generated::KeyPathDotExpr { module Impl {
override string toString() { result = "\\...." } class KeyPathDotExpr extends Generated::KeyPathDotExpr {
override string toString() { result = "\\...." }
}
} }

View File

@@ -1,9 +1,11 @@
private import codeql.swift.generated.expr.KeyPathExpr private import codeql.swift.generated.expr.KeyPathExpr
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* A key-path expression. /**
*/ * A key-path expression.
class KeyPathExpr extends Generated::KeyPathExpr { */
override string toString() { result = "#keyPath(...)" } class KeyPathExpr extends Generated::KeyPathExpr {
override string toString() { result = "#keyPath(...)" }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.LazyInitializationExpr private import codeql.swift.generated.expr.LazyInitializationExpr
class LazyInitializationExpr extends Generated::LazyInitializationExpr { module Impl {
override string toString() { result = this.getSubExpr().toString() } class LazyInitializationExpr extends Generated::LazyInitializationExpr {
override string toString() { result = this.getSubExpr().toString() }
}
} }

View File

@@ -4,9 +4,11 @@
private import codeql.swift.generated.expr.LiteralExpr private import codeql.swift.generated.expr.LiteralExpr
/** module Impl {
* A Swift literal. /**
* * A Swift literal.
* This is the root class for all literals. *
*/ * This is the root class for all literals.
class LiteralExpr extends Generated::LiteralExpr { } */
class LiteralExpr extends Generated::LiteralExpr { }
}

View File

@@ -1,13 +1,15 @@
private import codeql.swift.generated.expr.MagicIdentifierLiteralExpr private import codeql.swift.generated.expr.MagicIdentifierLiteralExpr
/** module Impl {
* An identifier literal that is expanded at compile time. For example `#file` in: /**
* ``` * An identifier literal that is expanded at compile time. For example `#file` in:
* let x = #file * ```
* ``` * let x = #file
*/ * ```
class MagicIdentifierLiteralExpr extends Generated::MagicIdentifierLiteralExpr { */
override string toString() { result = "#..." } class MagicIdentifierLiteralExpr extends Generated::MagicIdentifierLiteralExpr {
override string toString() { result = "#..." }
override string getValueString() { none() } // TODO: value not yet extracted override string getValueString() { none() } // TODO: value not yet extracted
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.MakeTemporarilyEscapableExpr private import codeql.swift.generated.expr.MakeTemporarilyEscapableExpr
class MakeTemporarilyEscapableExpr extends Generated::MakeTemporarilyEscapableExpr { module Impl {
override string toString() { result = this.getSubExpr().toString() } class MakeTemporarilyEscapableExpr extends Generated::MakeTemporarilyEscapableExpr {
override string toString() { result = this.getSubExpr().toString() }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.MemberRefExpr private import codeql.swift.generated.expr.MemberRefExpr
class MemberRefExpr extends Generated::MemberRefExpr { module Impl {
override string toString() { result = "." + this.getMember().toString() } class MemberRefExpr extends Generated::MemberRefExpr {
override string toString() { result = "." + this.getMember().toString() }
}
} }

View File

@@ -0,0 +1,3 @@
private import ApplyExprImpl
final class MethodApplyExpr = Impl::MethodApplyExpr;

View File

@@ -1,4 +1,4 @@
private import ApplyExprExt private import MethodApplyExpr
private import codeql.swift.elements.expr.CallExpr private import codeql.swift.elements.expr.CallExpr
private import codeql.swift.elements.expr.ApplyExpr private import codeql.swift.elements.expr.ApplyExpr
private import codeql.swift.elements.expr.SuperRefExpr private import codeql.swift.elements.expr.SuperRefExpr

View File

@@ -7,25 +7,27 @@ private import codeql.swift.elements.decl.Method
private import codeql.swift.generated.Raw private import codeql.swift.generated.Raw
private import codeql.swift.generated.Synth private import codeql.swift.generated.Synth
class MethodLookupExpr extends Generated::MethodLookupExpr { module Impl {
override string toString() { result = "." + this.getMember().toString() } class MethodLookupExpr extends Generated::MethodLookupExpr {
override string toString() { result = "." + this.getMember().toString() }
override Expr getImmediateBase() { override Expr getImmediateBase() {
result = Synth::convertExprFromRaw(this.getUnderlying().getBase()) result = Synth::convertExprFromRaw(this.getUnderlying().getBase())
}
override Decl getMember() {
result = this.getMethodRef().(DeclRefExpr).getDecl()
or
result = this.getMethodRef().(OtherInitializerRefExpr).getInitializer()
}
override Expr getImmediateMethodRef() {
result = Synth::convertExprFromRaw(this.getUnderlying().getFunction())
}
Method getMethod() { result = this.getMember() }
cached
private Raw::SelfApplyExpr getUnderlying() { this = Synth::TMethodLookupExpr(result) }
} }
override Decl getMember() {
result = this.getMethodRef().(DeclRefExpr).getDecl()
or
result = this.getMethodRef().(OtherInitializerRefExpr).getInitializer()
}
override Expr getImmediateMethodRef() {
result = Synth::convertExprFromRaw(this.getUnderlying().getFunction())
}
Method getMethod() { result = this.getMember() }
cached
private Raw::SelfApplyExpr getUnderlying() { this = Synth::TMethodLookupExpr(result) }
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.NilLiteralExpr private import codeql.swift.generated.expr.NilLiteralExpr
class NilLiteralExpr extends Generated::NilLiteralExpr { module Impl {
override string toString() { result = "nil" } class NilLiteralExpr extends Generated::NilLiteralExpr {
override string toString() { result = "nil" }
}
} }

View File

@@ -1,5 +1,7 @@
private import codeql.swift.generated.expr.ObjCSelectorExpr private import codeql.swift.generated.expr.ObjCSelectorExpr
class ObjCSelectorExpr extends Generated::ObjCSelectorExpr { module Impl {
override string toString() { result = "#selector(...)" } class ObjCSelectorExpr extends Generated::ObjCSelectorExpr {
override string toString() { result = "#selector(...)" }
}
} }

View File

@@ -1,25 +1,27 @@
private import codeql.swift.generated.expr.ObjectLiteralExpr private import codeql.swift.generated.expr.ObjectLiteralExpr
// the following QLdoc is generated: if you need to edit it, do it in the schema file module Impl {
/** // the following QLdoc is generated: if you need to edit it, do it in the schema file
* An instance of `#fileLiteral`, `#imageLiteral` or `#colorLiteral` expressions, which are used in playgrounds. /**
*/ * An instance of `#fileLiteral`, `#imageLiteral` or `#colorLiteral` expressions, which are used in playgrounds.
class ObjectLiteralExpr extends Generated::ObjectLiteralExpr { } */
class ObjectLiteralExpr extends Generated::ObjectLiteralExpr { }
class FileLiteralExpr extends ObjectLiteralExpr { class FileLiteralExpr extends ObjectLiteralExpr {
FileLiteralExpr() { this.getKind() = 0 } FileLiteralExpr() { this.getKind() = 0 }
override string toString() { result = "#fileLiteral(...)" } override string toString() { result = "#fileLiteral(...)" }
} }
class ImageLiteralExpr extends ObjectLiteralExpr { class ImageLiteralExpr extends ObjectLiteralExpr {
ImageLiteralExpr() { this.getKind() = 1 } ImageLiteralExpr() { this.getKind() = 1 }
override string toString() { result = "#imageLiteral(...)" } override string toString() { result = "#imageLiteral(...)" }
} }
class ColorLiteralExpr extends ObjectLiteralExpr { class ColorLiteralExpr extends ObjectLiteralExpr {
ColorLiteralExpr() { this.getKind() = 2 } ColorLiteralExpr() { this.getKind() = 2 }
override string toString() { result = "#colorLiteral(...)" } override string toString() { result = "#colorLiteral(...)" }
}
} }

Some files were not shown because too many files have changed in this diff Show More