Skip to content

Commit 8c5daba

Browse files
committed
(WIP) cleanup
1 parent 379adaf commit 8c5daba

File tree

1 file changed

+34
-31
lines changed

1 file changed

+34
-31
lines changed

sonar-kotlin-checks/src/main/java/org/sonarsource/kotlin/checks/DelegationPatternCheck.kt

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,60 +17,63 @@
1717
package org.sonarsource.kotlin.checks
1818

1919
import com.intellij.psi.PsiElement
20-
import org.jetbrains.kotlin.analysis.api.symbols.*
20+
import org.jetbrains.kotlin.analysis.api.symbols.KaClassKind
21+
import org.jetbrains.kotlin.analysis.api.symbols.KaClassSymbol
22+
import org.jetbrains.kotlin.analysis.api.symbols.KaFunctionSymbol
23+
import org.jetbrains.kotlin.analysis.api.symbols.name
2124
import org.jetbrains.kotlin.analysis.api.types.KaType
2225
import org.jetbrains.kotlin.analysis.api.types.KaTypeParameterType
2326
import org.jetbrains.kotlin.analysis.api.types.symbol
24-
import org.jetbrains.kotlin.psi.*
27+
import org.jetbrains.kotlin.psi.KtBlockExpression
28+
import org.jetbrains.kotlin.psi.KtCallExpression
29+
import org.jetbrains.kotlin.psi.KtClass
30+
import org.jetbrains.kotlin.psi.KtClassOrObject
31+
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
32+
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
33+
import org.jetbrains.kotlin.psi.KtNamedFunction
34+
import org.jetbrains.kotlin.psi.KtParameter
35+
import org.jetbrains.kotlin.psi.KtReturnExpression
36+
import org.jetbrains.kotlin.psi.KtValueArgument
2537
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
2638
import org.jetbrains.kotlin.psi.psiUtil.isPublic
2739
import org.sonar.check.Rule
28-
import org.sonarsource.kotlin.api.checks.*
40+
import org.sonarsource.kotlin.api.checks.AbstractCheck
41+
import org.sonarsource.kotlin.api.checks.allPaired
42+
import org.sonarsource.kotlin.api.checks.overrides
2943
import org.sonarsource.kotlin.api.frontend.KotlinFileContext
3044
import org.sonarsource.kotlin.api.visiting.withKaSession
3145

3246
@Rule(key = "S6514")
3347
class DelegationPatternCheck : AbstractCheck() {
3448

35-
override fun visitClassOrObject(classOrObject: KtClassOrObject, context: KotlinFileContext) {
36-
withKaSession {
37-
val classSymbol = classOrObject.classSymbol ?: return
38-
if (classSymbol.classKind == KaClassKind.INTERFACE) return
39-
val superInterfaces: Set<KaClassSymbol> = classSymbol.getSuperInterfaces()
49+
override fun visitClassOrObject(classOrObject: KtClassOrObject, context: KotlinFileContext) = withKaSession {
50+
val classSymbol = classOrObject.classSymbol ?: return
51+
if (classSymbol.classKind == KaClassKind.INTERFACE) return
52+
val superInterfaces: Set<KaClassSymbol> = classSymbol.getSuperInterfaces()
53+
if (superInterfaces.isEmpty()) return
4054

41-
classOrObject.declarations.forEach {
42-
if (it is KtNamedFunction) {
43-
checkNamedFunction(it, context, superInterfaces)
44-
}
55+
classOrObject.declarations.forEach {
56+
if (it is KtNamedFunction) {
57+
checkNamedFunction(it, superInterfaces, context)
4558
}
4659
}
4760
}
4861

49-
private fun checkNamedFunction(
50-
function: KtNamedFunction,
51-
context: KotlinFileContext,
52-
superInterfaces: Set<KaClassSymbol>
53-
) {
62+
private fun checkNamedFunction(function: KtNamedFunction, superInterfaces: Set<KaClassSymbol>, context: KotlinFileContext) = withKaSession {
5463
if (!(function.isPublic && function.overrides())) return
55-
val delegeeType1 = getDelegeeOrNull(function)?.determineType() ?: return
64+
val delegeeType = getDelegeeOrNull(function)?.expressionType ?: return
5665

57-
val commonSuperInterfaces = getCommonSuperInterfaces(superInterfaces, delegeeType1)
58-
59-
if (commonSuperInterfaces.any {
60-
isFunctionInInterface(function, it)
61-
}) {
66+
if (getCommonSuperInterfaces(superInterfaces, delegeeType).any {
67+
isFunctionInInterface(function, it)
68+
}) {
6269
context.reportIssue(function.nameIdentifier!!, """Replace with interface delegation using "by" in the class header.""")
6370
}
6471
}
6572
}
6673

67-
private fun isFunctionInInterface(
68-
function: KtNamedFunction,
69-
superInterface1: KaClassSymbol
70-
): Boolean = withKaSession {
71-
val classDeclaration = superInterface1.psi as? KtClass ?: return false
72-
return classDeclaration.declarations.any {
73-
it is KtNamedFunction && haveCompatibleFunctionSignature(it.symbol, function.symbol)
74+
private fun isFunctionInInterface(function: KtNamedFunction, superInterface: KaClassSymbol): Boolean = withKaSession {
75+
superInterface.declaredMemberScope.declarations.any {
76+
it is KaFunctionSymbol && haveCompatibleFunctionSignature(it, function.symbol)
7477
}
7578
}
7679

@@ -123,7 +126,7 @@ private fun getDelegeeOrNull(function: KtNamedFunction): KtNameReferenceExpressi
123126
private fun isDelegatedParameter(parameter: KtParameter, arguments: KtValueArgument): Boolean = withKaSession {
124127
val argumentExpression = arguments.getArgumentExpression() as? KtNameReferenceExpression ?: return false
125128
if (parameter.name != argumentExpression.getReferencedName()) return false
126-
val argumentType = argumentExpression.determineType() ?: return false
129+
val argumentType = argumentExpression.expressionType ?: return false
127130
return parameter.symbol.returnType.semanticallyEquals(argumentType)
128131
}
129132

0 commit comments

Comments
 (0)