Skip to content

Commit 16e479a

Browse files
committed
wip
1 parent 1e676e1 commit 16e479a

1 file changed

Lines changed: 63 additions & 70 deletions

File tree

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

Lines changed: 63 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,59 @@ private import TypeInferencePlugin as Plugin
55
private import codeql.unified.internal.StaticNameBinding
66
private import codeql.unified.internal.ExprPositions
77

8-
private predicate isInnerAlias0(
9-
TypeAliasDeclaration alias, ClassLikeDeclaration nested, ClassLikeDeclaration parent
10-
) {
11-
nested = alias.getType().(TypeMention).getClassLikeDeclaration() and
12-
parent = nested.getEnclosingClassResolved() and
13-
alias.getEnclosingClassResolved().getEnclosingClassResolved+() = parent
8+
private TypeAliasDeclaration getAForwardedAlias(TypeAliasDeclaration alias) {
9+
result = alias
10+
or
11+
TAliasType(result) = getAForwardedAlias(alias).getType().(TypeMention).getUnexpandedType()
1412
}
1513

16-
private predicate isInnerAlias(
17-
TypeAliasDeclaration alias, ClassLikeDeclaration nested, ClassLikeDeclaration parent,
18-
TypePath prefix, ClassLikeDeclaration cls
19-
) {
20-
isInnerAlias0(alias, nested, parent) and
21-
prefix = TypePath::singleton(TParentTypeParameterType(alias)) and
22-
cls = alias.getEnclosingClassResolved()
23-
or
24-
exists(TypePath mid, ClassLikeDeclaration cls0 |
25-
isInnerAlias(alias, nested, parent, mid, cls0) and
26-
prefix = mid.append(TypePath::singleton(TParentTypeParameterType(cls0))) and
27-
cls = cls0.getEnclosingClassResolved() and
28-
not cls0 = parent
14+
private predicate aliasHasQualifier(TypeAliasDeclaration alias) {
15+
exists(Type ultimate, ParentTypeParameterType tp |
16+
ultimate = getAForwardedAlias(alias).getType().(TypeMention).getUnexpandedType() and
17+
tp = TParentTypeParameterType(ultimate.asClass()) and
18+
exists(
19+
getAForwardedAlias(alias).getType().(TypeMention).getUnexpandedTypeAt(TypePath::singleton(tp))
20+
)
2921
)
3022
}
3123

32-
private predicate isOuterAlias0(
33-
TypeAliasDeclaration alias, ClassLikeDeclaration nested, ClassLikeDeclaration parent
24+
/**
25+
* Holds if `alias` is an alias for nested type `nested` with enclosing type
26+
* `parent`, where the alias itself is also enclosed by `parent`:
27+
*
28+
* ```swift
29+
* class Parent {
30+
* class Nested {}
31+
* typealias Alias = Nested // example
32+
* class MoreNested {
33+
* typealias Alias = Nested // example
34+
* }
35+
* }
36+
* typealias Alias = Parent.Nested // non-example
37+
* ```
38+
*
39+
* The type path `path` is any valid sequence of `ParentTypeParameterType`s starting
40+
* from the alias declaration and not escaping `parent`, while `encl` is the enclosing
41+
* class of the last element of `path`.
42+
*
43+
* Restricted to aliases without a qualifier for `nested`.
44+
*/
45+
private predicate isInnerAlias(
46+
TypeAliasDeclaration alias, ClassLikeDeclaration nested, ClassLikeDeclaration parent,
47+
TypePath path, ClassLikeDeclaration encl
3448
) {
49+
not aliasHasQualifier(alias) and
3550
nested = alias.getType().(TypeMention).getClassLikeDeclaration() and
3651
parent = nested.getEnclosingClassResolved() and
37-
not alias.getEnclosingClassResolved().getEnclosingClassResolved+() = parent
38-
// not isInnerAlias0(alias, _, _)
39-
}
40-
41-
private AliasType getFoo(AliasType alias) {
42-
result = alias
52+
alias.getEnclosingClassResolved+() = parent and
53+
path = TypePath::singleton(TParentTypeParameterType(alias)) and
54+
encl = alias.getEnclosingClassResolved()
4355
or
44-
result = getFoo(alias).getAlias().getUnexpandedType()
45-
}
46-
47-
private predicate hasQualifier(AliasType alias) {
48-
exists(Type t, ParentTypeParameterType tp |
49-
t = getFoo(alias).getAlias().getUnexpandedType() and
50-
tp = TParentTypeParameterType(t.asClass()) and
51-
exists(getFoo(alias).getAlias().getUnexpandedTypeAt(TypePath::singleton(tp)))
56+
exists(TypePath mid, ClassLikeDeclaration enclMid |
57+
isInnerAlias(alias, nested, parent, mid, enclMid) and
58+
not enclMid = parent and
59+
path = mid.append(TypePath::singleton(TParentTypeParameterType(enclMid))) and
60+
encl = enclMid.getEnclosingClassResolved()
5261
)
5362
}
5463

@@ -95,9 +104,24 @@ abstract private class TypeMentionImpl extends AstNode {
95104
)
96105
)
97106
or
98-
result = this.sdfsdf(path)
99-
or
100-
result = this.sdfsdf2(path)
107+
// class Parent<TParent> {
108+
// class Nested {}
109+
// class MoreNested {
110+
// typealias Alias = Nested
111+
// }
112+
// }
113+
//
114+
// let x : Parent<String>.MoreNested.Alias = ... // this will expand to `Parent<String>.Nested`
115+
exists(
116+
AliasType alias, TypePath prefix, TypePath pathToParent, ClassLikeDeclaration nested,
117+
ClassLikeDeclaration parent, TypePath suffix
118+
|
119+
this.getExpandedTypeAt(prefix) = alias and
120+
isInnerAlias(alias.getTypeAliasDeclaration(), nested, parent, pathToParent, _) and
121+
this.getExpandedTypeAt(prefix.append(pathToParent)).asClass().getABaseClass*() = parent and
122+
result = this.getExpandedTypeAt(prefix.append(pathToParent).appendInverse(suffix)) and
123+
path = prefix.append(TypePath::cons(TParentTypeParameterType(nested), suffix))
124+
)
101125
}
102126

103127
private Type getExpandedType() { result = this.getExpandedTypeAt(TypePath::nil()) }
@@ -109,37 +133,6 @@ abstract private class TypeMentionImpl extends AstNode {
109133
result = this.getExpandedType().(ClassLikeDeclarationType).getClassLikeDeclaration()
110134
}
111135

112-
private Type sdfsdf(TypePath path) {
113-
exists(
114-
AliasType alias, TypePath prefix, TypePath path0, ClassLikeDeclaration nested,
115-
ClassLikeDeclaration parent, TypePath suffix, ClassLikeDeclaration cls
116-
|
117-
not hasQualifier(alias) and
118-
this.getExpandedTypeAt(prefix) = alias and
119-
isInnerAlias(alias.getTypeAliasDeclaration(), nested, parent, path0, cls) and
120-
this.getExpandedTypeAt(prefix.append(path0)).asClass().getABaseClass*() = parent and
121-
result = this.getExpandedTypeAt(prefix.append(path0).appendInverse(suffix)) and
122-
path = prefix.append(TypePath::cons(TParentTypeParameterType(nested), suffix))
123-
)
124-
}
125-
126-
private Type sdfsdf2(TypePath path) {
127-
exists(
128-
AliasType alias, TypePath prefix, ClassLikeDeclaration nested, ClassLikeDeclaration parent,
129-
TypePath suffix, TypePath path0
130-
|
131-
not hasQualifier(alias) and
132-
path0 =
133-
prefix
134-
.append(TypePath::singleton(TParentTypeParameterType(alias.getTypeAliasDeclaration()))) and
135-
this.getExpandedTypeAt(prefix) = alias and
136-
isOuterAlias0(alias.getTypeAliasDeclaration(), nested, parent) and
137-
this.getExpandedTypeAt(path0).asClass().getABaseClass*() = parent and
138-
result = this.getExpandedTypeAt(path0.appendInverse(suffix)) and
139-
path = prefix.append(TypePath::cons(TParentTypeParameterType(nested), suffix))
140-
)
141-
}
142-
143136
pragma[nomagic]
144137
private ClassLikeDeclaration getImplicitEnclosingCand(TypePath path, ParentTypeParameterType tp) {
145138
exists(Type t |
@@ -166,7 +159,7 @@ abstract private class TypeMentionImpl extends AstNode {
166159
) and
167160
not result = unique( | | this.getExpandedTypeAt(path))
168161
or
169-
path.getElement(_) = alias.getATypeParameter() //and
162+
path.getElement(_) = alias.getATypeParameter()
170163
) and
171164
(
172165
result = this.getExpandedTypeAt(path)

0 commit comments

Comments
 (0)