Swift: Introduce EnumElmentDecl.hasQualifiedName and use it to clean up the code.

This commit is contained in:
Geoffrey White
2023-07-11 18:13:46 +01:00
parent 5f8f1b64c6
commit 5c6b8bd36e
3 changed files with 43 additions and 6 deletions

View File

@@ -1,5 +1,38 @@
private import codeql.swift.generated.decl.EnumElementDecl
private import codeql.swift.elements.decl.Decl
/**
* 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 function is called `funcName` and is a member of a
* class, struct, extension, enum or protocol called `typeName`.
*/
cached
predicate hasQualifiedName(string typeName, string enumElementName) {
this.getName() = enumElementName 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 enumElementName) {
this.hasQualifiedName(typeName, enumElementName) and
this.getModule().getFullName() = moduleName
}
}

View File

@@ -10,7 +10,14 @@ private import codeql.swift.elements.expr.MethodLookupExpr
private import codeql.swift.elements.decl.EnumElementDecl
/**
* An expression that constructs a case of an enum.
* An expression that references a case of an enum. For example both `enumElement` in:
* ```
* let value = MyEnum.enumElement
* ...
* switch (anotherValue) {
* case .enumElement:
* ...
* ```
*/
class EnumElementExpr extends Expr {
EnumElementDecl decl;

View File

@@ -53,12 +53,9 @@ private class GlobalVariablePathInjectionSink extends PathInjectionSink {
private class EnumConstructorPathInjectionSink extends PathInjectionSink {
EnumConstructorPathInjectionSink() {
// first argument to `Connection.Location.uri(_:parameters:)`
exists(ApplyExpr ae, EnumElementDecl decl, NominalTypeDecl parent |
exists(ApplyExpr ae, EnumElementDecl decl |
ae.getFunction().(MethodLookupExpr).getMember() = decl and
decl.getName() = "uri" and
decl.getDeclaringDecl() = parent and
parent.getName() = "Location" and
parent.getDeclaringDecl().(NominalTypeDecl).(NominalTypeDecl).getName() = "Connection" and
decl.hasQualifiedName("Connection.Location", "uri") and
this.asExpr() = ae.getArgument(0).getExpr()
)
}