From 688591e0233a1f03414cdbbfdd08ac325226e8e1 Mon Sep 17 00:00:00 2001 From: marcin Date: Wed, 20 Nov 2024 13:49:32 +0100 Subject: [PATCH 1/4] Vaadin Endpoints integration --- build.gradle.kts | 4 +- .../endpoints/VaadinEndpointsProvider.kt | 68 ++++++++++++ .../endpoints/VaadinImplicitUsageProvider.kt | 31 ++++++ .../vaadin/plugin/endpoints/VaadinModel.kt | 47 ++++++++ .../endpoints/VaadinReferenceContributor.kt | 43 ++++++++ .../vaadin/plugin/endpoints/VaadinRoute.kt | 11 ++ .../plugin/endpoints/VaadinUrlResolver.kt | 103 ++++++++++++++++++ src/main/resources/META-INF/plugin.xml | 15 +++ 8 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/com/vaadin/plugin/endpoints/VaadinEndpointsProvider.kt create mode 100644 src/main/kotlin/com/vaadin/plugin/endpoints/VaadinImplicitUsageProvider.kt create mode 100644 src/main/kotlin/com/vaadin/plugin/endpoints/VaadinModel.kt create mode 100644 src/main/kotlin/com/vaadin/plugin/endpoints/VaadinReferenceContributor.kt create mode 100644 src/main/kotlin/com/vaadin/plugin/endpoints/VaadinRoute.kt create mode 100644 src/main/kotlin/com/vaadin/plugin/endpoints/VaadinUrlResolver.kt diff --git a/build.gradle.kts b/build.gradle.kts index 0aa8fad..ada1033 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -44,10 +44,12 @@ repositories { dependencies { intellijPlatform { - create("IC", "2023.3") + create("IU", "2023.3") bundledPlugin("com.intellij.java") bundledPlugin("org.jetbrains.idea.maven") bundledPlugin("org.jetbrains.plugins.gradle") + bundledPlugin("com.intellij.properties") + bundledPlugin("com.intellij.microservices.jvm") pluginVerifier() zipSigner() diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinEndpointsProvider.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinEndpointsProvider.kt new file mode 100644 index 0000000..d542acd --- /dev/null +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinEndpointsProvider.kt @@ -0,0 +1,68 @@ +package com.vaadin.plugin.endpoints + +import com.intellij.microservices.endpoints.* +import com.intellij.microservices.endpoints.EndpointsProvider.Status +import com.intellij.microservices.endpoints.presentation.HttpUrlPresentation +import com.intellij.microservices.url.UrlPath +import com.intellij.navigation.ItemPresentation +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.ModificationTracker +import com.intellij.psi.PsiElement +import com.intellij.uast.UastModificationTracker +import com.vaadin.plugin.utils.VaadinIcons + +internal class VaadinEndpointsProvider : EndpointsProvider { + override val endpointType: EndpointType = HTTP_SERVER_TYPE + + override val presentation: FrameworkPresentation = + FrameworkPresentation("Vaadin", "Vaadin Flow", VaadinIcons.VAADIN_BLUE) + + override fun getStatus(project: Project): Status { + if (hasVaadinFlow(project)) return Status.HAS_ENDPOINTS + + return Status.UNAVAILABLE + } + + override fun getModificationTracker(project: Project): ModificationTracker { + return UastModificationTracker.getInstance(project) + } + + override fun getEndpointGroups(project: Project, filter: EndpointsFilter): Iterable { + if (filter !is ModuleEndpointsFilter) return emptyList() + if (!hasVaadinFlow(filter.module)) return emptyList() + + return findVaadinRoutes(project, filter.transitiveSearchScope) + } + + override fun getEndpoints(group: VaadinRoute): Iterable { + return listOf(group) + } + + override fun isValidEndpoint(group: VaadinRoute, endpoint: VaadinRoute): Boolean { + return group.isValid() + } + + override fun getEndpointPresentation(group: VaadinRoute, endpoint: VaadinRoute): ItemPresentation { + return HttpUrlPresentation(normalizeUrl(group.urlMapping), group.locationString, VaadinIcons.VAADIN_BLUE) + } + + private fun normalizeUrl(urlMapping: String): String { + val urlString = run { + if (urlMapping.isBlank()) return@run "/" + if (!urlMapping.startsWith("/")) return@run "/$urlMapping" + return@run urlMapping + } + + return parseVaadinUrlMapping(urlString).getPresentation(VaadinUrlRenderer) + } + + override fun getDocumentationElement(group: VaadinRoute, endpoint: VaadinRoute): PsiElement? { + return endpoint.anchor.retrieve() + } +} + +private object VaadinUrlRenderer : UrlPath.PathSegmentRenderer { + override fun visitVariable(variable: UrlPath.PathSegment.Variable): String { + return "{${variable.variableName}}" + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinImplicitUsageProvider.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinImplicitUsageProvider.kt new file mode 100644 index 0000000..16f900f --- /dev/null +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinImplicitUsageProvider.kt @@ -0,0 +1,31 @@ +package com.vaadin.plugin.endpoints + +import com.intellij.codeInsight.AnnotationUtil +import com.intellij.codeInsight.daemon.ImplicitUsageProvider +import com.intellij.lang.jvm.JvmModifier +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiField +import com.intellij.psi.util.InheritanceUtil + +internal class VaadinImplicitUsageProvider : ImplicitUsageProvider { + override fun isImplicitUsage(element: PsiElement): Boolean { + return element is PsiClass + && !element.isInterface + && !element.isEnum + && !element.hasModifier(JvmModifier.ABSTRACT) + && !element.isAnnotationType + && (AnnotationUtil.isAnnotated(element, VAADIN_ROUTE, 0) + || AnnotationUtil.isAnnotated(element, VAADIN_TAG, 0) + || InheritanceUtil.isInheritor(element, VAADIN_APP_SHELL_CONFIGURATOR)) + } + + override fun isImplicitRead(element: PsiElement): Boolean { + return false + } + + override fun isImplicitWrite(element: PsiElement): Boolean { + return element is PsiField + && AnnotationUtil.isAnnotated(element, VAADIN_ID, 0) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinModel.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinModel.kt new file mode 100644 index 0000000..654fbaf --- /dev/null +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinModel.kt @@ -0,0 +1,47 @@ +package com.vaadin.plugin.endpoints + +import com.intellij.java.library.JavaLibraryUtil.hasLibraryClass +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.psi.JavaPsiFacade +import com.intellij.psi.PsiAnchor +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.search.ProjectScope +import com.intellij.psi.search.searches.AnnotatedElementsSearch +import com.intellij.util.Processor +import org.jetbrains.uast.UClass +import org.jetbrains.uast.evaluateString +import org.jetbrains.uast.toUElementOfType + +internal const val VAADIN_ROUTE = "com.vaadin.flow.router.Route" +internal const val VAADIN_APP_SHELL_CONFIGURATOR = "com.vaadin.flow.component.page.AppShellConfigurator" +internal const val VAADIN_ID = "com.vaadin.flow.component.template.Id" +internal const val VAADIN_TAG = "com.vaadin.flow.component.Tag" + +internal fun hasVaadinFlow(project: Project): Boolean = hasLibraryClass(project, VAADIN_ROUTE) + +internal fun hasVaadinFlow(module: Module): Boolean = hasLibraryClass(module, VAADIN_ROUTE) + +internal fun findVaadinRoutes(project: Project, scope: GlobalSearchScope): Collection { + val vaadinRouteClass = JavaPsiFacade.getInstance(project) + .findClass(VAADIN_ROUTE, ProjectScope.getLibrariesScope(project)) ?: return emptyList() + + val routes = ArrayList() + + AnnotatedElementsSearch.searchPsiClasses(vaadinRouteClass, scope).forEach(Processor { psiClass -> + val uClass = psiClass.toUElementOfType() + val sourcePsi = uClass?.sourcePsi + val className = psiClass.name + + if (sourcePsi == null || className == null) return@Processor true + val uAnnotation = uClass.findAnnotation(VAADIN_ROUTE) ?: return@Processor true + + val urlMapping = uAnnotation.findAttributeValue("value")?.evaluateString() ?: "" + + routes.add(VaadinRoute(urlMapping, className, PsiAnchor.create(sourcePsi))) + + true + }) + + return routes.toList() +} diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinReferenceContributor.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinReferenceContributor.kt new file mode 100644 index 0000000..77dc987 --- /dev/null +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinReferenceContributor.kt @@ -0,0 +1,43 @@ +package com.vaadin.plugin.endpoints + +import com.intellij.codeInsight.highlighting.HighlightedReference +import com.intellij.lang.properties.references.PropertyReference +import com.intellij.microservices.jvm.url.uastUrlPathReferenceInjectorForScheme +import com.intellij.microservices.jvm.url.uastUrlReferenceProvider +import com.intellij.microservices.url.HTTP_SCHEMES +import com.intellij.patterns.PsiJavaPatterns.psiMethod +import com.intellij.patterns.uast.callExpression +import com.intellij.patterns.uast.injectionHostUExpression +import com.intellij.psi.* +import com.intellij.util.ProcessingContext +import org.jetbrains.uast.UElement +import org.jetbrains.uast.expressions.UInjectionHost + +internal class VaadinReferenceContributor : PsiReferenceContributor() { + override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) { + registrar.registerUastReferenceProvider( + injectionHostUExpression() + .annotationParam(VAADIN_ROUTE, "value"), + uastUrlReferenceProvider(uastUrlPathReferenceInjectorForScheme(HTTP_SCHEMES, vaadinUrlPksParser)) + ) + + registrar.registerUastReferenceProvider( + injectionHostUExpression() + .callParameter(0, callExpression() + .withMethodName("getTranslation") + .withAnyResolvedMethod(psiMethod() + .withName("getTranslation") + .definedInClass("com.vaadin.flow.component.Component"))), + object : UastReferenceProvider() { + override fun getReferencesByElement(element: UElement, context: ProcessingContext): Array { + if (element !is UInjectionHost) return PsiReference.EMPTY_ARRAY + val key = element.evaluateToString() ?: return PsiReference.EMPTY_ARRAY + val sourcePsi = element.sourcePsi ?: return PsiReference.EMPTY_ARRAY + + return arrayOf(object : PropertyReference(key, sourcePsi, null, false), HighlightedReference { + }) + } + } + ) + } +} diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinRoute.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinRoute.kt new file mode 100644 index 0000000..84b9c09 --- /dev/null +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinRoute.kt @@ -0,0 +1,11 @@ +package com.vaadin.plugin.endpoints + +import com.intellij.psi.PsiAnchor + +internal class VaadinRoute( + val urlMapping: String, + val locationString: String, + val anchor: PsiAnchor +) { + fun isValid(): Boolean = anchor.retrieve() != null +} diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinUrlResolver.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinUrlResolver.kt new file mode 100644 index 0000000..048ef40 --- /dev/null +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinUrlResolver.kt @@ -0,0 +1,103 @@ +package com.vaadin.plugin.endpoints + +import com.intellij.microservices.jvm.cache.ModuleCacheValueHolder +import com.intellij.microservices.jvm.cache.SourceLibSearchProvider +import com.intellij.microservices.jvm.cache.UastCachedSearchUtils.sequenceWithCache +import com.intellij.microservices.url.* +import com.intellij.microservices.url.UrlPath.PathSegment +import com.intellij.microservices.url.references.UrlPksParser +import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiAnchor +import com.intellij.psi.PsiElement +import com.intellij.psi.util.PartiallyKnownString +import com.intellij.psi.util.SplitEscaper +import com.vaadin.plugin.utils.VaadinIcons +import javax.swing.Icon + +internal class VaadinUrlResolverFactory : UrlResolverFactory { + override fun forProject(project: Project): UrlResolver? { + return if (hasVaadinFlow(project)) VaadinUrlResolver(project) else null + } +} + +internal class VaadinUrlResolver(private val project: Project) : UrlResolver { + override val supportedSchemes: List + get() = HTTP_SCHEMES + + override fun getVariants(): Iterable { + return getAllModuleVariants(project) + .asIterable() + } + + override fun resolve(request: UrlResolveRequest): Iterable { + if (request.method != HttpMethods.GET) return emptyList() + + val allModuleVariants = getAllModuleVariants(project) + .toList() + + return UrlPath.combinations(request.path) + .flatMap { path -> + allModuleVariants.asSequence() + .filter { it.path.isCompatibleWith(path) } + } + .asIterable() + } +} + +internal val VAADIN_ROUTES_SEARCH: SourceLibSearchProvider, Module> = + SourceLibSearchProvider("VAADIN_ROUTES") { p, _, scope -> + findVaadinRoutes(p, scope).toList() + } + +private fun getAllModuleVariants(project: Project): Sequence { + val modules = ModuleManager.getInstance(project).modules + + return modules.asSequence() + .flatMap(::getVariants) + .map(::VaadinUrlTargetInfo) +} + +private fun getVariants(module: Module): Sequence { + if (!hasVaadinFlow(module)) return emptySequence() + + return sequenceWithCache(ModuleCacheValueHolder(module), VAADIN_ROUTES_SEARCH) +} + +private class VaadinUrlTargetInfo(route: VaadinRoute) : UrlTargetInfo { + private val anchor: PsiAnchor = route.anchor + + override val authorities: List + get() = emptyList() + + override val path: UrlPath = parseVaadinUrlMapping(route.urlMapping) + + override val icon: Icon + get() = VaadinIcons.VAADIN_BLUE + + override val schemes: List + get() = HTTP_SCHEMES + + override fun resolveToPsiElement(): PsiElement? = anchor.retrieve() +} + +internal val vaadinUrlPksParser: UrlPksParser = UrlPksParser( + splitEscaper = { _, _ -> SplitEscaper.AcceptAll }, + customPathSegmentExtractor = { part -> + if (part.startsWith(":")) { + val varName = part.removePrefix(":") + .substringBefore("?") + .substringBefore("(") + PathSegment.Variable(varName) + } else { + PathSegment.Exact(part) + } + } +) + +internal fun parseVaadinUrlMapping(urlMapping: String): UrlPath { + return vaadinUrlPksParser + .parseUrlPath(PartiallyKnownString(urlMapping)) + .urlPath +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index d235172..f76e4dce 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -28,6 +28,13 @@ org.jetbrains.idea.maven org.jetbrains.plugins.gradle + com.intellij.properties + + + com.intellij.modules.microservices + com.intellij.microservices.jvm + com.intellij.modules.ultimate + Check release notes at GitHub for more information.

@@ -71,6 +78,14 @@ + + + + + + + + From 37c5a160c1fe0c7e2c6912e7b523418539f8e0cd Mon Sep 17 00:00:00 2001 From: marcin Date: Wed, 20 Nov 2024 13:51:50 +0100 Subject: [PATCH 2/4] deps update --- src/main/resources/META-INF/plugin.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index f76e4dce..d2447b0 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -28,12 +28,12 @@ org.jetbrains.idea.maven org.jetbrains.plugins.gradle - com.intellij.properties - com.intellij.modules.microservices - com.intellij.microservices.jvm - com.intellij.modules.ultimate + com.intellij.properties + com.intellij.modules.microservices + com.intellij.microservices.jvm + com.intellij.modules.ultimate Date: Wed, 20 Nov 2024 14:14:32 +0100 Subject: [PATCH 3/4] spotless --- .../endpoints/VaadinEndpointsProvider.kt | 2 +- .../endpoints/VaadinImplicitUsageProvider.kt | 21 ++++----- .../vaadin/plugin/endpoints/VaadinModel.kt | 27 ++++++----- .../endpoints/VaadinReferenceContributor.kt | 30 ++++++------ .../vaadin/plugin/endpoints/VaadinRoute.kt | 6 +-- .../plugin/endpoints/VaadinUrlResolver.kt | 47 +++++++------------ 6 files changed, 60 insertions(+), 73 deletions(-) diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinEndpointsProvider.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinEndpointsProvider.kt index d542acd..6aa0f1a 100644 --- a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinEndpointsProvider.kt +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinEndpointsProvider.kt @@ -65,4 +65,4 @@ private object VaadinUrlRenderer : UrlPath.PathSegmentRenderer { override fun visitVariable(variable: UrlPath.PathSegment.Variable): String { return "{${variable.variableName}}" } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinImplicitUsageProvider.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinImplicitUsageProvider.kt index 16f900f..11357c2 100644 --- a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinImplicitUsageProvider.kt +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinImplicitUsageProvider.kt @@ -10,14 +10,14 @@ import com.intellij.psi.util.InheritanceUtil internal class VaadinImplicitUsageProvider : ImplicitUsageProvider { override fun isImplicitUsage(element: PsiElement): Boolean { - return element is PsiClass - && !element.isInterface - && !element.isEnum - && !element.hasModifier(JvmModifier.ABSTRACT) - && !element.isAnnotationType - && (AnnotationUtil.isAnnotated(element, VAADIN_ROUTE, 0) - || AnnotationUtil.isAnnotated(element, VAADIN_TAG, 0) - || InheritanceUtil.isInheritor(element, VAADIN_APP_SHELL_CONFIGURATOR)) + return element is PsiClass && + !element.isInterface && + !element.isEnum && + !element.hasModifier(JvmModifier.ABSTRACT) && + !element.isAnnotationType && + (AnnotationUtil.isAnnotated(element, VAADIN_ROUTE, 0) || + AnnotationUtil.isAnnotated(element, VAADIN_TAG, 0) || + InheritanceUtil.isInheritor(element, VAADIN_APP_SHELL_CONFIGURATOR)) } override fun isImplicitRead(element: PsiElement): Boolean { @@ -25,7 +25,6 @@ internal class VaadinImplicitUsageProvider : ImplicitUsageProvider { } override fun isImplicitWrite(element: PsiElement): Boolean { - return element is PsiField - && AnnotationUtil.isAnnotated(element, VAADIN_ID, 0) + return element is PsiField && AnnotationUtil.isAnnotated(element, VAADIN_ID, 0) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinModel.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinModel.kt index 654fbaf..dcfad44 100644 --- a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinModel.kt +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinModel.kt @@ -23,25 +23,28 @@ internal fun hasVaadinFlow(project: Project): Boolean = hasLibraryClass(project, internal fun hasVaadinFlow(module: Module): Boolean = hasLibraryClass(module, VAADIN_ROUTE) internal fun findVaadinRoutes(project: Project, scope: GlobalSearchScope): Collection { - val vaadinRouteClass = JavaPsiFacade.getInstance(project) - .findClass(VAADIN_ROUTE, ProjectScope.getLibrariesScope(project)) ?: return emptyList() + val vaadinRouteClass = + JavaPsiFacade.getInstance(project).findClass(VAADIN_ROUTE, ProjectScope.getLibrariesScope(project)) + ?: return emptyList() val routes = ArrayList() - AnnotatedElementsSearch.searchPsiClasses(vaadinRouteClass, scope).forEach(Processor { psiClass -> - val uClass = psiClass.toUElementOfType() - val sourcePsi = uClass?.sourcePsi - val className = psiClass.name + AnnotatedElementsSearch.searchPsiClasses(vaadinRouteClass, scope) + .forEach( + Processor { psiClass -> + val uClass = psiClass.toUElementOfType() + val sourcePsi = uClass?.sourcePsi + val className = psiClass.name - if (sourcePsi == null || className == null) return@Processor true - val uAnnotation = uClass.findAnnotation(VAADIN_ROUTE) ?: return@Processor true + if (sourcePsi == null || className == null) return@Processor true + val uAnnotation = uClass.findAnnotation(VAADIN_ROUTE) ?: return@Processor true - val urlMapping = uAnnotation.findAttributeValue("value")?.evaluateString() ?: "" + val urlMapping = uAnnotation.findAttributeValue("value")?.evaluateString() ?: "" - routes.add(VaadinRoute(urlMapping, className, PsiAnchor.create(sourcePsi))) + routes.add(VaadinRoute(urlMapping, className, PsiAnchor.create(sourcePsi))) - true - }) + true + }) return routes.toList() } diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinReferenceContributor.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinReferenceContributor.kt index 77dc987..658a462 100644 --- a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinReferenceContributor.kt +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinReferenceContributor.kt @@ -16,28 +16,30 @@ import org.jetbrains.uast.expressions.UInjectionHost internal class VaadinReferenceContributor : PsiReferenceContributor() { override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) { registrar.registerUastReferenceProvider( - injectionHostUExpression() - .annotationParam(VAADIN_ROUTE, "value"), - uastUrlReferenceProvider(uastUrlPathReferenceInjectorForScheme(HTTP_SCHEMES, vaadinUrlPksParser)) - ) + injectionHostUExpression().annotationParam(VAADIN_ROUTE, "value"), + uastUrlReferenceProvider(uastUrlPathReferenceInjectorForScheme(HTTP_SCHEMES, vaadinUrlPksParser))) registrar.registerUastReferenceProvider( injectionHostUExpression() - .callParameter(0, callExpression() - .withMethodName("getTranslation") - .withAnyResolvedMethod(psiMethod() - .withName("getTranslation") - .definedInClass("com.vaadin.flow.component.Component"))), + .callParameter( + 0, + callExpression() + .withMethodName("getTranslation") + .withAnyResolvedMethod( + psiMethod() + .withName("getTranslation") + .definedInClass("com.vaadin.flow.component.Component"))), object : UastReferenceProvider() { - override fun getReferencesByElement(element: UElement, context: ProcessingContext): Array { + override fun getReferencesByElement( + element: UElement, + context: ProcessingContext + ): Array { if (element !is UInjectionHost) return PsiReference.EMPTY_ARRAY val key = element.evaluateToString() ?: return PsiReference.EMPTY_ARRAY val sourcePsi = element.sourcePsi ?: return PsiReference.EMPTY_ARRAY - return arrayOf(object : PropertyReference(key, sourcePsi, null, false), HighlightedReference { - }) + return arrayOf(object : PropertyReference(key, sourcePsi, null, false), HighlightedReference {}) } - } - ) + }) } } diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinRoute.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinRoute.kt index 84b9c09..60349ed 100644 --- a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinRoute.kt +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinRoute.kt @@ -2,10 +2,6 @@ package com.vaadin.plugin.endpoints import com.intellij.psi.PsiAnchor -internal class VaadinRoute( - val urlMapping: String, - val locationString: String, - val anchor: PsiAnchor -) { +internal class VaadinRoute(val urlMapping: String, val locationString: String, val anchor: PsiAnchor) { fun isValid(): Boolean = anchor.retrieve() != null } diff --git a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinUrlResolver.kt b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinUrlResolver.kt index 048ef40..59f0d13 100644 --- a/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinUrlResolver.kt +++ b/src/main/kotlin/com/vaadin/plugin/endpoints/VaadinUrlResolver.kt @@ -27,36 +27,27 @@ internal class VaadinUrlResolver(private val project: Project) : UrlResolver { get() = HTTP_SCHEMES override fun getVariants(): Iterable { - return getAllModuleVariants(project) - .asIterable() + return getAllModuleVariants(project).asIterable() } override fun resolve(request: UrlResolveRequest): Iterable { if (request.method != HttpMethods.GET) return emptyList() - val allModuleVariants = getAllModuleVariants(project) - .toList() + val allModuleVariants = getAllModuleVariants(project).toList() return UrlPath.combinations(request.path) - .flatMap { path -> - allModuleVariants.asSequence() - .filter { it.path.isCompatibleWith(path) } - } + .flatMap { path -> allModuleVariants.asSequence().filter { it.path.isCompatibleWith(path) } } .asIterable() } } internal val VAADIN_ROUTES_SEARCH: SourceLibSearchProvider, Module> = - SourceLibSearchProvider("VAADIN_ROUTES") { p, _, scope -> - findVaadinRoutes(p, scope).toList() - } + SourceLibSearchProvider("VAADIN_ROUTES") { p, _, scope -> findVaadinRoutes(p, scope).toList() } private fun getAllModuleVariants(project: Project): Sequence { val modules = ModuleManager.getInstance(project).modules - return modules.asSequence() - .flatMap(::getVariants) - .map(::VaadinUrlTargetInfo) + return modules.asSequence().flatMap(::getVariants).map(::VaadinUrlTargetInfo) } private fun getVariants(module: Module): Sequence { @@ -82,22 +73,18 @@ private class VaadinUrlTargetInfo(route: VaadinRoute) : UrlTargetInfo { override fun resolveToPsiElement(): PsiElement? = anchor.retrieve() } -internal val vaadinUrlPksParser: UrlPksParser = UrlPksParser( - splitEscaper = { _, _ -> SplitEscaper.AcceptAll }, - customPathSegmentExtractor = { part -> - if (part.startsWith(":")) { - val varName = part.removePrefix(":") - .substringBefore("?") - .substringBefore("(") - PathSegment.Variable(varName) - } else { - PathSegment.Exact(part) - } - } -) +internal val vaadinUrlPksParser: UrlPksParser = + UrlPksParser( + splitEscaper = { _, _ -> SplitEscaper.AcceptAll }, + customPathSegmentExtractor = { part -> + if (part.startsWith(":")) { + val varName = part.removePrefix(":").substringBefore("?").substringBefore("(") + PathSegment.Variable(varName) + } else { + PathSegment.Exact(part) + } + }) internal fun parseVaadinUrlMapping(urlMapping: String): UrlPath { - return vaadinUrlPksParser - .parseUrlPath(PartiallyKnownString(urlMapping)) - .urlPath + return vaadinUrlPksParser.parseUrlPath(PartiallyKnownString(urlMapping)).urlPath } From bcacd2360bfe250858b0b852565865a67be105b2 Mon Sep 17 00:00:00 2001 From: marcin Date: Wed, 20 Nov 2024 14:43:40 +0100 Subject: [PATCH 4/4] make it work locally and in community edition --- build.gradle.kts | 5 ++++- src/main/resources/META-INF/plugin.xml | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ada1033..237bb23 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -80,7 +80,10 @@ configure { } tasks { - patchPluginXml { sinceBuild.set("233") } + patchPluginXml { + sinceBuild.set("233") + untilBuild.set("252.*") + } signPlugin { certificateChain.set(System.getenv("CERTIFICATE_CHAIN")) diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index d2447b0..332e90b 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -31,9 +31,9 @@ com.intellij.properties - com.intellij.modules.microservices - com.intellij.microservices.jvm - com.intellij.modules.ultimate + com.intellij.modules.microservices + com.intellij.microservices.jvm + com.intellij.modules.ultimate