Skip to content

Commit 6947794

Browse files
committed
Unified: Rename isInnerUnqualifiedAlias and take sub typing into account
1 parent d4de773 commit 6947794

3 files changed

Lines changed: 54 additions & 49 deletions

File tree

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

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,52 +6,58 @@ private import codeql.unified.internal.StaticNameBinding
66
private import codeql.unified.internal.ExprPositions
77

88
/**
9-
* Holds if `alias` is an alias at `pathToNested` for nested type `nested` with
10-
* enclosing type `parent`, where the alias itself is also enclosed by `parent`:
9+
* Holds if `alias` is an alias where the type mentioned at `pathToNested` in the
10+
* right-hand side is the nested type `nested`, and the alias is enclosed by `encl`,
11+
* which is (a sub class of) the parent class of `nested`. Furthermore, the mention
12+
* of `nested` must be "orphaned", meaning it's parent type is not mentioned explicitly:
1113
*
1214
* ```swift
13-
* class Parent {
15+
* class Parent<TParent> {
1416
* class Nested {}
15-
* typealias Alias = Nested // example
17+
* typealias Alias = Nested // example
18+
* typealias Alias2 = Parent<Int>.Nested // non-example (not orphaned)
1619
* class MoreNested {
17-
* typealias Alias = Nested // example
20+
* typealias Alias = Nested // example
1821
* }
1922
* }
20-
* typealias Alias = Parent.Nested // non-example
23+
* typealias Alias = Parent<Int>.Nested // non-example (not orphaned, not enclosed by `Parent`)
24+
* class Sub : Parent<Int> {
25+
* typealias SubAlias = Nested // example
26+
* }
2127
* ```
2228
*
2329
* The type path `pathParents` is any valid sequence of `ParentTypeParameterType`s starting
24-
* from the alias declaration and not escaping `parent`, while `encl` is the enclosing
25-
* class of the last element of `pathParents`.
26-
*
27-
* Restricted to aliases without a qualifier for `nested`.
30+
* from the alias declaration and not escaping `encl`, while `last` is the enclosing
31+
* class of the last element of `pathParents` (used to build up `pathParents` recursively).
2832
*/
29-
private predicate isInnerUnqualifiedAlias(
33+
private predicate isInnerAliasWithOrphanedNestedType(
3034
TypeAliasDeclaration alias, TypePath pathToNested, ClassLikeDeclaration nested,
31-
ClassLikeDeclaration parent, TypePath pathParents, ClassLikeDeclaration encl
35+
ClassLikeDeclaration encl, TypePath pathParents, ClassLikeDeclaration last
3236
) {
33-
nested = alias.getType().(TypeMention).getSimpleExpandedTypeAt(pathToNested).asClass() and
34-
// if the alias already has a qualifier that mentions the parent type, then we assume
35-
// it applies
36-
not exists(ParentTypeParameterType ptp |
37-
ptp.getParent() = parent and
38-
exists(
39-
alias
40-
.getType()
41-
.(TypeMention)
42-
.getSimpleExpandedTypeAt(pathToNested.append(TypePath::singleton(ptp)))
43-
)
44-
) and
45-
parent = nested.getEnclosingClassResolved() and
46-
alias.getEnclosingClassResolved+() = parent and
47-
pathParents = TypePath::singleton(TParentTypeParameterType(alias)) and
48-
encl = alias.getEnclosingClassResolved()
37+
exists(ClassLikeDeclaration parent |
38+
parent = nested.getEnclosingClassResolved() and
39+
nested = alias.getType().(TypeMention).getSimpleExpandedTypeAt(pathToNested).asClass() and
40+
// if the alias already mentions the parent type, then we assume it applies
41+
not exists(ParentTypeParameterType ptp |
42+
ptp.getParent().getABaseClass*() = parent and
43+
exists(
44+
alias
45+
.getType()
46+
.(TypeMention)
47+
.getSimpleExpandedTypeAt(pathToNested.append(TypePath::singleton(ptp)))
48+
)
49+
) and
50+
encl.getABaseClass*() = parent and
51+
alias.getEnclosingClassResolved+() = encl and
52+
pathParents = TypePath::singleton(TParentTypeParameterType(alias)) and
53+
last = alias.getEnclosingClassResolved()
54+
)
4955
or
50-
exists(TypePath mid, ClassLikeDeclaration enclMid |
51-
isInnerUnqualifiedAlias(alias, pathToNested, nested, parent, mid, enclMid) and
52-
not enclMid = parent and
53-
pathParents = mid.append(TypePath::singleton(TParentTypeParameterType(enclMid))) and
54-
encl = enclMid.getEnclosingClassResolved()
56+
exists(TypePath mid, ClassLikeDeclaration lastMid |
57+
isInnerAliasWithOrphanedNestedType(alias, pathToNested, nested, encl, mid, lastMid) and
58+
not lastMid = encl and
59+
pathParents = mid.append(TypePath::singleton(TParentTypeParameterType(lastMid))) and
60+
last = lastMid.getEnclosingClassResolved()
5561
)
5662
}
5763

@@ -95,17 +101,18 @@ abstract private class TypeMentionImpl extends AstNode {
95101
not result = alias.getATypeParameter()
96102
or
97103
// substitute for type parameters in alias RHS
98-
exists(TypeParameter tp, TypePath mid |
104+
exists(TypeParameter tp, TypePath pathToTp, TypePath mid |
99105
tp = alias.getATypeParameter() and
100-
tp = alias.getAlias().getSimpleExpandedTypeAt(mid) and
101-
result =
102-
this.getSimpleExpandedTypeAt(prefix
103-
.appendInverse(any(TypePath cons | cons.isCons(tp, suffix)))) and
104-
path = prefix.append(mid).append(suffix)
106+
tp = alias.getAlias().getSimpleExpandedTypeAt(pathToTp) and
107+
result = this.getSimpleExpandedTypeAt(prefix.appendInverse(mid)) and
108+
mid.isCons(tp, suffix) and
109+
path = prefix.append(pathToTp).append(suffix)
105110
)
106111
)
107112
}
108113

114+
Type getSimpleExpandedType() { result = this.getSimpleExpandedTypeAt(TypePath::nil()) }
115+
109116
/**
110117
* Same as `getSimpleExpandedTypeAt`, but also handles inner unqualified aliases where
111118
* the qualifier is provided at the use site:
@@ -130,22 +137,20 @@ abstract private class TypeMentionImpl extends AstNode {
130137
ClassLikeDeclaration parent, TypePath pathParents, TypePath suffix
131138
|
132139
this.getExpandedTypeAt(prefix) = alias and
133-
isInnerUnqualifiedAlias(alias.getTypeAliasDeclaration(), pathToNested, nested, parent,
134-
pathParents, _) and
140+
isInnerAliasWithOrphanedNestedType(alias.getTypeAliasDeclaration(), pathToNested, nested,
141+
parent, pathParents, _) and
135142
this.getExpandedTypeAt(prefix.append(pathParents)).asClass().getABaseClass*() = parent and
136143
result = this.getExpandedTypeAt(prefix.append(pathParents).appendInverse(suffix)) and
137144
path =
138145
prefix.append(pathToNested.append(TypePath::cons(TParentTypeParameterType(nested), suffix)))
139146
)
140147
}
141148

142-
private Type getExpandedType() { result = this.getExpandedTypeAt(TypePath::nil()) }
143-
144149
/**
145150
* Gets the class-like declaration mentioned by this type mention, if any.
146151
*/
147152
ClassLikeDeclaration getClassLikeDeclaration() {
148-
result = this.getExpandedType().(ClassLikeDeclarationType).getClassLikeDeclaration()
153+
result = this.getSimpleExpandedType().(ClassLikeDeclarationType).getClassLikeDeclaration()
149154
}
150155

151156
pragma[nomagic]

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ class Sub: Base2<String> {
296296
}
297297
class SubSub: Sub {
298298
func f(
299-
x1: Sub.Element, // $ MISSING: type=x1@Base2.Nested<(parent:Nested)>:Sub
299+
x1: Sub.Element, // $ type=x1@Base2.Nested<(parent:Nested)>:Sub
300300
x2: Element, // $ type=x2@Base2.Nested<(parent:Nested)>:SubSub
301301
x3: Element2, // $ type=x3@Base2.Nested<(parent:Nested)>:Sub
302302
x4: SubSub.Element2 // $ type=x4@Base2.Nested<(parent:Nested)>:Sub

‎unified/ql/test/library-tests/type-inference/type-inference.expected‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -804,15 +804,15 @@ inferCertainType
804804
| nested_types.swift:285:13:285:13 | x | | nested_types.swift:283:13:283:13 | T |
805805
| nested_types.swift:288:20:288:20 | x | | nested_types.swift:283:13:283:13 | T |
806806
| nested_types.swift:299:9:299:10 | x1 | | nested_types.swift:284:5:290:5 | Base2.Nested |
807-
| nested_types.swift:299:9:299:10 | x1 | (parent:Nested) | nested_types.swift:297:1:309:1 | SubSub |
807+
| nested_types.swift:299:9:299:10 | x1 | (parent:Nested) | nested_types.swift:292:1:296:1 | Sub |
808808
| nested_types.swift:300:9:300:10 | x2 | | nested_types.swift:284:5:290:5 | Base2.Nested |
809809
| nested_types.swift:300:9:300:10 | x2 | (parent:Nested) | nested_types.swift:297:1:309:1 | SubSub |
810810
| nested_types.swift:301:9:301:10 | x3 | | nested_types.swift:284:5:290:5 | Base2.Nested |
811811
| nested_types.swift:301:9:301:10 | x3 | (parent:Nested) | nested_types.swift:292:1:296:1 | Sub |
812812
| nested_types.swift:302:9:302:10 | x4 | | nested_types.swift:284:5:290:5 | Base2.Nested |
813813
| nested_types.swift:302:9:302:10 | x4 | (parent:Nested) | nested_types.swift:292:1:296:1 | Sub |
814814
| nested_types.swift:304:17:304:18 | x1 | | nested_types.swift:284:5:290:5 | Base2.Nested |
815-
| nested_types.swift:304:17:304:18 | x1 | (parent:Nested) | nested_types.swift:297:1:309:1 | SubSub |
815+
| nested_types.swift:304:17:304:18 | x1 | (parent:Nested) | nested_types.swift:292:1:296:1 | Sub |
816816
| nested_types.swift:305:17:305:18 | x2 | | nested_types.swift:284:5:290:5 | Base2.Nested |
817817
| nested_types.swift:305:17:305:18 | x2 | (parent:Nested) | nested_types.swift:297:1:309:1 | SubSub |
818818
| nested_types.swift:306:17:306:18 | x3 | | nested_types.swift:284:5:290:5 | Base2.Nested |
@@ -3615,15 +3615,15 @@ inferType
36153615
| nested_types.swift:287:26:289:9 | Block | | nested_types.swift:283:13:283:13 | T |
36163616
| nested_types.swift:288:20:288:20 | x | | nested_types.swift:283:13:283:13 | T |
36173617
| nested_types.swift:299:9:299:10 | x1 | | nested_types.swift:284:5:290:5 | Base2.Nested |
3618-
| nested_types.swift:299:9:299:10 | x1 | (parent:Nested) | nested_types.swift:297:1:309:1 | SubSub |
3618+
| nested_types.swift:299:9:299:10 | x1 | (parent:Nested) | nested_types.swift:292:1:296:1 | Sub |
36193619
| nested_types.swift:300:9:300:10 | x2 | | nested_types.swift:284:5:290:5 | Base2.Nested |
36203620
| nested_types.swift:300:9:300:10 | x2 | (parent:Nested) | nested_types.swift:297:1:309:1 | SubSub |
36213621
| nested_types.swift:301:9:301:10 | x3 | | nested_types.swift:284:5:290:5 | Base2.Nested |
36223622
| nested_types.swift:301:9:301:10 | x3 | (parent:Nested) | nested_types.swift:292:1:296:1 | Sub |
36233623
| nested_types.swift:302:9:302:10 | x4 | | nested_types.swift:284:5:290:5 | Base2.Nested |
36243624
| nested_types.swift:302:9:302:10 | x4 | (parent:Nested) | nested_types.swift:292:1:296:1 | Sub |
36253625
| nested_types.swift:304:17:304:18 | x1 | | nested_types.swift:284:5:290:5 | Base2.Nested |
3626-
| nested_types.swift:304:17:304:18 | x1 | (parent:Nested) | nested_types.swift:297:1:309:1 | SubSub |
3626+
| nested_types.swift:304:17:304:18 | x1 | (parent:Nested) | nested_types.swift:292:1:296:1 | Sub |
36273627
| nested_types.swift:305:17:305:18 | x2 | | nested_types.swift:284:5:290:5 | Base2.Nested |
36283628
| nested_types.swift:305:17:305:18 | x2 | (parent:Nested) | nested_types.swift:297:1:309:1 | SubSub |
36293629
| nested_types.swift:306:17:306:18 | x3 | | nested_types.swift:284:5:290:5 | Base2.Nested |

0 commit comments

Comments
 (0)