Skip to content

Commit

Permalink
Fix #28 (#30)
Browse files Browse the repository at this point in the history
* Fixes #28

* Fixes #28
  • Loading branch information
5peak2me committed Sep 23, 2023
1 parent 270082e commit 6e24670
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
Expand Up @@ -2,6 +2,7 @@ package com.faendir.intellij.gradleVersionCatalogs.kotlin

import com.faendir.intellij.gradleVersionCatalogs.VCElementType
import com.intellij.psi.*
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull

private const val PROVIDER = "org.gradle.api.provider.Provider"
Expand All @@ -15,11 +16,22 @@ private const val BUNDLE_SUPPLIER = "org.gradle.api.internal.catalog.ExternalMod
private const val PLUGIN_SUPPLIER = "org.gradle.api.internal.catalog.ExternalModuleDependencyFactory.PluginNotationSupplier"


@Suppress("SpellCheckingInspection")
data class Accessor(val element: PsiElement, val id: String, val type: VCElementType) {
companion object {
fun find(element: PsiElement): Accessor? {
val returnType = element.lastChild.references.map { it.resolve() }.firstIsInstanceOrNull<PsiMethod>()?.returnType ?: return null
val segments by lazy { element.text.replace(Regex("\\s+"), "").split(".").drop(1) }
val references = if (element.lastChild.references.mapNotNull(PsiReference::resolve).isEmpty()) {
element.lastChild.firstChild.references
} else element.lastChild.references
val returnType = references.map { it.resolve() }.firstIsInstanceOrNull<PsiMethod>()?.returnType ?: return null
val segments by lazy { element.text.replace(Regex("\\s+"), "").split(".").drop(1)
// e.g. libs.map.get3dmap() -> [libs, map, get3dmap()] -> [map, get3dmap()] -> [map, 3dmap]
.map {
it.applyIf(it.matches(Regex("^get.*\\(\\s*\\)\$"))) {
removePrefix("get").removeSuffix("()")
}
}
}
val type = when {
returnType.extendsFrom(createGenericType(PROVIDER, element, createType(LIBRARY_DEPENDENCY, element))) ||
returnType.extendsFrom(createType(LIBRARY_SUPPLIER, element)) -> VCElementType.LIBRARY
Expand Down
Expand Up @@ -37,14 +37,15 @@ class VersionCatalogInlayHintsProvider : InlayHintsProvider<NoSettings> {
val accessor = BuildGradleKtsPsiCache.findAccessor(element)
if (accessor != null && BuildGradleKtsPsiCache.findAccessor(element.parent) == null) {
val referencedElement = element.project.findInVersionsTomlKeyValues({ VersionsTomlPsiCache.getDefinitions(it, accessor.type) }, accessor.id)
.firstOrNull()
.firstOrNull()
if (referencedElement != null) {
val referencedValue = referencedElement.value
if (referencedValue != null) {
val inlayText: String? = when (referencedElement.vcElementType) {
VCElementType.LIBRARY -> resolvePotentiallyTabledDefinition(referencedValue, "module")
VCElementType.VERSION -> referencedValue.text?.unquote()
VCElementType.PLUGIN -> resolvePotentiallyTabledDefinition(referencedValue, "id")
VCElementType.BUNDLE -> resolveBundlesDefinition(referencedValue)
else -> null
}
if (inlayText != null) {
Expand All @@ -66,10 +67,36 @@ class VersionCatalogInlayHintsProvider : InlayHintsProvider<NoSettings> {
return null
}

/**
* handle the definition of libs.bundles.xxx
*
* @since 1.3.2
*/
private fun resolveBundlesDefinition(referencedValue: TomlValue): String? {
return if (referencedValue is TomlArray) {
val size = referencedValue.elements.size
referencedValue.elements.take(3).mapNotNull { value ->
VersionsTomlPsiCache.getDefinitions(
referencedValue.containingFile as TomlFile,
VCElementType.LIBRARY
).find {
it.key.textMatches(value.text.unquote())
}?.value?.let {
resolvePotentiallyTabledDefinition(it, "module")
}
}.joinToString(separator = "", postfix = if (size > 3) "..." else "")
} else null
}

private fun resolvePotentiallyTabledDefinition(referencedValue: TomlValue, moduleTableKey: String) = when (referencedValue) {
is TomlTable, is TomlInlineTable -> {
val keys = referencedValue.childrenOfType<TomlKeyValue>()
keys.find { it.key.textMatches(moduleTableKey) }?.value?.text?.unquote()?.let { module ->
val identifier = if (referencedValue.text.contains(moduleTableKey)) {
keys.find { it.key.textMatches(moduleTableKey) }?.value?.text?.unquote()
} else {
keys.filterNot { it.text.contains("version") }.joinToString(":") { it.value?.text?.unquote().orEmpty() }
}
identifier?.let { module ->
(
keys.find { it.key.textMatches("version") }?.value?.text?.unquote()
?: keys.find { it.isVersionRef() }?.value?.text?.unquote()?.let { search ->
Expand Down

0 comments on commit 6e24670

Please sign in to comment.