1
+ package org.tabooproject.development.inspection
2
+
3
+ import com.intellij.codeInspection.*
4
+ import com.intellij.openapi.project.Project
5
+ import org.jetbrains.kotlin.descriptors.ClassDescriptor
6
+ import org.jetbrains.kotlin.idea.caches.resolve.analyze
7
+ import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection
8
+ import org.jetbrains.kotlin.psi.*
9
+ import org.jetbrains.kotlin.resolve.BindingContext
10
+ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
11
+ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
12
+
13
+ class DatabaseWorkspaceInspection : AbstractKotlinInspection () {
14
+ override fun buildVisitor (holder : ProblemsHolder , isOnTheFly : Boolean ): KtVisitorVoid {
15
+ return object : KtVisitorVoid () {
16
+ override fun visitCallExpression (expression : KtCallExpression ) {
17
+ super .visitCallExpression(expression)
18
+ val calleeExpression = expression.calleeExpression?.text
19
+ if (calleeExpression == " workspace" ) {
20
+ val qualifiedExpression = expression.parent as ? KtDotQualifiedExpression
21
+ val receiverExpression = qualifiedExpression?.receiverExpression
22
+ val context = receiverExpression?.analyze(BodyResolveMode .PARTIAL )
23
+ val type = context?.get(BindingContext .EXPRESSION_TYPE_INFO , receiverExpression)?.type
24
+ val classDescriptor = type?.constructor ?.declarationDescriptor as ? ClassDescriptor
25
+ val fqName = classDescriptor?.fqNameSafe?.asString()
26
+
27
+ if (fqName != " taboolib.module.database.Table" ) return
28
+
29
+ val parent = expression.parent
30
+
31
+ if (parent is KtDotQualifiedExpression ) {
32
+ val grandParent = parent.parent
33
+ if (grandParent is KtBlockExpression ) {
34
+ val hasRunCall = grandParent.statements.any {
35
+ it is KtCallExpression && it.calleeExpression != null
36
+ }
37
+ if (! hasRunCall) {
38
+ holder.registerProblem(
39
+ expression,
40
+ " Calling 'workspace' without any method" ,
41
+ ProblemHighlightType .WARNING ,
42
+ AddRunQuickFix ()
43
+ )
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ class AddRunQuickFix : LocalQuickFix {
53
+ override fun getName () = " Add 'run' method after workspace"
54
+ override fun getFamilyName () = name
55
+
56
+ override fun applyFix (project : Project , descriptor : ProblemDescriptor ) {
57
+ val element = descriptor.psiElement
58
+ val parent = element.parent
59
+ if (parent is KtDotQualifiedExpression ) {
60
+ val factory = KtPsiFactory (project)
61
+ val newExpression = factory.createExpression(" ${parent.text} .run()" )
62
+ parent.replace(newExpression)
63
+ }
64
+ }
65
+ }
66
+ }
0 commit comments