diff --git a/lsp/jvm-symbol-index/src/main/kotlin/org/appdevforall/codeonthego/indexing/jvm/KtFileMetadataIndex.kt b/lsp/jvm-symbol-index/src/main/kotlin/org/appdevforall/codeonthego/indexing/jvm/KtFileMetadataIndex.kt index ea39b293d9..e70c112cf9 100644 --- a/lsp/jvm-symbol-index/src/main/kotlin/org/appdevforall/codeonthego/indexing/jvm/KtFileMetadataIndex.kt +++ b/lsp/jvm-symbol-index/src/main/kotlin/org/appdevforall/codeonthego/indexing/jvm/KtFileMetadataIndex.kt @@ -30,7 +30,7 @@ class KtFileMetadataIndex private constructor( SQLiteIndex( descriptor = KtFileMetadataDescriptor, context = context, - dbName = null, + dbName = dbName, name = "kt-file-metadata", ) ) diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/KotlinLanguageServer.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/KotlinLanguageServer.kt index 2e6d5c9b92..312ef848cd 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/KotlinLanguageServer.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/KotlinLanguageServer.kt @@ -19,10 +19,14 @@ package com.itsaky.androidide.lsp.kotlin import com.itsaky.androidide.app.BaseApplication import com.itsaky.androidide.app.configuration.IJdkDistributionProvider +import com.itsaky.androidide.eventbus.events.BuildCompletedEvent import com.itsaky.androidide.eventbus.events.editor.DocumentChangeEvent import com.itsaky.androidide.eventbus.events.editor.DocumentCloseEvent import com.itsaky.androidide.eventbus.events.editor.DocumentOpenEvent import com.itsaky.androidide.eventbus.events.editor.DocumentSaveEvent +import com.itsaky.androidide.eventbus.events.file.FileCreationEvent +import com.itsaky.androidide.eventbus.events.file.FileDeletionEvent +import com.itsaky.androidide.eventbus.events.file.FileRenameEvent import com.itsaky.androidide.lsp.api.ILanguageClient import com.itsaky.androidide.lsp.api.ILanguageServer import com.itsaky.androidide.lsp.api.IServerSettings @@ -55,6 +59,7 @@ import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch import org.appdevforall.codeonthego.indexing.jvm.JvmLibraryIndexingService import org.appdevforall.codeonthego.indexing.jvm.JvmSymbolIndex import org.appdevforall.codeonthego.indexing.jvm.KtFileMetadataIndex @@ -312,4 +317,87 @@ class KotlinLanguageServer : ILanguageServer { compiler?.compilationEnvironmentFor(event.savedFile) ?.onFileSaved(event.savedFile) } + + @Subscribe + @Suppress("unused") + fun onBuildCompleted(event: BuildCompletedEvent) { + compiler?.refreshSources() + } + + @Subscribe + @Suppress("unused") + fun onFileCreated(event: FileCreationEvent) { + val path = event.file.toPath() + if (!DocumentUtils.isKotlinFile(path)) { + return + } + + scope.launch { + compiler?.compilationEnvironmentFor(path) + ?.ktSymbolIndex + ?.submitForIndexing(path) + } + } + + @Subscribe + @Suppress("unused") + fun onFileDeleted(event: FileDeletionEvent) { + val path = event.file.toPath() + if (!DocumentUtils.isKotlinFile(path)) { + return + } + + scope.launch { + compiler?.compilationEnvironmentFor(path) + ?.ktSymbolIndex + ?.removeFromIndex(path) + } + } + + @Subscribe + @Suppress("unused") + fun onFileRenamed(event: FileRenameEvent) { + val fromPath = event.file.toPath() + val toPath = event.newFile.toPath() + + scope.launch { + val oldIsKotlinFile = DocumentUtils.isKotlinFile(fromPath) + val newIsKotlinFile = DocumentUtils.isKotlinFile(toPath) + + if (!oldIsKotlinFile && newIsKotlinFile) { + // only the new file is a Kotlin file + // so just submit it for indexing + compiler?.compilationEnvironmentFor(toPath) + ?.ktSymbolIndex + ?.submitForIndexing(toPath) + return@launch + } + + if (oldIsKotlinFile && !newIsKotlinFile) { + // only the old file was a Kotlin file + // so just remove it from the index + compiler?.compilationEnvironmentFor(fromPath) + ?.ktSymbolIndex + ?.removeFromIndex(fromPath) + return@launch + } + + val fromKind = runCatching { compiler?.compilationKindFor(fromPath) }.getOrNull() + val toKind = runCatching { compiler?.compilationKindFor(toPath) }.getOrNull() + val fromEnv = fromKind?.let { compiler?.compilationEnvironmentFor(it) } + val toEnv = toKind?.let { compiler?.compilationEnvironmentFor(it) } + + if (fromKind != null && fromEnv == toEnv && toEnv != null) { + // file was renamed within the same compilation environment + toEnv.ktSymbolIndex.onFileMoved(fromPath, toPath) + return@launch + } + + // file may have been moved from one compilation environment to another + // remove from old env's index + // and submit to the new env for indexing + fromEnv?.ktSymbolIndex?.removeFromIndex(fromPath) + toEnv?.ktSymbolIndex?.submitForIndexing(toPath) + } + } } diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationEnvironment.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationEnvironment.kt index b3b60f92bf..6772e7f31d 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationEnvironment.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationEnvironment.kt @@ -13,11 +13,11 @@ import com.itsaky.androidide.lsp.kotlin.compiler.services.KtLspService import com.itsaky.androidide.lsp.kotlin.compiler.services.ProjectStructureProvider import com.itsaky.androidide.lsp.kotlin.compiler.services.WriteAccessGuard import com.itsaky.androidide.lsp.kotlin.compiler.services.latestLanguageVersionSettings -import com.itsaky.androidide.utils.KeyedDebouncingAction import com.itsaky.androidide.lsp.kotlin.diagnostic.collectDiagnosticsFor import com.itsaky.androidide.lsp.kotlin.utils.SymbolVisibilityChecker import com.itsaky.androidide.projects.FileManager import com.itsaky.androidide.projects.api.Workspace +import com.itsaky.androidide.utils.KeyedDebouncingAction import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -110,6 +110,7 @@ import kotlin.time.Duration.Companion.milliseconds @OptIn(K1Deprecation::class) internal class CompilationEnvironment( name: String, + val kind: CompilationKind, workspace: Workspace, val ktProject: KotlinProjectModel, val intellijPluginRoot: Path, @@ -179,6 +180,7 @@ internal class CompilationEnvironment( val ktSymbolIndex by lazy { KtSymbolIndex( + kind = kind, project = project, modules = modules, fileIndex = requireFileIndex, @@ -397,6 +399,12 @@ internal class CompilationEnvironment( } } + fun refreshSources() { + ktSymbolIndex.refreshSources() + // TODO: Should also update/notify Java file services about possibly changed Java files + // But that's a bit problematic right now, scheduled for later + } + fun openFileIfNeeded(path: Path) { ktSymbolIndex.getOpenedKtFile(path) ?: onFileOpen(path) diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationKind.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationKind.kt index a15305ffba..59777e4712 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationKind.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationKind.kt @@ -1,16 +1,37 @@ package com.itsaky.androidide.lsp.kotlin.compiler +import java.nio.file.Path +import kotlin.io.path.extension + /** * The kind of compilation being performed in a [Compiler]. */ -enum class CompilationKind { +sealed interface CompilationKind { + + /** + * The types of files this compilation kind accepts. + */ + val fileExtensions: List + + /** + * Whether this compilation kind accepts the given file path. The default + * implementation simply checks the accepted [fileExtensions]. + */ + fun acceptsFile(path: Path): Boolean { + return path.extension in fileExtensions + } + /** * The default compilation kind. Mostly used for normal Kotlin source files. */ - Default, + data object Default : CompilationKind { + override val fileExtensions = listOf("kt") + } /** * Compilation kind for compiling Kotlin scripts. */ - Script, + data object Script : CompilationKind { + override val fileExtensions = listOf("kts") + } } \ No newline at end of file diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/Compiler.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/Compiler.kt index e71fa50dd4..762931ff4f 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/Compiler.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/Compiler.kt @@ -39,6 +39,7 @@ internal class Compiler( init { defaultCompilationEnv = CompilationEnvironment( name = "default", + kind = CompilationKind.Default, workspace = workspace, ktProject = projectModel, intellijPluginRoot = intellijPluginRoot, @@ -53,14 +54,19 @@ internal class Compiler( VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) } + fun refreshSources() { + defaultCompilationEnv.refreshSources() + } + fun updateLanguageClient(client: ILanguageClient?) { defaultCompilationEnv.languageClient = client // TODO: update client for script env once we have one } fun compilationKindFor(file: Path): CompilationKind { - // TODO: This should return a different environment for Kotlin script files - return CompilationKind.Default + if (CompilationKind.Default.acceptsFile(file)) return CompilationKind.Default + if (CompilationKind.Script.acceptsFile(file)) return CompilationKind.Script + throw IllegalStateException("Cannot get compilation kind for file: ${file.pathString}. It may not be supported.") } fun compilationEnvironmentFor(file: Path): CompilationEnvironment? { diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/IndexCommand.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/IndexCommand.kt index c6f6027173..29e3d94a10 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/IndexCommand.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/IndexCommand.kt @@ -2,14 +2,14 @@ package com.itsaky.androidide.lsp.kotlin.compiler.index import org.jetbrains.kotlin.com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.psi.KtFile +import java.nio.file.Path internal sealed interface IndexCommand { data object Stop : IndexCommand data object SourceScanningComplete: IndexCommand data object IndexingComplete: IndexCommand data class ScanSourceFile(val vf: VirtualFile): IndexCommand - data class IndexModifiedFile(val ktFile: KtFile): IndexCommand { - - } + data class IndexModifiedFile(val ktFile: KtFile): IndexCommand data class IndexSourceFile(val vf: VirtualFile): IndexCommand + data class RemoveFromIndex(val path: Path): IndexCommand } \ No newline at end of file diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/IndexWorker.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/IndexWorker.kt index 520c37e63d..b10fabb20d 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/IndexWorker.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/IndexWorker.kt @@ -3,9 +3,12 @@ package com.itsaky.androidide.lsp.kotlin.compiler.index import com.itsaky.androidide.lsp.kotlin.compiler.CompilationEnvironment import com.itsaky.androidide.lsp.kotlin.compiler.modules.backingFilePath import com.itsaky.androidide.lsp.kotlin.compiler.read +import com.itsaky.androidide.lsp.kotlin.utils.toNioPathOrNull import com.itsaky.androidide.progress.ICancelChecker import com.itsaky.androidide.utils.KeyedDebouncingAction import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.isActive import org.appdevforall.codeonthego.indexing.jvm.JvmSymbolIndex import org.appdevforall.codeonthego.indexing.jvm.KtFileMetadata import org.appdevforall.codeonthego.indexing.jvm.KtFileMetadataIndex @@ -14,6 +17,7 @@ import org.jetbrains.kotlin.com.intellij.psi.PsiManager import org.jetbrains.kotlin.psi.KtFile import org.slf4j.LoggerFactory import java.nio.file.Path +import kotlin.io.path.pathString internal class IndexWorker( private val project: Project, @@ -42,7 +46,7 @@ internal class IndexWorker( operator fun component2() = ktFile } - suspend fun start() { + suspend fun start() = coroutineScope { var scanCount = 0 var sourceIndexCount = 0 @@ -55,17 +59,23 @@ internal class IndexWorker( sourceIndexCount++ } - while (true) { - when (val command = queue.take()) { + while (isActive) { + when (val cmd = queue.take()) { + is IndexCommand.RemoveFromIndex -> { + val filePath = cmd.path.pathString + fileIndex.remove(filePath) + sourceIndex.removeBySource(filePath) + } + is IndexCommand.IndexSourceFile -> { - if (command.vf.fileSystem.protocol != "file") { - logger.warn("Unknown source file protocol: {}", command.vf.path) + if (cmd.vf.fileSystem.protocol != "file") { + logger.warn("Unknown source file protocol: {}", cmd.vf.path) continue } val ktFile = project.read { PsiManager.getInstance(project) - .findFile(command.vf) as? KtFile + .findFile(cmd.vf) as? KtFile } if (ktFile == null) { @@ -87,8 +97,8 @@ internal class IndexWorker( is IndexCommand.IndexModifiedFile -> { modifiedFileIndexer.schedule( ModFileIndexKey( - command.ktFile.backingFilePath!!, - command.ktFile + cmd.ktFile.backingFilePath!!, + cmd.ktFile ) ) } @@ -103,7 +113,7 @@ internal class IndexWorker( is IndexCommand.ScanSourceFile -> { val ktFile = project.read { - PsiManager.getInstance(project).findFile(command.vf) as? KtFile + PsiManager.getInstance(project).findFile(cmd.vf) as? KtFile } ?: continue diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/KtSymbolIndex.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/KtSymbolIndex.kt index e345ab539c..7f0c9118ca 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/KtSymbolIndex.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/KtSymbolIndex.kt @@ -1,13 +1,16 @@ package com.itsaky.androidide.lsp.kotlin.compiler.index import com.github.benmanes.caffeine.cache.Caffeine +import com.itsaky.androidide.lsp.kotlin.compiler.CompilationKind import com.itsaky.androidide.lsp.kotlin.compiler.modules.KtModule import com.itsaky.androidide.lsp.kotlin.compiler.read +import com.itsaky.androidide.lsp.kotlin.utils.toVirtualFileOrNull import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.launch import org.appdevforall.codeonthego.indexing.jvm.JvmSymbolIndex import org.appdevforall.codeonthego.indexing.jvm.KtFileMetadataIndex @@ -17,6 +20,7 @@ import org.jetbrains.kotlin.com.intellij.openapi.project.Project import org.jetbrains.kotlin.com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.com.intellij.psi.PsiManager import org.jetbrains.kotlin.psi.KtFile +import org.slf4j.LoggerFactory import java.nio.file.Path import java.util.concurrent.ConcurrentHashMap @@ -30,6 +34,7 @@ val KT_SOURCE_FILE_META_INDEX_KEY = IndexKey("kt-source-fil * Callers are responsible for closing the provided indexes. */ internal class KtSymbolIndex( + val kind: CompilationKind, val project: Project, modules: List, val fileIndex: KtFileMetadataIndex, @@ -43,6 +48,7 @@ internal class KtSymbolIndex( ) ) { companion object { + private val logger = LoggerFactory.getLogger(KtSymbolIndex::class.java) const val DEFAULT_CACHE_SIZE = 100L } @@ -56,6 +62,7 @@ internal class KtSymbolIndex( ) private val scanningWorker = ScanningWorker( + kind = kind, sourceIndex = sourceIndex, indexWorker = indexWorker, modules = modules, @@ -75,14 +82,73 @@ internal class KtSymbolIndex( get() = openedFiles.asSequence() fun syncIndexInBackground() { - // TODO: Figure out how to handle already-running scanning/indexing jobs. + indexingJob?.cancel() + startIndexing() - indexingJob = scope.launch { - indexWorker.start() + scanningJob?.cancel() + startScanning() + } + + private fun startIndexing() { + val job = scope.launch { + try { + indexWorker.start() + } finally { + if (indexingJob === coroutineContext[Job]) { + indexingJob = null + } + } + } + + indexingJob = job + } + + private fun startScanning() { + scanningJob = scope.launch { + try { + scanningWorker.scan() + } finally { + if (scanningJob === coroutineContext[Job]) { + scanningJob = null + } + } } + } + + fun refreshSources() { + indexingJob ?: startIndexing() + + scanningJob?.cancel() + startScanning() + } + + private fun getVirtualFileOrWarn(path: Path): VirtualFile? { + return path.toVirtualFileOrNull() ?: run { + logger.warn("unable to find virtual file for path {}", path) + null + } + } + + suspend fun submitForIndexing(path: Path) { + val vf = getVirtualFileOrWarn(path) ?: return + indexWorker.apply { + submitCommand(IndexCommand.ScanSourceFile(vf)) + submitCommand(IndexCommand.IndexSourceFile(vf)) + } + } + + suspend fun removeFromIndex(path: Path) { + indexWorker.submitCommand(IndexCommand.RemoveFromIndex(path)) + } + + suspend fun onFileMoved(from: Path, to: Path) { + // always remove the source file from index + indexWorker.submitCommand(IndexCommand.RemoveFromIndex(from)) - scanningJob = scope.launch(Dispatchers.IO) { - scanningWorker.start() + val toVf = getVirtualFileOrWarn(to) ?: return + indexWorker.apply { + submitCommand(IndexCommand.ScanSourceFile(toVf)) + submitCommand(IndexCommand.IndexSourceFile(toVf)) } } @@ -124,10 +190,9 @@ internal class KtSymbolIndex( } suspend fun close() { - scanningWorker.stop() indexWorker.submitCommand(IndexCommand.Stop) - scanningJob?.join() + scanningJob?.cancelAndJoin() indexingJob?.join() } } diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/ScanningWorker.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/ScanningWorker.kt index 0f5a7c7db3..3f2c06fdec 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/ScanningWorker.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/ScanningWorker.kt @@ -1,59 +1,60 @@ package com.itsaky.androidide.lsp.kotlin.compiler.index +import com.itsaky.androidide.lsp.kotlin.compiler.CompilationKind import com.itsaky.androidide.lsp.kotlin.compiler.modules.KtModule import com.itsaky.androidide.lsp.kotlin.compiler.modules.asFlatSequence import com.itsaky.androidide.lsp.kotlin.compiler.modules.isSourceModule +import com.itsaky.androidide.lsp.kotlin.utils.toNioPathOrNull +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.isActive import org.appdevforall.codeonthego.indexing.jvm.JvmSymbolIndex import org.slf4j.LoggerFactory -import java.util.concurrent.atomic.AtomicBoolean internal class ScanningWorker( - private val sourceIndex: JvmSymbolIndex, - private val indexWorker: IndexWorker, - private val modules: List, + private val kind: CompilationKind, + private val sourceIndex: JvmSymbolIndex, + private val indexWorker: IndexWorker, + private val modules: List, ) { - companion object { - private val logger = LoggerFactory.getLogger(ScanningWorker::class.java) - } - - private val isRunning = AtomicBoolean(false) - - suspend fun start() { - isRunning.set(true) - try { - scan() - } finally { - isRunning.set(false) - } - } - - private suspend fun scan() { - val sourceFiles = modules.asFlatSequence() - .filter { it.isSourceModule } - .flatMap { it.computeFiles(extended = true) } - .takeWhile { isRunning.get() } - .toList() - - sourceIndex.setActiveSources(sourceFiles.asSequence().map { it.path }.toSet()) - - for (sourceFile in sourceFiles) { - if (!isRunning.get()) return - indexWorker.submitCommand(IndexCommand.ScanSourceFile(sourceFile)) - } - - indexWorker.submitCommand(IndexCommand.SourceScanningComplete) - - sourceFiles.asSequence() - .takeWhile { isRunning.get() } - .forEach { sourceFile -> - indexWorker.submitCommand(IndexCommand.IndexSourceFile(sourceFile)) - } - - indexWorker.submitCommand(IndexCommand.IndexingComplete) - } - - fun stop() { - isRunning.set(false) - } + companion object { + private val logger = LoggerFactory.getLogger(ScanningWorker::class.java) + } + + suspend fun scan() = coroutineScope { + val sourceFiles = modules.asFlatSequence() + .filter { it.isSourceModule } + .flatMap { it.computeFiles(extended = true) } + .filter { + it.toNioPathOrNull()?.let { path -> kind.acceptsFile(path) } ?: run { + logger.warn("rejecting {} from kt source index", it) + false + } + } + .takeWhile { isActive } + .toList() + + sourceIndex.setActiveSources( + sourceFiles + .asSequence() + .map { it.path } + .takeWhile { isActive } + .toSet() + ) + + for (sourceFile in sourceFiles) { + if (!isActive) return@coroutineScope + indexWorker.submitCommand(IndexCommand.ScanSourceFile(sourceFile)) + } + + indexWorker.submitCommand(IndexCommand.SourceScanningComplete) + + sourceFiles.asSequence() + .takeWhile { isActive } + .forEach { sourceFile -> + indexWorker.submitCommand(IndexCommand.IndexSourceFile(sourceFile)) + } + + indexWorker.submitCommand(IndexCommand.IndexingComplete) + } } \ No newline at end of file diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/DeclarationsProvider.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/DeclarationsProvider.kt index 1b61343589..c65ddacdfb 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/DeclarationsProvider.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/DeclarationsProvider.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtClassLikeDeclaration import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtProperty @@ -76,9 +75,6 @@ internal class DeclarationProvider( private val index: KtSymbolIndex ) : KotlinDeclarationProvider { - private val KtElement.inScope: Boolean - get() = containingKtFile.virtualFile in scope - override val hasSpecificCallablePackageNamesComputation: Boolean get() = false override val hasSpecificClassifierPackageNamesComputation: Boolean diff --git a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/utils/VirtualFileExts.kt b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/utils/VirtualFileExts.kt index 2232db0561..a5bc54fc80 100644 --- a/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/utils/VirtualFileExts.kt +++ b/lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/utils/VirtualFileExts.kt @@ -1,7 +1,11 @@ package com.itsaky.androidide.lsp.kotlin.utils import org.jetbrains.kotlin.com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.kotlin.com.intellij.openapi.vfs.VirtualFileManager import java.nio.file.Path fun VirtualFile.toNioPathOrNull(): Path? = - runCatching { toNioPath() }.getOrNull() \ No newline at end of file + runCatching { toNioPath() }.getOrNull() + +fun Path.toVirtualFileOrNull(): VirtualFile? = + VirtualFileManager.getInstance().findFileByNioPath(this) \ No newline at end of file