Swift: fixes responding to comments

This commit is contained in:
Nora Dimitrijević
2023-02-15 15:57:02 +01:00
parent 052a008926
commit 9353549629
4 changed files with 48 additions and 26 deletions

View File

@@ -563,7 +563,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
exists(EnumElementExpr enum, int pos |
node1.asExpr() = enum.getArgument(pos).getExpr() and
node2.asExpr() = enum and
c.isSingleton(any(Content::EnumContent ec | ec.getField() = enum.getElement().getParam(pos)))
c.isSingleton(any(Content::EnumContent ec | ec.getParam() = enum.getElement().getParam(pos)))
)
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2)
@@ -588,14 +588,14 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
)
or
// read of an enum member via `case let .variant(v1, v2)` pattern matching
exists(Expr enumExpr, ParamDecl enumField, VarDecl boundVar |
exists(Expr enumExpr, ParamDecl enumParam, VarDecl boundVar |
node1.asExpr() = enumExpr and
node2.asDefinition().getSourceVariable() = boundVar and
c.isSingleton(any(Content::EnumContent ec | ec.getField() = enumField))
c.isSingleton(any(Content::EnumContent ec | ec.getParam() = enumParam))
|
exists(EnumElementPattern enumPat, NamedPattern namePat, int idx |
enumPat.getMatchingExpr() = enumExpr and
enumPat.getElement().getParam(idx) = enumField and
enumPat.getElement().getParam(idx) = enumParam and
namePat.getIdentityPreservingEnclosingPattern*() = enumPat.getSubPattern(idx) and
namePat.getVarDecl() = boundVar
)

View File

@@ -172,17 +172,17 @@ module Content {
override string toString() { result = "Tuple element at index " + index.toString() }
}
/** A field of an enum element. */
/** A parameter of an enum element. */
class EnumContent extends Content, TEnumContent {
private ParamDecl f;
private ParamDecl p;
EnumContent() { this = TEnumContent(f) }
EnumContent() { this = TEnumContent(p) }
/** Gets the declaration of the enum field. */
ParamDecl getField() { result = f }
/** Gets the declaration of the enum parameter. */
ParamDecl getParam() { result = p }
override string toString() {
exists(EnumElementDecl d, int pos | d.getParam(pos) = f | result = d.toString() + ":" + pos)
exists(EnumElementDecl d, int pos | d.getParam(pos) = p | result = d.toString() + ":" + pos)
}
}
}

View File

@@ -8,14 +8,19 @@ private import codeql.swift.elements.decl.EnumElementDecl
/**
* An expression that constructs a case of an enum.
*/
abstract class EnumElementExpr extends Expr {
class EnumElementExpr extends Expr {
EnumElementDecl decl;
EnumElementExpr() {
this.(NullaryEnumElementExpr).getElement() = decl or
this.(NonNullaryEnumElementExpr).getElement() = decl
}
/** Gets the declaration of the enum element that this expression creates. */
EnumElementDecl getElement() { result = decl }
/** Gets the `i`th argument passed to this enum element expression (0-based). */
Argument getArgument(int i) { none() }
Argument getArgument(int i) { result = this.(NonNullaryEnumElementExpr).getArgument(i) }
/** Gets an argument passed to this enum element expression, if any. */
final Argument getAnArgument() { result = this.getArgument(_) }
@@ -24,23 +29,28 @@ abstract class EnumElementExpr extends Expr {
final int getNumberOfArguments() { result = count(this.getArgument(_)) }
}
/**
* An expression that refers to an enum element, either directly in the case of a nullary enum element,
* or referring to the enum element constructor in the case of a non-nullary enum element.
*/
private class EnumElementLookupExpr extends MethodLookupExpr {
EnumElementLookupExpr() { this.getMember() instanceof EnumElementDecl }
}
private class NullaryEnumElementExpr extends EnumElementExpr instanceof EnumElementLookupExpr {
NullaryEnumElementExpr() {
this.getMember() = decl and not exists(CallExpr ce | ce.getFunction() = this)
}
/** An expression creating an enum with no arguments */
private class NullaryEnumElementExpr extends EnumElementLookupExpr {
/** Gets the declaration of the enum element that this expression creates. */
EnumElementDecl getElement() { this.getMember() = result }
NullaryEnumElementExpr() { not exists(CallExpr ce | ce.getFunction() = this) }
}
private class NonNullaryEnumElementExpr extends EnumElementExpr instanceof CallExpr {
NonNullaryEnumElementExpr() {
exists(EnumElementLookupExpr eele |
this.getFunction() = eele and
eele.getMember() = decl
)
}
/** An expression creating an enum with arguments */
private class NonNullaryEnumElementExpr extends CallExpr {
EnumElementLookupExpr eele;
override Argument getArgument(int i) { result = CallExpr.super.getArgument(i) }
/** Gets the declaration of the enum element that this expression creates. */
EnumElementDecl getElement() { eele.getMember() = result }
NonNullaryEnumElementExpr() { this.getFunction() = eele }
}

View File

@@ -1,11 +1,23 @@
private import codeql.swift.generated.pattern.NamedPattern
private import codeql.swift.elements.decl.VarDecl
/**
* A pattern that corresponds to a fresh variable binding.
*
* For example, `x` as in `if case let .some(x) = ...` is a `NamedPattern`,
* whereas `y` as in `if case .some(y) = ...` is instead an `ExprPattern`.
*/
class NamedPattern extends Generated::NamedPattern {
/** Holds if this named pattern has a corresponding `VarDecl` */
/**
* Holds if this named pattern has a corresponding `VarDecl`.
* This will be the case as long as the variable is subsequently used.
*/
predicate hasVarDecl() { exists(this.getVarDecl()) }
/** Gets the `VarDecl` bound by this named pattern, if any. */
/**
* Gets the `VarDecl` bound by this named pattern, if any.
* This will be the case as long as the variable is subsequently used.
*/
VarDecl getVarDecl() {
this.getEnclosingPattern*() = result.getParentPattern().getFullyUnresolved() and
result.getName() = this.getName()