@@ -43,7 +43,7 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData)
43
43
if (isUnrelated(instruction.variable)) return
44
44
val element = controlFlow.getElement(index)
45
45
if (element is PsiReferenceExpression && isUnstableVariable(element, instruction.variable)) {
46
- typeData[element] = bottomForType (instruction.variable.type, instruction.variable)
46
+ typeData[element] = topForType (instruction.variable.type, instruction.variable)
47
47
return
48
48
}
49
49
val value = ssaConstruction.readVariable(instruction.variable, block)
@@ -217,9 +217,9 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData)
217
217
" parameterList" ,
218
218
" parameterType" ,
219
219
" toMethodDescriptorString" ,
220
- -> noMethodHandle ()
220
+ -> unrelatedType ()
221
221
222
- in objectMethods -> noMethodHandle ()
222
+ in objectMethods -> unrelatedType ()
223
223
else -> warnUnsupported(expression, " MethodType" )
224
224
}
225
225
} else if (receiverIsMethodHandles(expression)) {
@@ -245,21 +245,27 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData)
245
245
" describeConstable" ,
246
246
" invoke" ,
247
247
" invokeExact" ,
248
- " invokeWithArguments" -> noMethodHandle ()
248
+ " invokeWithArguments" -> unrelatedType ()
249
249
250
250
" type" -> qualifier?.methodHandleType(block)
251
251
?.withVarargs(TriState .NO ) // if ever used somewhere else, assume non-varargs
252
252
253
- in objectMethods -> noMethodHandle ()
253
+ in objectMethods -> unrelatedType ()
254
254
else -> warnUnsupported(expression, " MethodHandle" )
255
255
}
256
256
} else if (receiverIsLookup(expression)) {
257
257
return lookup(expression, arguments, block)
258
+ } else {
259
+ return methodExpression.type?.let { topForType(it, expression) }
258
260
}
259
261
} else if (expression is PsiReferenceExpression ) {
260
262
val variable = expression.resolve() as ? PsiVariable ? : return noMatch()
261
263
if (isUnstableVariable(expression, variable)) {
262
- return bottomForType(variable.type, variable)
264
+ return topForType(variable.type, variable)
265
+ }
266
+ // parameters are always top - could be anything
267
+ if (variable is PsiParameter ) {
268
+ return topForType(variable.type, variable)
263
269
}
264
270
val value = ssaConstruction.readVariable(variable, block)
265
271
return if (value is Holder ) {
@@ -337,9 +343,9 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData)
337
343
" unreflectSetter" ,
338
344
" unreflectSpecial" ,
339
345
" unreflectVarHandle"
340
- -> noMethodHandle ()
346
+ -> unrelatedType ()
341
347
342
- in objectMethods -> noMethodHandle ()
348
+ in objectMethods -> unrelatedType ()
343
349
else -> warnUnsupported(expression, " MethodHandles.Lookup" )
344
350
}
345
351
}
@@ -353,7 +359,7 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData)
353
359
return resolver(refc, type)
354
360
}
355
361
356
- private fun noMethodHandle (): MethodHandleType ? = null
362
+ private fun unrelatedType (): TypeLatticeElement < * > ? = null
357
363
358
364
private fun methodHandles (
359
365
expression : PsiMethodCallExpression ,
@@ -551,9 +557,9 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData)
551
557
" lookup" ,
552
558
" privateLookupIn" ,
553
559
" publicLookup" ,
554
- " reflectAs" -> noMethodHandle ()
560
+ " reflectAs" -> unrelatedType ()
555
561
556
- in objectMethods -> noMethodHandle ()
562
+ in objectMethods -> unrelatedType ()
557
563
else -> warnUnsupported(expression, " MethodHandles" )
558
564
}
559
565
}
@@ -563,7 +569,7 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData)
563
569
}
564
570
565
571
private inline fun <reified T : TypeLatticeElement <T >> notConstant (): T {
566
- return bottomForType <T >()
572
+ return topForType <T >()
567
573
}
568
574
569
575
private fun singleParameter (
@@ -642,4 +648,30 @@ class SsaAnalyzer(private val controlFlow: ControlFlow, val typeData: TypeData)
642
648
}
643
649
}
644
650
651
+ private inline fun <reified T : TypeLatticeElement <* >> topForType (): T {
652
+ return topForType(T ::class )
653
+ }
654
+
655
+ private fun <T : TypeLatticeElement <* >> topForType (clazz : KClass <T >): T {
656
+ if (clazz == MethodHandleType ::class ) {
657
+ return clazz.java.cast(TopMethodHandleType )
658
+ }
659
+ if (clazz == VarHandleType ::class ) {
660
+ return clazz.java.cast(TopVarHandleType )
661
+ }
662
+ if (clazz == Type ::class ) {
663
+ return clazz.java.cast(TopType )
664
+ }
665
+ throw UnsupportedOperationException (" $clazz is not supported" )
666
+ }
667
+
668
+ private fun topForType (psiType : PsiType , context : PsiElement ): TypeLatticeElement <* > {
669
+ return when (psiType) {
670
+ methodTypeType(context) -> topForType<MethodHandleType >()
671
+ methodHandleType(context) -> topForType<MethodHandleType >()
672
+ varHandleType(context) -> topForType<VarHandleType >()
673
+ else -> throw UnsupportedOperationException (" ${psiType.presentableText} is not supported" )
674
+ }
675
+ }
676
+
645
677
}
0 commit comments