1
+ package org.tabooproject.intellij.suppressor
2
+
3
+ import com.intellij.codeInspection.InspectionSuppressor
4
+ import com.intellij.codeInspection.SuppressQuickFix
5
+ import com.intellij.psi.PsiElement
6
+ import com.intellij.psi.util.PsiTreeUtil
7
+ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
8
+ import org.jetbrains.kotlin.psi.KtClassOrObject
9
+ import org.jetbrains.kotlin.psi.KtTypeReference
10
+ import org.jetbrains.kotlin.resolve.BindingContext
11
+ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
12
+ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
13
+
14
+ private const val INSPECTION = " unused"
15
+
16
+ private val classes = listOf (
17
+ " taboolib.platform.compat.PlaceholderExpansion" ,
18
+ " taboolib.common.platform.Plugin" ,
19
+ )
20
+
21
+ class ExpansionUnusedSuppressor : InspectionSuppressor {
22
+ override fun isSuppressedFor (element : PsiElement , toolId : String ): Boolean {
23
+ if (toolId != INSPECTION ) {
24
+ return false
25
+ }
26
+
27
+ return classes.any { className ->
28
+ checkIfClassImplementsOrExtends(element, className)
29
+ }
30
+ }
31
+
32
+ override fun getSuppressActions (element : PsiElement ? , toolId : String ): Array <SuppressQuickFix > =
33
+ SuppressQuickFix .EMPTY_ARRAY
34
+
35
+ private fun checkIfClassImplementsOrExtends (element : PsiElement , className : String ): Boolean {
36
+ val ktClass = PsiTreeUtil .getParentOfType(element, KtClassOrObject ::class .java) ? : return false
37
+ val context = ktClass.getResolutionFacade().analyze(ktClass, BodyResolveMode .FULL )
38
+ return ktClass.implementsInterface(className, context) || ktClass.isSubclassOf(className, context)
39
+ }
40
+
41
+ private fun KtClassOrObject.isSubclassOf (className : String , context : BindingContext ): Boolean {
42
+ if (fqName?.asString() == className) return true
43
+
44
+ val superTypes = this .superTypeListEntries
45
+ return superTypes.any { typeEntry ->
46
+ val typeReference = typeEntry.typeReference
47
+ val typeFqName = typeReference?.getFqName(context)
48
+ typeFqName == className
49
+ }
50
+ }
51
+
52
+ private fun KtClassOrObject.implementsInterface (interfaceName : String , context : BindingContext ): Boolean {
53
+ if (isSubclassOf(interfaceName, context)) return true
54
+
55
+ val superTypes = this .superTypeListEntries
56
+ return superTypes.any { typeEntry ->
57
+ val typeReference = typeEntry.typeReference
58
+ val typeFqName = typeReference?.getFqName(context)
59
+ typeFqName == interfaceName
60
+ }
61
+ }
62
+
63
+ private fun KtTypeReference.getFqName (context : BindingContext ): String? {
64
+ val type = context[BindingContext .TYPE , this ]
65
+ return type?.constructor ?.declarationDescriptor?.fqNameSafe?.asString()
66
+ }
67
+ }
0 commit comments