@@ -5,50 +5,59 @@ private import TypeInferencePlugin as Plugin
55private import codeql.unified.internal.StaticNameBinding
66private 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