Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 221fa37

Browse files
smowtonigfoo
authored andcommitted
Fix naming of local class instances that fall within generic functions
1 parent 735520a commit 221fa37

3 files changed

Lines changed: 21 additions & 13 deletions

File tree

java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,22 @@ open class KotlinUsesExtractor(
145145
} ?: argsIncludingOuterClasses
146146
}
147147

148+
fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner
149+
148150
// Gets nested inner classes starting at `c` and proceeding outwards to the innermost enclosing static class.
149151
// For example, for (java syntax) `class A { static class B { class C { class D { } } } }`,
150152
// `nonStaticParentsWithSelf(D)` = `[D, C, B]`.
151153
fun parentsWithTypeParametersInScope(c: IrClass): List<IrDeclarationParent> {
152154
val parentsList = c.parentsWithSelf.toList()
153-
val firstOuterClassIdx = parentsList.indexOfFirst { it is IrClass && !it.isInner }
155+
val firstOuterClassIdx = parentsList.indexOfFirst { it is IrClass && isStaticClass(it) }
154156
return if (firstOuterClassIdx == -1) parentsList else parentsList.subList(0, firstOuterClassIdx + 1)
155157
}
156158

157159
// Gets the type parameter symbols that are in scope for class `c` in Kotlin order (i.e. for
158160
// `class NotInScope<T> { static class OutermostInScope<A, B> { class QueryClass<C, D> { } } }`,
159161
// `getTypeParametersInScope(QueryClass)` = `[C, D, A, B]`.
160162
fun getTypeParametersInScope(c: IrClass) =
161-
parentsWithTypeParametersInScope(c).mapNotNull({ (it as? IrClass)?.typeParameters }).flatten()
163+
parentsWithTypeParametersInScope(c).mapNotNull({ getTypeParameters(it) }).flatten()
162164

163165
// Returns a map from `c`'s type variables in scope to type arguments `argsIncludingOuterClasses`.
164166
// Hack for the time being: the substituted types are always nullable, to prevent downstream code
@@ -167,18 +169,17 @@ open class KotlinUsesExtractor(
167169
fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>) =
168170
getTypeParametersInScope(c).map({ it.symbol }).zip(argsIncludingOuterClasses.map { it.withQuestionMark(true) }).toMap()
169171

170-
// The Kotlin compiler internal representation of Outer<A, B>.Inner<C, D>.InnerInner<E, F> is InnerInner<E, F, C, D, A, B>. This function returns [A, B, C, D, E, F].
172+
// The Kotlin compiler internal representation of Outer<A, B>.Inner<C, D>.InnerInner<E, F>.someFunction<G, H>.LocalClass<I, J> is LocalClass<I, J, G, H, E, F, C, D, A, B>. This function returns [A, B, C, D, E, F, G, H, I, J].
171173
fun orderTypeArgsLeftToRight(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?): List<IrTypeArgument>? {
172174
if(argsIncludingOuterClasses.isNullOrEmpty())
173175
return argsIncludingOuterClasses
174176
val ret = ArrayList<IrTypeArgument>()
175177
// Iterate over nested inner classes starting at `c`'s surrounding top-level or static nested class and ending at `c`, from the outermost inwards:
176178
val truncatedParents = parentsWithTypeParametersInScope(c)
177179
for(parent in truncatedParents.reversed()) {
178-
if(parent is IrClass) {
179-
val firstArgIdx = argsIncludingOuterClasses.size - (ret.size + parent.typeParameters.size)
180-
ret.addAll(argsIncludingOuterClasses.subList(firstArgIdx, firstArgIdx + parent.typeParameters.size))
181-
}
180+
val parentTypeParameters = getTypeParameters(parent)
181+
val firstArgIdx = argsIncludingOuterClasses.size - (ret.size + parentTypeParameters.size)
182+
ret.addAll(argsIncludingOuterClasses.subList(firstArgIdx, firstArgIdx + parentTypeParameters.size))
182183
}
183184
return ret
184185
}
@@ -612,6 +613,13 @@ class X {
612613
return if (f is IrConstructor) f.typeParameters else f.typeParameters.filter { it.parent == f }
613614
}
614615

616+
fun getTypeParameters(dp: IrDeclarationParent): List<IrTypeParameter> =
617+
when(dp) {
618+
is IrClass -> dp.typeParameters
619+
is IrFunction -> getFunctionTypeParameters(dp)
620+
else -> listOf()
621+
}
622+
615623
fun getFunctionLabel(f: IrFunction, classTypeArguments: List<IrTypeArgument>? = null) : String {
616624
return getFunctionLabel(f.parent, getFunctionShortName(f), f.valueParameters, f.returnType, f.extensionReceiverParameter, getFunctionTypeParameters(f), classTypeArguments)
617625
}

