Skip to content

Commit 3175532

Browse files
committed
wip
1 parent 92bdb7b commit 3175532

3 files changed

Lines changed: 709 additions & 634 deletions

File tree

‎unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll‎

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ abstract private class TypeMentionImpl extends AstNode {
6060
bindingset[this, qualifier]
6161
pragma[inline_late]
6262
predicate isValidParentType(TypeMention qualifier) {
63-
this.isValidParentType0(qualifier.getClassLikeDeclaration())
63+
this.isValidParentType0(qualifier.getClassLikeDeclaration().getEnclosingClassResolved*())
6464
}
6565

6666
/**
@@ -128,17 +128,35 @@ abstract private class ExprTypeMentionImpl extends TypeMentionImpl, Expr {
128128

129129
abstract Type getTypeAtImpl(TypePath path);
130130

131+
pragma[nomagic]
132+
private ClassLikeDeclaration getQualifierTypeAt(TypePath path) {
133+
result =
134+
this.getParentQualifier().getTypeAt(path).(ClassLikeDeclarationType).getClassLikeDeclaration()
135+
}
136+
137+
pragma[nomagic]
138+
private predicate isNestedClass(
139+
ClassLikeDeclaration cls, ParentTypeParameterType tp, ClassLikeDeclaration parent
140+
) {
141+
cls = this.getClassLikeDeclaration() and
142+
tp = TParentTypeParameterType(cls) and
143+
parent = tp.getParent()
144+
}
145+
131146
final override Type getTypeAt(TypePath path) {
132147
// recursion guard to check that `getType` does not recursively depend on `getTypeAt`
133148
(exists(this.getType()) implies any()) and
134149
result = this.getTypeAtImpl(path)
135150
or
136151
// A mention of a nested type with an explicit qualifier
137-
exists(TypeMention qualifier, ClassLikeDeclaration cls, TypePath suffix |
152+
exists(
153+
TypeMention qualifier, ClassLikeDeclaration cls, ParentTypeParameterType tp, TypePath prefix,
154+
TypePath suffix
155+
|
138156
qualifier = this.getParentQualifier() and
139-
cls = this.getClassLikeDeclaration() and
140-
path = TypePath::cons(TParentTypeParameterType(cls), suffix) and
141-
result = qualifier.getTypeAt(suffix)
157+
this.isNestedClass(cls, tp, this.getQualifierTypeAt(prefix)) and
158+
path = TypePath::cons(tp, suffix) and
159+
result = qualifier.getTypeAt(prefix.appendInverse(suffix))
142160
)
143161
or
144162
// A mention of a nested type without an explicit qualifier implicitly mentions

‎unified/ql/test/library-tests/type-inference/nested_types.swift‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ class Outer<TOuter> {
103103
let outer = x.getOuter() // $ target=Outer.Inner.getOuter type=outer:String
104104
let inner = x.getInner() // $ target=Outer.Inner.getInner type=inner:Int
105105
}
106+
107+
typealias Pair = (Inner<Int>, Inner<Int>)
108+
109+
func f3(p: Pair) {
110+
let outer = p.0.getOuter() // $ target=Outer.Inner.getOuter field=Tuple2.0 $ MISSING: type=outer:TOuter
111+
let inner = p.0.getInner() // $ target=Outer.Inner.getInner field=Tuple2.0 type=inner:Int
112+
}
106113
}
107114

108115
func extractInner<Ta, Tb>(_ inner: Outer<Ta>.Inner<Tb>) -> Tb {
@@ -245,6 +252,6 @@ func f(_ x: H.InnerAlias<Bool>, _ y: H2.InnerAlias<Bool>) {
245252
typealias G<A> = Outer<A>.Holder
246253

247254
func f(_ x: G<String>.InnerAlias<Bool>) {
248-
let outer = x.getOuter() // $ target=Outer.Inner.getOuter $ MISSING: type=outer:String
255+
let outer = x.getOuter() // $ target=Outer.Inner.getOuter type=outer:String
249256
let inner = x.getInner() // $ target=Outer.Inner.getInner type=inner:Bool
250257
}

0 commit comments

Comments
 (0)