16
16
*/
17
17
package org.sonarsource.kotlin.checks
18
18
19
- import org.jetbrains.kotlin.js.descriptorUtils.getKotlinTypeFqName
19
+ import org.jetbrains.kotlin.analysis.api.resolution.KaFunctionCall
20
+ import org.jetbrains.kotlin.analysis.api.resolution.symbol
21
+ import org.jetbrains.kotlin.analysis.api.symbols.name
22
+ import org.jetbrains.kotlin.analysis.api.types.symbol
20
23
import org.jetbrains.kotlin.psi.KtCallExpression
21
- import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
22
24
import org.sonar.check.Rule
23
25
import org.sonarsource.kotlin.api.checks.CallAbstractCheck
24
26
import org.sonarsource.kotlin.api.checks.FunMatcher
25
27
import org.sonarsource.kotlin.api.checks.FunMatcherImpl
26
- import org.sonarsource.kotlin.api.checks.determineType
27
28
import org.sonarsource.kotlin.api.checks.predictReceiverExpression
28
29
import org.sonarsource.kotlin.api.frontend.KotlinFileContext
30
+ import org.sonarsource.kotlin.api.visiting.withKaSession
29
31
30
32
private val OBJECT_ARRAY_MATCHER = FunMatcher (qualifier = " kotlin.Array" ) {
31
33
withNames(" hashCode" , " toString" )
@@ -52,22 +54,21 @@ private val PRIMITIVE_ARRAY_REPLACEMENT = mapOf("hashCode" to "contentHashCode",
52
54
private val OBJECT_ARRAY_REPLACEMENT = mapOf (" hashCode" to " contentDeepHashCode" , " toString" to " contentDeepToString" )
53
55
private val ARRAY_OF_ARRAY_REPLACEMENT = mapOf (" contentHashCode" to " contentDeepHashCode" , " contentToString" to " contentDeepToString" )
54
56
55
- @org.sonarsource.kotlin.api.frontend.K1only
56
57
@Rule(key = " S2116" )
57
58
class ArrayHashCodeAndToStringCheck : CallAbstractCheck () {
58
59
59
60
override val functionsToVisit = listOf (OBJECT_ARRAY_MATCHER , ARRAY_CONTENT_MATCHER ) + PRIMITIVE_ARRAY_MATCHERS
60
61
61
62
override fun visitFunctionCall (
62
63
callExpression : KtCallExpression ,
63
- resolvedCall : ResolvedCall <* >,
64
+ resolvedCall : KaFunctionCall <* >,
64
65
matchedFun : FunMatcherImpl ,
65
- kotlinFileContext : KotlinFileContext ,
66
+ kotlinFileContext : KotlinFileContext
66
67
) {
67
- val methodName = resolvedCall.resultingDescriptor. name.asString()
68
+ val methodName = resolvedCall.partiallyAppliedSymbol.symbol. name? .asString()
68
69
val replacement = when (matchedFun) {
69
70
OBJECT_ARRAY_MATCHER -> OBJECT_ARRAY_REPLACEMENT [methodName]
70
- ARRAY_CONTENT_MATCHER -> if (receiverIsArrayOfArray(callExpression, kotlinFileContext ))
71
+ ARRAY_CONTENT_MATCHER -> if (receiverIsArrayOfArray(callExpression))
71
72
ARRAY_OF_ARRAY_REPLACEMENT [methodName] else null
72
73
73
74
else -> PRIMITIVE_ARRAY_REPLACEMENT [methodName]
@@ -77,11 +78,9 @@ class ArrayHashCodeAndToStringCheck : CallAbstractCheck() {
77
78
}
78
79
}
79
80
80
- private fun receiverIsArrayOfArray (callExpression : KtCallExpression , kotlinFileContext : KotlinFileContext ): Boolean {
81
- val bindingContext = kotlinFileContext.bindingContext
82
- return callExpression.predictReceiverExpression(bindingContext)?.determineType(bindingContext)?.arguments
83
- ?.any { ARRAY_QUALIFIERS .contains(it.type.getKotlinTypeFqName(false )) }
84
- ? : false
81
+ private fun receiverIsArrayOfArray (callExpression : KtCallExpression ): Boolean = withKaSession {
82
+ val argument = callExpression.predictReceiverExpression()?.expressionType?.arrayElementType
83
+ return ARRAY_QUALIFIERS .contains(argument?.symbol?.classId?.asFqNameString())
85
84
}
86
85
87
86
}
0 commit comments