java/ql/test/kotlin/library-tests/generics/PrintAst.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ generics.kt:
223223
# 61| 1: [ExprStmt] <Expr>;
224224
# 61| 0: [MethodAccess] fn2(...)
225225
# 61| -2: [TypeAccess] String
226-
# 61| -1: [ClassInstanceExpr] new Local<T1>(...)
227-
# 61| -3: [TypeAccess] Local<T1>
226+
# 61| -1: [ClassInstanceExpr] new Local<Integer>(...)
227+
# 61| -3: [TypeAccess] Local<Integer>
228228
# 61| 0: [TypeAccess] Integer
229229
# 61| 0: [VarAccess] t
230230
# 61| 1: [StringLiteral]

java/ql/test/kotlin/library-tests/generics/generics.expected

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ parameterizedType
4949
| generics.kt:56:1:63:1 | Class1 | generics.kt:56:1:63:1 | Class1 | 0 | T1 |
5050
| generics.kt:56:1:63:1 | Class1<T1> | generics.kt:56:1:63:1 | Class1 | 0 | T2 |
5151
| generics.kt:58:9:60:9 | Local | generics.kt:58:9:60:9 | Local | 0 | T3 |
52-
| generics.kt:58:9:60:9 | Local<T1> | generics.kt:58:9:60:9 | Local | 0 | Integer |
52+
| generics.kt:58:9:60:9 | Local<Integer> | generics.kt:58:9:60:9 | Local | 0 | Integer |
5353
function
5454
| generics.kt:3:1:5:1 | f0 | f0(int,java.lang.Object) |
5555
| generics.kt:7:1:9:1 | f1 | f1(int,java.lang.Object) |
@@ -97,7 +97,7 @@ function
9797
| generics.kt:57:5:62:5 | fn1 | fn1(java.lang.Object) |
9898
| generics.kt:58:9:60:9 | <obinit> | <obinit>() |
9999
| generics.kt:58:9:60:9 | Local | Local() |
100-
| generics.kt:58:9:60:9 | Local<T1> | Local<T1>() |
100+
| generics.kt:58:9:60:9 | Local<Integer> | Local<Integer>() |
101101
| generics.kt:59:13:59:43 | fn2 | fn2(java.lang.Object,java.lang.Object) |
102102
| generics.kt:59:13:59:43 | fn2 | fn2(java.lang.Object,java.lang.Object) |
103103
genericFunction
@@ -110,7 +110,7 @@ genericFunction
110110
| generics.kt:21:5:21:23 | f4 | generics.kt:20:1:22:1 | C2 | generics.kt:21:10:21:10 | P | 0 |
111111
| generics.kt:57:5:62:5 | fn1 | generics.kt:56:1:63:1 | Class1 | generics.kt:57:10:57:11 | T2 | 0 |
112112
| generics.kt:59:13:59:43 | fn2 | generics.kt:58:9:60:9 | Local | generics.kt:59:18:59:19 | T4 | 0 |
113-
| generics.kt:59:13:59:43 | fn2 | generics.kt:58:9:60:9 | Local<T1> | generics.kt:59:18:59:19 | T4 | 0 |
113+
| generics.kt:59:13:59:43 | fn2 | generics.kt:58:9:60:9 | Local<Integer> | generics.kt:59:18:59:19 | T4 | 0 |
114114
genericCall
115115
| generics.kt:27:17:27:22 | f2(...) | generics.kt:15:10:15:10 | U | String |
116116
| generics.kt:30:17:30:21 | f2(...) | generics.kt:15:10:15:10 | U | Integer |
@@ -128,4 +128,4 @@ genericCtor
128128
| generics.kt:45:21:45:41 | new Inner1<Integer,String>(...) | 1 | String |
129129
| generics.kt:51:21:51:42 | new Nested1<Integer,String>(...) | 0 | Integer |
130130
| generics.kt:51:21:51:42 | new Nested1<Integer,String>(...) | 1 | String |
131-
| generics.kt:61:9:61:20 | new Local<T1>(...) | 0 | Integer |
131+
| generics.kt:61:9:61:20 | new Local<Integer>(...) | 0 | Integer |

0 commit comments

Comments
 (0)