Skip to content

Commit b24a27d

Browse files
committed
Swift: Add hasQualifiedName methods and tests.
1 parent 643cfce commit b24a27d

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-0
lines changed

swift/ql/lib/codeql/swift/elements/decl/MethodDecl.qll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,33 @@ class MethodDecl extends AbstractFunctionDecl {
2121
or
2222
this = getAMember(any(ProtocolDecl c))
2323
}
24+
25+
/**
26+
* Holds if this function is called `funcName` and its a member of a
27+
* class, struct, extension, enum or protocol call `typeName`.
28+
*/
29+
predicate hasQualifiedName(string typeName, string funcName) {
30+
this.getName() = funcName and
31+
(
32+
exists(NominalTypeDecl c |
33+
c.getFullName() = typeName and
34+
c.getAMember() = this
35+
)
36+
or
37+
exists(ExtensionDecl e |
38+
e.getExtendedTypeDecl().getFullName() = typeName and
39+
e.getAMember() = this
40+
)
41+
)
42+
}
43+
44+
/**
45+
* Holds if this function is called `funcName` and its a member of a
46+
* class, struct, extension, enum or protocol call `typeName` in a moduile
47+
* called `moduleName`.
48+
*/
49+
predicate hasQualifiedName(string moduleName, string typeName, string funcName) {
50+
this.hasQualifiedName(typeName, funcName) and
51+
this.getModule().getFullName() = moduleName
52+
}
2453
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| abstractfunctiondecl.swift:2:1:2:15 | func1() | getName:func1() |
2+
| abstractfunctiondecl.swift:5:2:5:16 | func2() | MethodDecl, getName:func2(), hasQualifiedName(2):Class1.func2(), hasQualifiedName(3):abstractfunctiondecl.Class1.func2() |
3+
| abstractfunctiondecl.swift:8:3:8:17 | func3() | MethodDecl, getName:func3(), hasQualifiedName(2):Class1.Class2.func3(), hasQualifiedName(3):abstractfunctiondecl.Class1.Class2.func3() |
4+
| abstractfunctiondecl.swift:13:2:13:13 | func4() | MethodDecl, getName:func4(), hasQualifiedName(2):Protocol1.func4(), hasQualifiedName(3):abstractfunctiondecl.Protocol1.func4() |
5+
| abstractfunctiondecl.swift:17:2:17:16 | func4() | MethodDecl, getName:func4(), hasQualifiedName(2):Class3.func4(), hasQualifiedName(3):abstractfunctiondecl.Class3.func4() |
6+
| abstractfunctiondecl.swift:21:2:21:16 | func5() | MethodDecl, getName:func5(), hasQualifiedName(2):Class3.func5(), hasQualifiedName(3):abstractfunctiondecl.Class3.func5() |
7+
| abstractfunctiondecl.swift:25:2:25:16 | func6() | MethodDecl, getName:func6(), hasQualifiedName(2):Struct1.func6(), hasQualifiedName(3):abstractfunctiondecl.Struct1.func6() |
8+
| abstractfunctiondecl.swift:31:2:31:16 | func7() | MethodDecl, getName:func7(), hasQualifiedName(2):Enum1.func7(), hasQualifiedName(3):abstractfunctiondecl.Enum1.func7() |
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import swift
2+
3+
string describe(AbstractFunctionDecl f) {
4+
result = "getName:" + f.getName()
5+
or
6+
(
7+
result = "MethodDecl" and f instanceof MethodDecl
8+
)
9+
or
10+
exists(string a, string b |
11+
f.(MethodDecl).hasQualifiedName(a, b) and
12+
result = "hasQualifiedName(2):" + a + "." + b
13+
)
14+
or
15+
exists(string a, string b, string c |
16+
f.(MethodDecl).hasQualifiedName(a, b, c) and
17+
result = "hasQualifiedName(3):" + a + "." + b + "." + c
18+
)
19+
}
20+
21+
from AbstractFunctionDecl f
22+
where
23+
not f.getFile() instanceof UnknownFile and
24+
not f.getName().matches("%init%")
25+
select f, concat(describe(f), ", ")
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
func func1() {}
3+
4+
class Class1 {
5+
func func2() {}
6+
7+
class Class2 {
8+
func func3() {}
9+
}
10+
}
11+
12+
protocol Protocol1 {
13+
func func4()
14+
}
15+
16+
class Class3: Class1, Protocol1 {
17+
func func4() {}
18+
}
19+
20+
extension Class3 {
21+
func func5() {}
22+
}
23+
24+
struct Struct1 {
25+
func func6() {}
26+
}
27+
28+
enum Enum1 {
29+
case case1
30+
case case2
31+
func func7() {}
32+
}

0 commit comments

Comments
 (0)