1616package org.domaframework.doma.intellij.document
1717
1818import com.intellij.lang.documentation.AbstractDocumentationProvider
19- import com.intellij.openapi.project.Project
2019import com.intellij.psi.PsiElement
21- import com.intellij.psi.PsiFile
2220import com.intellij.psi.util.PsiTreeUtil
23- import org.domaframework.doma.intellij.common.dao.findDaoMethod
24- import org.domaframework.doma.intellij.common.psi.PsiDaoMethod
25- import org.domaframework.doma.intellij.common.psi.PsiParentClass
26- import org.domaframework.doma.intellij.common.psi.PsiStaticElement
27- import org.domaframework.doma.intellij.common.sql.foritem.ForItem
28- import org.domaframework.doma.intellij.common.util.ForDirectiveUtil
29- import org.domaframework.doma.intellij.extension.expr.accessElements
30- import org.domaframework.doma.intellij.extension.expr.accessElementsPrevOriginalElement
31- import org.domaframework.doma.intellij.extension.psi.findParameter
32- import org.domaframework.doma.intellij.extension.psi.getForItem
33- import org.domaframework.doma.intellij.extension.psi.psiClassType
34- import org.domaframework.doma.intellij.psi.SqlElClass
35- import org.domaframework.doma.intellij.psi.SqlElFieldAccessExpr
21+ import org.domaframework.doma.intellij.document.generator.DocumentDaoParameterGenerator
22+ import org.domaframework.doma.intellij.document.generator.DocumentStaticFieldGenerator
3623import org.domaframework.doma.intellij.psi.SqlElIdExpr
3724import org.domaframework.doma.intellij.psi.SqlElStaticFieldAccessExpr
3825import org.domaframework.doma.intellij.psi.SqlTypes
@@ -56,93 +43,26 @@ class ForItemElementDocumentationProvider : AbstractDocumentationProvider() {
5643
5744 val staticFieldAccessExpr =
5845 PsiTreeUtil .getParentOfType(originalElement, SqlElStaticFieldAccessExpr ::class .java)
59- if (staticFieldAccessExpr != null ) {
60- generateStaticFieldDocument(
61- staticFieldAccessExpr,
62- file,
63- originalElement,
64- project,
65- result,
66- )
67- } else {
68- generateDaoFieldAccessDocument(originalElement, project, result)
69- }
70- return result.joinToString(" \n " )
71- }
72-
73- private fun generateDaoFieldAccessDocument (
74- originalElement : PsiElement ,
75- project : Project ,
76- result : MutableList <String ?>,
77- ) {
78- var topParentType: PsiParentClass ? = null
79- val selfSkip = isSelfSkip(originalElement)
80- val forDirectives = ForDirectiveUtil .getForDirectiveBlocks(originalElement, selfSkip)
81- val fieldAccessExpr =
82- PsiTreeUtil .getParentOfType(
83- originalElement,
84- SqlElFieldAccessExpr ::class .java,
85- )
86- val fieldAccessBlocks =
87- fieldAccessExpr?.accessElementsPrevOriginalElement(originalElement.textOffset)
88- val searchElement = fieldAccessBlocks?.firstOrNull() ? : originalElement
89-
90- var isBatchAnnotation = false
91- if (ForDirectiveUtil .findForItem(searchElement, forDirectives = forDirectives) != null ) {
92- topParentType = ForDirectiveUtil .getForDirectiveItemClassType(project, forDirectives)
93- } else {
94- val daoMethod = findDaoMethod(originalElement.containingFile) ? : return
95- val param = daoMethod.findParameter(originalElement.text) ? : return
96- isBatchAnnotation = PsiDaoMethod (project, daoMethod).daoType.isBatchAnnotation()
97- topParentType = PsiParentClass (param.type)
98- }
99- if (fieldAccessExpr != null && fieldAccessBlocks != null ) {
100- topParentType?.let {
101- ForDirectiveUtil .getFieldAccessLastPropertyClassType(
102- fieldAccessBlocks,
46+ val generator =
47+ if (staticFieldAccessExpr != null ) {
48+ DocumentStaticFieldGenerator (
49+ originalElement,
50+ project,
51+ result,
52+ staticFieldAccessExpr,
53+ file,
54+ )
55+ } else {
56+ DocumentDaoParameterGenerator (
57+ originalElement,
10358 project,
104- it,
105- isBatchAnnotation = isBatchAnnotation,
106- complete = { lastType ->
107- result.add(" ${generateTypeLink(lastType)} ${originalElement.text} " )
108- },
59+ result,
10960 )
11061 }
111- return
112- }
113- result.add(" ${generateTypeLink(topParentType)} ${originalElement.text} " )
114- }
115-
116- private fun generateStaticFieldDocument (
117- staticFieldAccessExpr : SqlElStaticFieldAccessExpr ,
118- file : PsiFile ,
119- originalElement : PsiElement ,
120- project : Project ,
121- result : MutableList <String ?>,
122- ) {
123- val fieldAccessBlocks = staticFieldAccessExpr.accessElements
124- val staticElement = PsiStaticElement (fieldAccessBlocks, file)
125- val referenceClass = staticElement.getRefClazz() ? : return
126- if (PsiTreeUtil .getParentOfType(originalElement, SqlElClass ::class .java) != null ) {
127- val clazzType = PsiParentClass (referenceClass.psiClassType)
128- result.add(" ${generateTypeLink(clazzType)} ${originalElement.text} " )
129- return
130- }
13162
132- ForDirectiveUtil .getFieldAccessLastPropertyClassType(
133- fieldAccessBlocks.filter { it.textOffset <= originalElement.textOffset },
134- project,
135- PsiParentClass (referenceClass.psiClassType),
136- complete = { lastType ->
137- result.add(" ${generateTypeLink(lastType)} ${originalElement.text} " )
138- },
139- )
140- }
63+ generator.generateDocument()
14164
142- private fun isSelfSkip (targetElement : PsiElement ): Boolean {
143- val forItem = ForItem (targetElement)
144- val forDirectiveExpr = forItem.getParentForDirectiveExpr()
145- return ! (forDirectiveExpr != null && forDirectiveExpr.getForItem()?.textOffset == targetElement.textOffset)
65+ return result.joinToString(" \n " )
14666 }
14767
14868 override fun generateHoverDoc (
@@ -159,36 +79,4 @@ class ForItemElementDocumentationProvider : AbstractDocumentationProvider() {
15979 result.add(typeDocument)
16080 return result.joinToString(" \n " )
16181 }
162-
163- private fun generateTypeLink (parentClass : PsiParentClass ? ): String {
164- if (parentClass?.type != null ) {
165- return generateTypeLinkFromCanonicalText(parentClass.type.canonicalText)
166- }
167- return " "
168- }
169-
170- private fun generateTypeLinkFromCanonicalText (canonicalText : String ): String {
171- val regex = Regex (" ([a-zA-Z0-9_]+\\ .)*([a-zA-Z0-9_]+)" )
172- val result = StringBuilder ()
173- var lastIndex = 0
174-
175- for (match in regex.findAll(canonicalText)) {
176- val fullMatch = match.value
177- val typeName = match.groups[2 ]?.value ? : fullMatch
178- val startIndex = match.range.first
179- val endIndex = match.range.last + 1
180-
181- if (lastIndex < startIndex) {
182- result.append(canonicalText.substring(lastIndex, startIndex))
183- }
184- result.append(" <a href=\" psi_element://$fullMatch \" >$typeName </a>" )
185- lastIndex = endIndex
186- }
187-
188- if (lastIndex < canonicalText.length) {
189- result.append(canonicalText.substring(lastIndex))
190- }
191-
192- return result.toString()
193- }
19482}
0 commit comments