Skip to content

Commit

Permalink
Merge branch 'main' into chore/analytics
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcinVaadin authored Jan 3, 2025
2 parents eaaafcd + 5f6c57d commit 616da94
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 4 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ dependencies {
bundledPlugin("org.jetbrains.plugins.gradle")
bundledPlugin("com.intellij.properties")
bundledPlugin("com.intellij.microservices.jvm")
bundledPlugin("JavaScript")

pluginVerifier()
zipSigner()
Expand Down
34 changes: 34 additions & 0 deletions src/main/kotlin/com/vaadin/plugin/symbols/HillaSymbol.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.vaadin.plugin.symbols

import com.intellij.model.Pointer
import com.intellij.model.Symbol
import com.intellij.navigation.NavigatableSymbol
import com.intellij.navigation.SymbolNavigationService
import com.intellij.openapi.project.Project
import com.intellij.platform.backend.navigation.NavigationTarget
import com.intellij.psi.PsiElement

class HillaSymbol(private val target: PsiElement) : NavigatableSymbol {

override fun createPointer(): Pointer<out Symbol> {
return Pointer.hardPointer(this)
}

override fun getNavigationTargets(project: Project): Collection<NavigationTarget> {
if (target.project != project) return emptyList()
return listOf(SymbolNavigationService.getInstance().psiElementNavigationTarget(target))
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as HillaSymbol

return target == other.target
}

override fun hashCode(): Int {
return target.hashCode()
}
}
62 changes: 62 additions & 0 deletions src/main/kotlin/com/vaadin/plugin/symbols/HillaSymbolReference.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.vaadin.plugin.symbols

import com.intellij.model.Symbol
import com.intellij.model.psi.PsiSymbolReference
import com.intellij.openapi.util.TextRange
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectScope
import com.intellij.psi.search.searches.AnnotatedElementsSearch
import com.vaadin.plugin.endpoints.HILLA_BROWSER_CALLABLE

class HillaSymbolReference(private val element: PsiElement) : PsiSymbolReference {

override fun resolveReference(): Collection<Symbol> {
val hillaBrowserCallableClass =
JavaPsiFacade.getInstance(element.project)
.findClass(HILLA_BROWSER_CALLABLE, ProjectScope.getLibrariesScope(element.project)) ?: return emptySet()

val scope = GlobalSearchScope.allScope(element.project)

var className = element.text
var methodName: String? = null

// both ClassName and ClassName.methodName are JSReferenceExpressions
if (element.textContains('.')) {
element.text.split('.').let {
className = it[0]
methodName = it[1]
}
}

val psiClasses =
AnnotatedElementsSearch.searchPsiClasses(hillaBrowserCallableClass, scope).filter {
it.name?.endsWith(className) == true
}

if (psiClasses.isEmpty()) {
return emptySet()
}

if (methodName != null) {
return psiClasses
.mapNotNull { it.findMethodsByName(methodName, true).firstOrNull() }
.map { HillaSymbol(it) }
}

return psiClasses.map { HillaSymbol(it) }
}

override fun getElement(): PsiElement {
return element
}

override fun getRangeInElement(): TextRange {
val indexOfDot = element.text.indexOf('.')
if (indexOfDot != -1) {
return TextRange.from(indexOfDot + 1, element.text.length - indexOfDot)
}
return TextRange.allOf(element.text)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.vaadin.plugin.symbols

import com.intellij.lang.javascript.psi.JSReferenceExpression
import com.intellij.model.Symbol
import com.intellij.model.psi.PsiExternalReferenceHost
import com.intellij.model.psi.PsiSymbolReference
import com.intellij.model.psi.PsiSymbolReferenceHints
import com.intellij.model.psi.PsiSymbolReferenceProvider
import com.intellij.model.search.SearchRequest
import com.intellij.openapi.project.Project

internal class HillaSymbolReferenceProvider : PsiSymbolReferenceProvider {

override fun getReferences(
host: PsiExternalReferenceHost,
hints: PsiSymbolReferenceHints
): Collection<PsiSymbolReference> {
if (host !is JSReferenceExpression) {
return emptyList()
}

return listOf(HillaSymbolReference(host))
}

override fun getSearchRequests(project: Project, symbol: Symbol): Collection<SearchRequest> {
return emptyList()
}
}
14 changes: 10 additions & 4 deletions src/main/kotlin/com/vaadin/plugin/ui/VaadinStatusBarWidget.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.vaadin.plugin.ui
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.wm.StatusBarWidget
import com.intellij.openapi.wm.WindowManager
import com.intellij.ui.IconManager
Expand All @@ -13,6 +14,7 @@ import com.intellij.util.ui.UIUtil
import com.vaadin.plugin.copilot.CopilotPluginUtil
import com.vaadin.plugin.utils.VaadinIcons
import com.vaadin.plugin.utils.hasEndpoints
import java.awt.Point
import java.awt.event.MouseEvent
import javax.swing.Icon

Expand Down Expand Up @@ -55,19 +57,23 @@ class VaadinStatusBarWidget(private val project: Project) : StatusBarWidget, Sta
override fun getClickConsumer(): Consumer<MouseEvent> {
return Consumer {
clicked = true
showPopup(RelativePoint.fromScreen(it.locationOnScreen))
showPopup(it)
update(project)
}
}

private fun showPopup(relativePoint: RelativePoint) {
private fun showPopup(e: MouseEvent) {
val panel = VaadinStatusBarInfoPopupPanel(project)
val popup = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, null).createPopup()
panel.afterRestart = {
popup.cancel()
showPopup(relativePoint)
showPopup(e)
}
popup.show(relativePoint)
val dimension = popup.content.preferredSize
val at = Point(0, -dimension.height)
popup.show(RelativePoint(e.component, at))
// destroy popup on unexpected project close
Disposer.register(this, popup)
}

override fun getTooltipText(): String {
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<depends optional="true" config-file="vaadin-with-microservices.xml">com.intellij.modules.microservices</depends>
<depends optional="true" config-file="vaadin-with-microservices-jvm.xml">com.intellij.microservices.jvm</depends>
<depends optional="true" config-file="vaadin-with-ultimate.xml">com.intellij.modules.ultimate</depends>
<depends optional="true" config-file="vaadin-with-javascript.xml">JavaScript</depends>

<change-notes>
<![CDATA[
Expand Down
11 changes: 11 additions & 0 deletions src/main/resources/META-INF/vaadin-with-javascript.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<idea-plugin>

<extensions defaultExtensionNs="com.intellij">
<psi.symbolReferenceProvider hostLanguage="TypeScript"
hostElementClass="com.intellij.lang.javascript.psi.JSReferenceExpression"
referenceClass="com.vaadin.plugin.symbols.HillaSymbolReference"
targetClass="com.vaadin.plugin.symbols.HillaSymbol"
implementationClass="com.vaadin.plugin.symbols.HillaSymbolReferenceProvider"/>
</extensions>

</idea-plugin>

0 comments on commit 616da94

Please sign in to comment.