@@ -4,15 +4,20 @@ import cc.unitmesh.devti.custom.document.LivingDocumentationType
4
4
import cc.unitmesh.devti.provider.LivingDocumentation
5
5
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil
6
6
import com.intellij.lang.ecmascript6.psi.ES6ExportDefaultAssignment
7
+ import com.intellij.lang.ecmascript6.psi.ES6ImportSpecifier
8
+ import com.intellij.lang.ecmascript6.psi.ES6ImportSpecifierAlias
9
+ import com.intellij.lang.ecmascript6.psi.ES6ImportedBinding
7
10
import com.intellij.lang.javascript.psi.*
8
- import com.intellij.lang.javascript.psi.ecma6.TypeScriptObjectType
11
+ import com.intellij.lang.javascript.psi.ecma6.TypeScriptModule
9
12
import com.intellij.lang.javascript.psi.ecmal4.JSClass
13
+ import com.intellij.lang.javascript.psi.util.JSStubBasedPsiTreeUtil
10
14
import com.intellij.lang.javascript.psi.util.JSUtils
11
15
import com.intellij.openapi.editor.Editor
12
16
import com.intellij.openapi.editor.SelectionModel
13
17
import com.intellij.psi.PsiElement
18
+ import com.intellij.psi.PsiFile
14
19
import com.intellij.psi.PsiNameIdentifierOwner
15
- import com.intellij.psi.PsiWhiteSpace
20
+ import com.intellij.psi.ResolveState
16
21
import com.intellij.psi.util.PsiTreeUtil
17
22
import com.intellij.psi.util.parentOfTypes
18
23
@@ -52,12 +57,15 @@ class JavaScriptLivingDocumentation : LivingDocumentation {
52
57
}
53
58
}
54
59
}
60
+
55
61
is ES6ExportDefaultAssignment -> {
56
62
candidate = psiElement.expression
57
63
}
64
+
58
65
is JSProperty , is JSFunction , is JSVariable , is JSClass , is JSField -> {
59
66
candidate = psiElement
60
67
}
68
+
61
69
is JSVarStatement -> {
62
70
val variables = psiElement.variables
63
71
if (variables.isNotEmpty()) {
@@ -73,16 +81,59 @@ class JavaScriptLivingDocumentation : LivingDocumentation {
73
81
root : PsiElement ,
74
82
selectionModel : SelectionModel
75
83
): List <PsiNameIdentifierOwner > {
76
- val findCommonParent = CollectHighlightsUtil .findCommonParent(
84
+ val commonParent = CollectHighlightsUtil .findCommonParent(
77
85
root,
78
86
selectionModel.selectionStart,
79
87
selectionModel.selectionEnd
80
88
) ? : return emptyList()
81
89
82
- return emptyList()
90
+ val decls: MutableList <PsiNameIdentifierOwner > = mutableListOf ()
91
+ JSStubBasedPsiTreeUtil .processDeclarationsInScope(
92
+ commonParent,
93
+ { element: PsiElement , _: ResolveState ->
94
+ if (element is PsiNameIdentifierOwner ) {
95
+ decls.add(element)
96
+ }
97
+ true
98
+ },
99
+ true
100
+ )
101
+
102
+ val list = decls.filter {
103
+ containsElement(selectionModel, it as PsiElement )
104
+ && isMeaningfulToDocumentInSelection(it as PsiElement )
105
+ }.toList()
106
+
107
+ return list.ifEmpty {
108
+ listOfNotNull(findNearestDocumentationTarget(commonParent))
109
+ }
83
110
}
84
111
85
112
private fun containsElement (selectionModel : SelectionModel , element : PsiElement ): Boolean {
86
113
return selectionModel.selectionStart <= element.textRange.startOffset && element.textRange.endOffset <= selectionModel.selectionEnd
87
114
}
115
+
116
+ private fun isMeaningfulToDocumentInSelection (element : PsiElement ? ): Boolean {
117
+ if ((element is ES6ImportedBinding ) || (element is ES6ImportSpecifierAlias ) || (element is ES6ImportSpecifier )) {
118
+ return false
119
+ }
120
+
121
+ if (element is JSVariable && ! JSUtils .isMember(element)) {
122
+ val initializerOrStub = element.initializerOrStub
123
+ if (initializerOrStub is JSFunctionExpression ) {
124
+ return true
125
+ }
126
+
127
+ if (initializerOrStub is JSCallExpression && initializerOrStub.isRequireCall) {
128
+ return false
129
+ }
130
+
131
+ val parentOfType = PsiTreeUtil .getParentOfType(element, JSSourceElement ::class .java, true )
132
+ val scope = parentOfType?.parent
133
+
134
+ return scope is PsiFile || scope is JSEmbeddedContent || scope is TypeScriptModule
135
+ }
136
+
137
+ return true
138
+ }
88
139
}
0 commit comments