Skip to content

Commit 9e3fdca

Browse files
committed
Introduce line marker for wasm_bindgen attributes
1 parent d7636d7 commit 9e3fdca

File tree

3 files changed

+91
-31
lines changed

3 files changed

+91
-31
lines changed

js/src/main/kotlin/org/rust/js/MyReferenceContributor.kt

-26
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Use of this source code is governed by the MIT license that can be
3+
* found in the LICENSE file.
4+
*/
5+
6+
package org.rust.js
7+
8+
import com.intellij.codeHighlighting.Pass
9+
import com.intellij.codeInsight.daemon.DefaultGutterIconNavigationHandler
10+
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo
11+
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider
12+
import com.intellij.lang.javascript.psi.JSElement
13+
import com.intellij.lang.javascript.psi.ecma6.TypeScriptClass
14+
import com.intellij.lang.javascript.psi.ecma6.TypeScriptEnum
15+
import com.intellij.lang.javascript.psi.ecma6.TypeScriptFunction
16+
import com.intellij.navigation.GotoRelatedItem
17+
import com.intellij.openapi.editor.markup.GutterIconRenderer
18+
import com.intellij.openapi.vfs.LocalFileSystem
19+
import com.intellij.psi.PsiElement
20+
import com.intellij.psi.PsiFile
21+
import com.intellij.psi.PsiManager
22+
import com.intellij.psi.util.findDescendantOfType
23+
import com.intellij.psi.util.nextLeaf
24+
import com.intellij.util.ConstantFunction
25+
import org.rust.ide.icons.RsIcons
26+
import org.rust.lang.core.crate.crateGraph
27+
import org.rust.lang.core.psi.RsEnumItem
28+
import org.rust.lang.core.psi.RsFunction
29+
import org.rust.lang.core.psi.RsImplItem
30+
import org.rust.lang.core.psi.RsStructItem
31+
import org.rust.lang.core.psi.ext.RsOuterAttributeOwner
32+
import org.rust.lang.core.psi.ext.RsVisibilityOwner
33+
import org.rust.lang.core.psi.ext.containingCargoPackage
34+
import org.rust.lang.core.psi.ext.findOuterAttr
35+
import org.rust.lang.core.psi.impl.RsBaseTypeImpl
36+
import java.nio.file.Paths
37+
38+
class RsWasmBindgenLineMarkerProvider : RelatedItemLineMarkerProvider() {
39+
override fun getLineMarkerInfo(element: PsiElement): RelatedItemLineMarkerInfo<*>? {
40+
if (element.project.crateGraph.topSortedCrates.none { it.presentableName == "wasm-bindgen" }) return null
41+
if (element !is RsOuterAttributeOwner) return null
42+
if (element is RsVisibilityOwner && element !is RsImplItem && !element.isPublic) return null
43+
val attr = element.findOuterAttr("wasm_bindgen")
44+
?.nextLeaf() ?: return null
45+
46+
val cargoPackage = element.containingCargoPackage ?: return null
47+
val expectedName = cargoPackage.normName
48+
val basePath = cargoPackage.contentRoot?.path ?: return null
49+
50+
val expectedPath = Paths.get(basePath, "pkg/$expectedName.d.ts").toString()
51+
val tsFile = LocalFileSystem.getInstance().findFileByPath(expectedPath) ?: return null
52+
val tsPsiFile = PsiManager.getInstance(element.project).findFile(tsFile) ?: return null
53+
54+
val destination = when (element) {
55+
is RsImplItem -> findTsElementForImpl(element, tsPsiFile)
56+
else -> findTsElement(element, tsPsiFile)
57+
} ?: return null
58+
59+
// BACKCOMPAT: 2020.1
60+
@Suppress("DEPRECATION")
61+
return RelatedItemLineMarkerInfo(
62+
attr,
63+
attr.textRange,
64+
RsIcons.WASM_PACK,
65+
Pass.LINE_MARKERS,
66+
ConstantFunction<PsiElement, String>("wasm-bindgen declaration"),
67+
DefaultGutterIconNavigationHandler(listOf(destination), "wasm-bindgen declaration"),
68+
GutterIconRenderer.Alignment.RIGHT,
69+
listOf(GotoRelatedItem(destination))
70+
)
71+
}
72+
73+
private fun findTsElement(element: RsOuterAttributeOwner, tsPsiFile: PsiFile): JSElement? =
74+
when (element) {
75+
is RsFunction -> tsPsiFile.findDescendantOfType<TypeScriptFunction> { it.name == element.name }
76+
is RsEnumItem -> tsPsiFile.findDescendantOfType<TypeScriptEnum> { it.name == element.name }
77+
is RsStructItem -> tsPsiFile.findDescendantOfType<TypeScriptClass> { it.name == element.name }
78+
else -> null
79+
}
80+
81+
private fun findTsElementForImpl(element: RsImplItem, tsPsiFile: PsiFile): TypeScriptClass? {
82+
val reference = (element.typeReference as? RsBaseTypeImpl) ?: return null
83+
val struct = (reference.path?.reference?.resolve() as? RsStructItem) ?: return null
84+
val name = struct.name ?: return null
85+
86+
return tsPsiFile.findDescendantOfType {
87+
it.name == name
88+
}
89+
}
90+
}
+1-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
<idea-plugin>
22
<extensions defaultExtensionNs="com.intellij">
3-
<psi.referenceContributor language="JSON" implementation="org.rust.js.MyReferenceContributor"/>
3+
<codeInsight.lineMarkerProvider language="Rust" implementationClass="org.rust.js.RsWasmBindgenLineMarkerProvider"/>
44
</extensions>
55
</idea-plugin>
6-
7-
8-
9-

0 commit comments

Comments
 (0)