174 lines
6.0 KiB
Kotlin
174 lines
6.0 KiB
Kotlin
package dev.hgh.jai.settings
|
|
|
|
import com.intellij.openapi.vfs.LocalFileSystem
|
|
import com.intellij.psi.PsiFile
|
|
import com.intellij.psi.PsiManager
|
|
import com.intellij.psi.PsiReferenceService
|
|
import com.intellij.psi.search.searches.ReferencesSearch
|
|
import com.intellij.psi.util.PsiTreeUtil
|
|
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
|
import dev.hgh.jai.psi.JaiDeclName
|
|
import dev.hgh.jai.psi.JaiLiteralExpr
|
|
import dev.hgh.jai.psi.JaiRefExpr
|
|
import java.nio.file.Files
|
|
import java.nio.file.Path
|
|
|
|
class JaiConfiguredRootTest : BasePlatformTestCase() {
|
|
private var temporaryRoot: Path? = null
|
|
|
|
fun testConfiguredRootResolvesImportedModuleAndSymbol() {
|
|
val module = configureRoot("Custom/module.jai" to "Helper :: () {}")
|
|
val source =
|
|
myFixture.addFileToProject(
|
|
"consumer.jai",
|
|
"""
|
|
#import "Custom";
|
|
main :: () { Helper(); }
|
|
""".trimIndent(),
|
|
)
|
|
|
|
val moduleLiteral = literalWithText(source, "\"Custom\"")
|
|
assertEquals(
|
|
module.path,
|
|
onlyReference(moduleLiteral)
|
|
.resolve()
|
|
?.containingFile
|
|
?.virtualFile
|
|
?.path,
|
|
)
|
|
|
|
val symbolReference =
|
|
PsiTreeUtil
|
|
.findChildrenOfType(source, JaiRefExpr::class.java)
|
|
.single { it.text == "Helper" }
|
|
assertEquals(
|
|
module.path,
|
|
onlyReference(symbolReference)
|
|
.resolve()
|
|
?.containingFile
|
|
?.virtualFile
|
|
?.path,
|
|
)
|
|
}
|
|
|
|
fun testConfiguredRootResolvesLoadFileFromConfiguredRoot() {
|
|
val externalFile = configureRoot("external.jai" to "value :: 1;")
|
|
val source = myFixture.addFileToProject("consumer.jai", "#load \"external.jai\";")
|
|
|
|
val literal = literalWithText(source, "\"external.jai\"")
|
|
|
|
assertEquals(
|
|
externalFile.path,
|
|
onlyReference(literal)
|
|
.resolve()
|
|
?.containingFile
|
|
?.virtualFile
|
|
?.path,
|
|
)
|
|
}
|
|
|
|
fun testConfiguredRootSuppliesImportAndLoadCompletion() {
|
|
configureRoot(
|
|
"Custom/module.jai" to "value :: 1;",
|
|
"external.jai" to "value :: 1;",
|
|
)
|
|
|
|
val configuredRoots = JaiProjectSettings.getInstance(project).configuredRoots()
|
|
assertEquals("expected one configured VFS root", 1, configuredRoots.size)
|
|
assertNotNull("expected the configured module directory", configuredRoots.single().findChild("Custom"))
|
|
|
|
myFixture.configureByText("import-consumer.jai", "#import \"Cus<caret>\";")
|
|
myFixture.completeBasic()
|
|
myFixture.checkResult("#import \"Custom\";")
|
|
|
|
myFixture.configureByText("load-consumer.jai", "#load \"ext<caret>\";")
|
|
myFixture.completeBasic()
|
|
myFixture.checkResult("#load \"external.jai\";")
|
|
}
|
|
|
|
fun testReferencesSearchIncludesProjectUsagesForConfiguredExternalDeclaration() {
|
|
val module = configureRoot("Custom/module.jai" to "Helper :: () {}")
|
|
val source =
|
|
myFixture.addFileToProject(
|
|
"consumer.jai",
|
|
"""
|
|
#import "Custom";
|
|
main :: () { Helper(); }
|
|
""".trimIndent(),
|
|
)
|
|
JaiProjectSettings.getInstance(project).refreshProjectRoots()
|
|
val externalFile =
|
|
PsiManager
|
|
.getInstance(project)
|
|
.findFile(module)
|
|
assertNotNull("expected PSI for configured external module", externalFile)
|
|
val declaration =
|
|
PsiTreeUtil
|
|
.findChildrenOfType(externalFile!!, JaiDeclName::class.java)
|
|
.single { it.text == "Helper" }
|
|
assertTrue(
|
|
"configured Jai files should be indexed as library sources",
|
|
com.intellij.openapi.roots.ProjectFileIndex
|
|
.getInstance(project)
|
|
.isInLibrarySource(module),
|
|
)
|
|
|
|
val usages = ReferencesSearch.search(declaration).findAll()
|
|
|
|
assertEquals(
|
|
"expected the project usage; scope=${declaration.useScope}, usages=$usages",
|
|
1,
|
|
usages.size,
|
|
)
|
|
assertEquals("Helper", usages.single().element.text)
|
|
assertEquals(
|
|
source.virtualFile.path,
|
|
usages
|
|
.single()
|
|
.element.containingFile.virtualFile.path,
|
|
)
|
|
}
|
|
|
|
private fun configureRoot(vararg files: Pair<String, String>): com.intellij.openapi.vfs.VirtualFile {
|
|
val root = Files.createTempDirectory("jai-configured-root-").toAbsolutePath().normalize()
|
|
temporaryRoot = root
|
|
files.forEach { (relativePath, contents) ->
|
|
val file = root.resolve(relativePath)
|
|
Files.createDirectories(file.parent)
|
|
Files.writeString(file, contents)
|
|
}
|
|
|
|
val virtualRoot = LocalFileSystem.getInstance().refreshAndFindFileByNioFile(root)
|
|
assertNotNull("expected the configured root to be visible to VFS", virtualRoot)
|
|
JaiProjectSettings.getInstance(project).setRootPaths(listOf(root.toString()))
|
|
return virtualRoot!!.findFileByRelativePath(files.first().first)!!
|
|
}
|
|
|
|
private fun literalWithText(
|
|
source: PsiFile,
|
|
text: String,
|
|
): JaiLiteralExpr {
|
|
val literal =
|
|
PsiTreeUtil
|
|
.findChildrenOfType(source, JaiLiteralExpr::class.java)
|
|
.firstOrNull { it.text == text }
|
|
assertNotNull("expected string literal $text", literal)
|
|
return literal!!
|
|
}
|
|
|
|
private fun onlyReference(element: com.intellij.psi.PsiElement) =
|
|
PsiReferenceService
|
|
.getService()
|
|
.getContributedReferences(element)
|
|
.also { assertEquals("expected exactly one reference", 1, it.size) }
|
|
.single()
|
|
|
|
override fun tearDown() {
|
|
try {
|
|
super.tearDown()
|
|
} finally {
|
|
temporaryRoot?.toFile()?.deleteRecursively()
|
|
}
|
|
}
|
|
}
|