Skip to content

Commit a63049b

Browse files
committed
feat(rust): init basic documentation
1 parent 463dc13 commit a63049b

File tree

6 files changed

+88
-9
lines changed

6 files changed

+88
-9
lines changed

java/src/main/kotlin/cc/unitmesh/idea/provider/JavaLivingDocumentation.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ class JavaLivingDocumentation : LivingDocumentation {
7575

7676
}
7777

78-
private fun containsElement(selectionModel: SelectionModel, element: PsiElement): Boolean {
79-
return selectionModel.selectionStart <= element.textRange.startOffset && element.textRange.endOffset <= selectionModel.selectionEnd
80-
}
81-
8278
override fun findDocTargetsInSelection(
8379
root: PsiElement,
8480
selectionModel: SelectionModel,

kotlin/src/main/kotlin/cc/unitmesh/kotlin/provider/KotlinLivingDocumentation.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,6 @@ class KotlinLivingDocumentation : LivingDocumentation {
137137
})
138138
}
139139

140-
private fun containsElement(selectionModel: SelectionModel, element: PsiElement): Boolean {
141-
return selectionModel.selectionStart <= element.textRange.startOffset && element.textRange.endOffset <= selectionModel.selectionEnd
142-
}
143-
144140
override fun findDocTargetsInSelection(
145141
root: PsiElement,
146142
selectionModel: SelectionModel,

rust/src/main/kotlin/cc/unitmesh/rust/context/RustClassContextBuilder.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,25 @@ import com.intellij.psi.PsiElement
66
import org.rust.lang.core.psi.RsEnumItem
77
import org.rust.lang.core.psi.RsStructItem
88
import org.rust.lang.core.psi.ext.RsStructOrEnumItemElement
9+
import org.rust.lang.core.psi.ext.fields
910

1011
class RustClassContextBuilder : ClassContextBuilder {
1112
override fun getClassContext(psiElement: PsiElement, gatherUsages: Boolean): ClassContext? {
1213
if (psiElement !is RsStructOrEnumItemElement) return null
1314
when (psiElement) {
1415
is RsStructItem -> {
16+
val fields: List<PsiElement> = psiElement.fields.map {
17+
it.typeReference?.reference?.resolve() ?: it
18+
}
1519
return ClassContext(
1620
psiElement,
1721
psiElement.text,
1822
psiElement.name,
1923
emptyList(),
24+
fields,
2025
emptyList(),
2126
emptyList(),
22-
emptyList()
27+
psiElement.name
2328
)
2429
}
2530

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package cc.unitmesh.rust.provider
2+
3+
import cc.unitmesh.devti.custom.document.LivingDocumentationType
4+
import cc.unitmesh.devti.provider.LivingDocumentation
5+
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil
6+
import com.intellij.openapi.editor.Editor
7+
import com.intellij.openapi.editor.SelectionModel
8+
import com.intellij.psi.PsiElement
9+
import com.intellij.psi.PsiNameIdentifierOwner
10+
import com.intellij.psi.util.PsiTreeUtil
11+
import org.rust.lang.core.psi.RsFunction
12+
import org.rust.lang.core.psi.ext.RsNameIdentifierOwner
13+
import org.rust.lang.core.psi.ext.RsStructOrEnumItemElement
14+
15+
class RustLivingDocumentation : LivingDocumentation {
16+
override val forbiddenRules: List<String>
17+
get() = listOf()
18+
19+
override fun startEndString(type: LivingDocumentationType): Pair<String, String> {
20+
return Pair("///", "///")
21+
}
22+
23+
override fun updateDoc(target: PsiElement, newDoc: String, type: LivingDocumentationType, editor: Editor) {
24+
val project = target.project
25+
val file = target.containingFile
26+
val startOffset = target.textRange.startOffset
27+
val newEndOffset = startOffset + newDoc.length
28+
29+
editor.document.insertString(startOffset, newDoc)
30+
val codeStyleManager = com.intellij.psi.codeStyle.CodeStyleManager.getInstance(project)
31+
codeStyleManager.reformatText(file, startOffset, newEndOffset)
32+
}
33+
34+
override fun findNearestDocumentationTarget(psiElement: PsiElement): PsiNameIdentifierOwner? {
35+
if (psiElement is RsNameIdentifierOwner) return psiElement
36+
37+
val closestIdentifierOwner = PsiTreeUtil.getParentOfType(psiElement, PsiNameIdentifierOwner::class.java)
38+
if (closestIdentifierOwner !is RsFunction) {
39+
return PsiTreeUtil.getParentOfType(psiElement, RsFunction::class.java) ?: closestIdentifierOwner
40+
}
41+
42+
return closestIdentifierOwner
43+
}
44+
45+
override fun findDocTargetsInSelection(
46+
root: PsiElement,
47+
selectionModel: SelectionModel
48+
): List<PsiNameIdentifierOwner> {
49+
val commonParent: PsiElement? =
50+
CollectHighlightsUtil.findCommonParent(root, selectionModel.selectionStart, selectionModel.selectionEnd)
51+
52+
if (commonParent is RsStructOrEnumItemElement) {
53+
return listOf(commonParent)
54+
}
55+
56+
val nearestDocumentationTarget = findNearestDocumentationTarget(commonParent!!)
57+
if (nearestDocumentationTarget !is RsFunction ||
58+
containsElement(selectionModel, nearestDocumentationTarget)
59+
) {
60+
return listOf(nearestDocumentationTarget!!)
61+
}
62+
63+
val classDeclarations = nearestDocumentationTarget.children
64+
return filterAndCollectNameIdentifierOwners(classDeclarations, selectionModel)
65+
}
66+
67+
private fun filterAndCollectNameIdentifierOwners(
68+
declarations: Array<PsiElement>,
69+
selectionModel: SelectionModel,
70+
): List<PsiNameIdentifierOwner> {
71+
val filteredElements = declarations.filterIsInstance<PsiNameIdentifierOwner>()
72+
.filter { containsElement(selectionModel, it) }
73+
return filteredElements.toList()
74+
}
75+
}

rust/src/main/resources/cc.unitmesh.rust.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,9 @@
1616
<contextPrompter language="Rust" implementation="cc.unitmesh.rust.provider.RustContextPrompter"/>
1717

1818
<chatContextProvider implementation="cc.unitmesh.rust.provider.RustContextProvider"/>
19+
20+
<livingDocumentation language="Rust"
21+
implementationClass="cc.unitmesh.rust.provider.RustLivingDocumentation"/>
22+
1923
</extensions>
2024
</idea-plugin>

src/main/kotlin/cc/unitmesh/devti/provider/LivingDocumentation.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ interface LivingDocumentation {
2727
fun findNearestDocumentationTarget(psiElement: PsiElement): PsiNameIdentifierOwner?
2828

2929
fun findDocTargetsInSelection(root: PsiElement, selectionModel: SelectionModel): List<PsiNameIdentifierOwner>
30+
fun containsElement(selectionModel: SelectionModel, element: PsiElement): Boolean {
31+
return selectionModel.selectionStart <= element.textRange.startOffset && element.textRange.endOffset <= selectionModel.selectionEnd
32+
}
3033

3134
companion object {
3235
private val languageExtension: LanguageExtension<LivingDocumentation> =

0 commit comments

Comments
 (0)