Skip to content

Commit

Permalink
Support navigation to tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sksamuel committed Jun 3, 2024
1 parent 61f02f0 commit 5de2beb
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 29 deletions.
9 changes: 3 additions & 6 deletions src/IC-242/kotlin/io/kotest/plugin/intellij/files.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ fun getLocationForFile(
name: String,
lineNumber: Int
): PsiLocation<PsiElement>? {
return FilenameIndex
.getVirtualFilesByName(name, scope)
.firstOrNull { it.isTestFile(project) }
?.toPsiFile(project)
?.elementAtLine(lineNumber)
?.toPsiLocation()
val testFile = FilenameIndex.getVirtualFilesByName(name, scope).firstOrNull { it.isTestFile(project) } ?: return null
// element at line is 1 indexed, so we need to add one
return testFile.toPsiFile(project)?.elementAtLine(lineNumber + 1)?.toPsiLocation()
}
61 changes: 38 additions & 23 deletions src/main/kotlin/io/kotest/plugin/intellij/KotestTestLocator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,34 +25,24 @@ import io.kotest.plugin.intellij.psi.toPsiLocation
*/
class KotestTestLocator : SMTestLocator {

/**
* Returns the PSI file that contains the class indicated by the fully qualified name.
*/
private fun loadPsiFile(fqn: String, project: Project, scope: GlobalSearchScope): PsiFile? {
val manager = PsiManager.getInstance(project)
// this is better than JavaPsiFacade as it will handle inner classes that use $
val psiClass = ClassUtil.findPsiClass(manager, fqn, null, true, scope)
val virtualFile = psiClass?.containingFile?.virtualFile
return virtualFile?.let { manager.findFile(it) }
}

private fun getLocationForFqn(
override fun getLocation(
protocol: String,
path: String,
project: Project,
scope: GlobalSearchScope,
fqn: String,
lineNumber: Int
): PsiLocation<PsiElement>? {
val psiFile = loadPsiFile(fqn, project, scope)
if (psiFile != null) {
val element = psiFile.elementAtLine(lineNumber) ?: psiFile
return element.toPsiLocation()
scope: GlobalSearchScope
): List<Location<PsiElement>> {
return when (protocol) {
Constants().FileLocatorProtocol -> parseFile(project, scope, path)
Constants().ClassLocatorProtocol -> parseClass(project, scope, path)
Constants().OldLocatorProtocol -> parseClass(project, scope, path)
else -> emptyList()
}
return null
}

override fun getLocation(
protocol: String,
path: String,
metainfo: String?,
project: Project,
scope: GlobalSearchScope
): List<Location<PsiElement>> {
Expand All @@ -64,6 +54,9 @@ class KotestTestLocator : SMTestLocator {
}
}

override fun getLocationCacheModificationTracker(project: Project): ModificationTracker =
ModificationTracker.EVER_CHANGED

private fun parseFile(project: Project, scope: GlobalSearchScope, path: String): List<Location<PsiElement>> {
val tokens = path.split(':')
val ident = tokens[0]
Expand All @@ -78,8 +71,30 @@ class KotestTestLocator : SMTestLocator {
return listOfNotNull(getLocationForFqn(project, scope, ident, lineNumber))
}

override fun getLocationCacheModificationTracker(project: Project): ModificationTracker =
ModificationTracker.EVER_CHANGED
/**
* Returns the PSI file that contains the class indicated by the fully qualified name.
*/
private fun loadPsiFile(fqn: String, project: Project, scope: GlobalSearchScope): PsiFile? {
val manager = PsiManager.getInstance(project)
// this is better than JavaPsiFacade as it will handle inner classes that use $
val psiClass = ClassUtil.findPsiClass(manager, fqn, null, true, scope)
val virtualFile = psiClass?.containingFile?.virtualFile
return virtualFile?.let { manager.findFile(it) }
}

private fun getLocationForFqn(
project: Project,
scope: GlobalSearchScope,
fqn: String,
lineNumber: Int
): PsiLocation<PsiElement>? {
val psiFile = loadPsiFile(fqn, project, scope)
if (psiFile != null) {
val element = psiFile.elementAtLine(lineNumber) ?: psiFile
return element.toPsiLocation()
}
return null
}
}


0 comments on commit 5de2beb

Please sign in to comment.