AA: add support VirtualFile inputs to source module

^KT-65571 fixed
This commit is contained in:
Jinseong Jeon
2024-02-13 10:28:07 -08:00
committed by Space Team
parent 520ae725d1
commit de4cce8dc8
3 changed files with 111 additions and 2 deletions
@@ -32,6 +32,7 @@ public class KtSourceModuleBuilder(
LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST)
private val sourceRoots: MutableList<Path> = mutableListOf()
private val sourceVirtualFiles: MutableList<VirtualFile> = mutableListOf()
public fun addSourceRoot(path: Path) {
sourceRoots.add(path)
@@ -41,6 +42,14 @@ public class KtSourceModuleBuilder(
sourceRoots.addAll(paths)
}
public fun addSourceVirtualFile(virtualFile: VirtualFile) {
sourceVirtualFiles.add(virtualFile)
}
public fun addSourceVirtualFiles(virtualFiles: Collection<VirtualFile>) {
sourceVirtualFiles.addAll(virtualFiles)
}
override fun build(): KtSourceModule {
val virtualFiles = collectVirtualFilesByRoots()
val psiManager = PsiManager.getInstance(kotlinCoreProjectEnvironment.project)
@@ -73,6 +82,7 @@ public class KtSourceModuleBuilder(
add(virtualFile)
}
}
addAll(sourceVirtualFiles)
}
}
}
@@ -248,4 +248,45 @@ class StandaloneSessionBuilderTest : TestWithDisposable() {
val ktCallExpression = ktFile.findDescendantOfType<KtCallExpression>()!!
ktCallExpression.assertIsCallOf(CallableId(FqName.ROOT, Name.identifier("foo")))
}
@Test
fun testKotlinSourceModuleSessionWithVirtualFile() {
val root = "otherModuleUsage"
lateinit var sourceModule: KtSourceModule
val session = buildStandaloneAnalysisAPISession(disposable) {
registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider())
buildKtModuleProvider {
platform = JvmPlatforms.defaultJvmPlatform
val dep = addModule(
buildKtSourceModule {
addSourceRoot(testDataPath(root).resolve("dependent"))
platform = JvmPlatforms.defaultJvmPlatform
moduleName = "dependent"
}
)
sourceModule = addModule(
buildKtSourceModule {
// addSourceRoot(testDataPath(root).resolve("main"))
// Instead, add [VirtualFile] on-the-fly
val virtualFile = createVirtualFileOnTheFly(
project,
"""
fun main() {
foo()
}
""".trimIndent()
)
addSourceVirtualFile(virtualFile)
addRegularDependency(dep)
platform = JvmPlatforms.defaultJvmPlatform
moduleName = "main"
}
)
}
}
val ktFile = session.modulesWithFiles.getValue(sourceModule).single() as KtFile
val ktCallExpression = ktFile.findDescendantOfType<KtCallExpression>()!!
ktCallExpression.assertIsCallOf(CallableId(FqName.ROOT, Name.identifier("foo")))
}
}
@@ -5,6 +5,10 @@
package org.jetbrains.kotlin.analysis.api.standalone.fir.test.cases.session.builder
import com.intellij.mock.MockVirtualFileSystem
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileSystem
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.calls.KtSuccessCallInfo
import org.jetbrains.kotlin.analysis.api.calls.successfulFunctionCallOrNull
@@ -12,6 +16,7 @@ import org.jetbrains.kotlin.analysis.api.calls.symbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.test.MockLibraryUtil
import org.jetbrains.kotlin.test.util.KtTestUtil
import java.nio.file.Files
@@ -21,6 +26,10 @@ import kotlin.io.path.absolutePathString
import kotlin.io.path.extension
import kotlin.streams.asSequence
import org.junit.jupiter.api.Assertions
import java.io.InputStream
import java.io.OutputStream
import java.time.LocalDateTime
import java.time.ZoneOffset
internal fun testDataPath(path: String): Path {
return Paths.get("analysis/analysis-api-standalone/testData/sessionBuilder").resolve(path)
@@ -36,7 +45,6 @@ fun KtCallExpression.assertIsCallOf(callableId: CallableId) {
}
}
internal fun compileCommonKlib(kLibSourcesRoot: Path): Path {
val ktFiles = Files.walk(kLibSourcesRoot).asSequence().filter { it.extension == "kt" }.toList()
val testKlib = KtTestUtil.tmpDir("testLibrary").resolve("library.klib").toPath()
@@ -49,4 +57,54 @@ internal fun compileCommonKlib(kLibSourcesRoot: Path): Path {
MockLibraryUtil.runMetadataCompiler(arguments)
return testKlib
}
}
internal fun createVirtualFileOnTheFly(
project: Project,
text: String,
fs: VirtualFileSystem = MockVirtualFileSystem(),
): VirtualFile {
val factory = KtPsiFactory(project, markGenerated = false)
val ktFile = factory.createFile(text)
return object : VirtualFile() {
override fun getName(): String = ktFile.name
override fun getFileSystem(): VirtualFileSystem = fs
override fun getPath(): String {
error("Not yet implemented")
}
override fun isWritable(): Boolean = false
override fun isDirectory(): Boolean = false
override fun isValid(): Boolean = ktFile.isValid
override fun getParent(): VirtualFile {
error("Not yet implemented")
}
override fun getChildren(): Array<VirtualFile> = emptyArray()
override fun getOutputStream(requestor: Any?, newModificationStamp: Long, newTimeStamp: Long): OutputStream {
error("Not yet implemented")
}
override fun contentsToByteArray(): ByteArray = ktFile.text.toByteArray()
private val timeStamp = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
override fun getTimeStamp(): Long = timeStamp
override fun getLength(): Long = ktFile.textLength.toLong()
override fun refresh(asynchronous: Boolean, recursive: Boolean, postRunnable: Runnable?) {
error("Not yet implemented")
}
override fun getInputStream(): InputStream {
error("Not yet implemented")
}
}
}