diff --git a/unified/ql/lib/codeql/unified/internal/NameBindingPlugin.qll b/unified/ql/lib/codeql/unified/internal/NameBindingPlugin.qll index 9057c512e41f..f6b6cc25f7f5 100644 --- a/unified/ql/lib/codeql/unified/internal/NameBindingPlugin.qll +++ b/unified/ql/lib/codeql/unified/internal/NameBindingPlugin.qll @@ -96,9 +96,9 @@ predicate isInstanceMember(Member member) { */ predicate isStaticMember(Member member) { exists(ClassLikeDeclaration cls | cls.getAMember() = member | - not any(NameBindingPlugin p).isInstanceMember(cls, member) - or - member instanceof ConstructorDeclaration + not any(NameBindingPlugin p).isInstanceMember(cls, member) or + member instanceof ConstructorDeclaration or + member instanceof TypeAliasDeclaration ) or member = any(TopLevel t).getBody().getAStmt() diff --git a/unified/ql/test/library-tests/static-name-binding/test.swift b/unified/ql/test/library-tests/static-name-binding/test.swift index 9b18bc5ebf72..7bf86d93e76e 100644 --- a/unified/ql/test/library-tests/static-name-binding/test.swift +++ b/unified/ql/test/library-tests/static-name-binding/test.swift @@ -1,24 +1,27 @@ -class B {} // name=top.B +class B {} // name=top.B class A { class B { class C {} } + + typealias BAlias = B // $ access=A.B } -let x1: B = nil; // $ access=top.B -let x2: A.B = nil; // $ access=A access=A.B -let x3: A.B.C = nil; // $ access=A access=A.B access=A.B.C +let x1: B = nil // $ access=top.B +let x2: A.B = nil // $ access=A access=A.B +let x3: A.B.C = nil // $ access=A access=A.B access=A.B.C +let x4: A.BAlias.C = nil // $ access=A access=A.BAlias access=A.B.C class D { - let x1: B = nil; // $ access=top.B - let x2: A.B = nil; // $ access=A access=A.B - let x3: A.B.C = nil; // $ access=A access=A.B access=A.B.C + let x1: B = nil // $ access=top.B + let x2: A.B = nil // $ access=A access=A.B + let x3: A.B.C = nil // $ access=A access=A.B access=A.B.C func member() { - let x1: B = nil; // $ access=top.B - let x2: A.B = nil; // $ access=A access=A.B - let x3: A.B.C = nil; // $ access=A access=A.B access=A.B.C + let x1: B = nil // $ access=top.B + let x2: A.B = nil // $ access=A access=A.B + let x3: A.B.C = nil // $ access=A access=A.B access=A.B.C } } @@ -28,49 +31,52 @@ class E { } } - let x1: A = nil; // $ access=E.A - let x2: A.B = nil; // $ access=E.A access=E.A.B + let x1: A = nil // $ access=E.A + let x2: A.B = nil // $ access=E.A access=E.A.B } class F { static let field = 1 - static let (a,b) = (1,2) + static let (a, b) = (1, 2) static func foo() { - F.field // $ access=F access=F.field - F.a // $ access=F access=F.a - F.b // $ access=F access=F.b + F.field // $ access=F access=F.field + F.a // $ access=F access=F.a + F.b // $ access=F access=F.b } } -typealias G = A // $ access=A +typealias G = A // $ access=A // Members can be accessed through aliases, but references to the alias itself do not bypass the alias. -class H { // name=H1 - let x1: G = nil; // $ access=G - let x2: G.B = nil; // $ access=G access=A.B - let x3: G.B.C = nil; // $ access=G access=A.B access=A.B.C +class H { // name=H1 + let x1: G = nil // $ access=G + let x2: G.B = nil // $ access=G access=A.B + let x3: G.B.C = nil // $ access=G access=A.B access=A.B.C } enum I { - case one=1, two=2 - case three=3 + case one = 1 + case two = 2 + case three = 3 } func useI() { - I.one // $ access=I access=I.one - I.two // $ access=I access=I.two - I.three // $ access=I access=I.three + I.one // $ access=I access=I.one + I.two // $ access=I access=I.two + I.three // $ access=I access=I.three } -protocol P { } +protocol P {} -extension H // $ access=H1 - : P { } // $ access=P +extension H // $ access=H1 + : P // $ access=P +{} -extension A.B.C // $ access=A access=A.B access=A.B.C - : P { } // $ access=P +extension A.B.C // $ access=A access=A.B access=A.B.C + : P // $ access=P +{} -A() // $ access=A +A() // $ access=A -A.init() // $ access=A access=A.init \ No newline at end of file +A.init() // $ access=A access=A.init