You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am trying to create a custom rule that finds extension functions of Any, and reports them.
My rule is successful in finding:
fun Any.functions() =Unit
But it will not detect anything here:
fun <T:Any> T.functions() =UnittypealiasSomething=Anyfun Something.functions() =Unit
I have been playing around with the AST elements involved, but can not find anything giving me information on the type beyond just the plain text in the source code.
I will share my attempt below. For all special test cases (generics and typealiases), the function will return either while trying to get typeElement or while trying to get pleaseBeTypeParam. It never makes it past those points, and never reports.
@RequiresTypeResolution
classNoExtensionOfAnyExample(config:Config) : Rule(config) {
overrideval issue =DefaultIssue(
id = javaClass.simpleName,
severity =Warning,
description ="Extension functions on Any",
)
overridefunvisitNamedDeclaration(declaration:KtNamedDeclaration) {
super.visitNamedDeclaration(declaration)
val callable:KtCallableDeclaration?=when (declaration) {
isKtNamedFunction, isKtProperty-> declaration asKtCallableDeclarationisKtPropertyAccessor-> declaration.getNonStrictParentOfType<KtProperty>()
else->null
}
val receiverType:KtTypeReference= callable?.receiverTypeReference ?:returnval receiverTypeText = receiverType.text
if (receiverTypeText inBAD_RECEIVER_TYPES) {
report(
CodeSmell(
issue = issue,
entity =Entity.from(declaration),
message ="The declaration $declaration is an extension of $receiverTypeText"
)
)
return
}
val typeElement:KtUserType= receiverType.typeElement as?KtUserType?:returnval refExpression:KtSimpleNameExpression= typeElement.referenceExpression ?:returnval pleaseBeTypeParam:KtTypeParameter=
bindingContext[BindingContext.REFERENCE_TARGET, refExpression] as?KtTypeParameter?:returnval resolvedReceiverType:KotlinType= bindingContext[BindingContext.TYPE, receiverType] ?:returnval nullable = resolvedReceiverType.isMarkedNullable
val typeArgument = typeElement.typeArgumentList?.arguments?.firstOrNull() ?:returnval typeReference = typeArgument.typeReference ?:returnval ktTypeParam = typeReference.typeElement as?KtTypeParameter?:returnval typeConstraint = ktTypeParam.extendsBound
val typeConstraintText = typeConstraint?.text
if (typeConstraintText inBAD_RECEIVER_TYPES) {
report(
CodeSmell(
issue = issue,
entity =Entity.from(declaration),
message ="The declaration $declaration is a (generic) extension of $typeConstraintText"
)
)
return
} elseif (ktTypeParam.extendsBound ==null) {
report(
CodeSmell(
issue = issue,
entity =Entity.from(declaration),
message ="The declaration $declaration is a (generic) extension Any?"
)
)
}
}
companionobject {
valBAD_RECEIVER_TYPES=setOf("Any", "Any?")
}
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I am trying to create a custom rule that finds extension functions of Any, and reports them.
My rule is successful in finding:
But it will not detect anything here:
I have been playing around with the AST elements involved, but can not find anything giving me information on the type beyond just the plain text in the source code.
I will share my attempt below. For all special test cases (generics and typealiases), the function will return either while trying to get
typeElement
or while trying to getpleaseBeTypeParam
. It never makes it past those points, and never reports.Beta Was this translation helpful? Give feedback.
All reactions