Skip to content

Commit a6adc77

Browse files
committed
(WIP) cleanup
1 parent be271fe commit a6adc77

File tree

2 files changed

+34
-60
lines changed

2 files changed

+34
-60
lines changed

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

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,6 @@ fun KaType.simpleName(): String? = withKaSession {
882882
return lowerBoundIfFlexible().symbol?.name?.asString()
883883
}
884884

885-
@Deprecated("use kotlin-analysis-api instead", ReplaceWith("this.determineType()"))
886885
fun PsiElement?.determineType(bindingContext: BindingContext): KotlinType? =
887886
this?.let {
888887
when (this) {
@@ -901,34 +900,6 @@ fun PsiElement?.determineType(bindingContext: BindingContext): KotlinType? =
901900

902901
}
903902

904-
fun PsiElement?.determineType(): KaType? = withKaSession {
905-
this?.let {
906-
when (this@determineType) {
907-
is KtCallExpression -> determineTypeFromCall()
908-
is KtParameter -> symbol.returnType
909-
is KtTypeReference -> type
910-
is KtProperty -> determineTypeFromCall()
911-
is KtDotQualifiedExpression -> determineTypeFromCall()
912-
is KtReferenceExpression -> determineTypeFromCall()
913-
is KtFunction -> (symbol as KaFunctionSymbol).returnType
914-
is KtClass -> returnType
915-
is KtConstantExpression -> this@determineType.expressionType
916-
is KtStringTemplateExpression -> this@determineType.expressionType
917-
is KtLambdaExpression -> this@determineType.expressionType
918-
is KtExpression -> determineTypeFromCall()
919-
is KtValueArgument -> this@determineType.getArgumentExpression()?.determineType()
920-
else -> null
921-
}
922-
}
923-
}
924-
925-
private fun KtElement.determineTypeFromCall(): KaType? = withKaSession {
926-
this@determineTypeFromCall.resolveToCall()?.let {
927-
(it.successfulFunctionCallOrNull() ?: it.singleVariableAccessCall())
928-
?.partiallyAppliedSymbol?.symbol?.returnType
929-
}
930-
}
931-
932903
fun KotlinType.isSupertypeOf(other: KotlinType): Boolean {
933904
return findCorrespondingSupertype(other, this).let { it != null && it != other }
934905
}

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)