mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] Remove custom seq in favor of stdlib sequence
I found a bug in TransformingIterator: hasNext isn't side-effect-free, and because of that calling hasNext() twice skips two elements. But then, I found that in comment in review IJ-MR-107533, where the custom seq was implemented, it was said that this seq is a temporary solution. So, let's remove it then. ^KTIJ-32260 GitOrigin-RevId: 0679789333698ec3a994ab05bd9f62fb75c2bc49
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4653aff32e
commit
8b15cc6700
+21
-23
@@ -45,17 +45,17 @@ private annotation class ModuleInfoDsl
|
||||
|
||||
@ModuleInfoDsl
|
||||
@K1ModeProjectStructureApi
|
||||
fun SeqScope<Result<IdeaModuleInfo>>.register(moduleInfo: IdeaModuleInfo) = yield { Result.success(moduleInfo) }
|
||||
suspend fun SequenceScope<Result<IdeaModuleInfo>>.register(moduleInfo: IdeaModuleInfo): Unit = yield(Result.success(moduleInfo))
|
||||
|
||||
@ModuleInfoDsl
|
||||
@K1ModeProjectStructureApi
|
||||
fun SeqScope<Result<IdeaModuleInfo>>.register(block: () -> IdeaModuleInfo?) = yield {
|
||||
block()?.let(Result.Companion::success)
|
||||
suspend fun SequenceScope<Result<IdeaModuleInfo>>.register(block: () -> IdeaModuleInfo?) {
|
||||
block()?.let { register(it) }
|
||||
}
|
||||
|
||||
@ModuleInfoDsl
|
||||
@K1ModeProjectStructureApi
|
||||
fun SeqScope<Result<IdeaModuleInfo>>.reportError(error: Throwable) = yield { Result.failure(error) }
|
||||
suspend fun SequenceScope<Result<IdeaModuleInfo>>.reportError(error: Throwable): Unit = yield(Result.failure(error))
|
||||
|
||||
@K1ModeProjectStructureApi
|
||||
interface ModuleInfoProviderExtension {
|
||||
@@ -64,15 +64,15 @@ interface ModuleInfoProviderExtension {
|
||||
ExtensionPointName("org.jetbrains.kotlin.idea.base.projectStructure.moduleInfoProviderExtension")
|
||||
}
|
||||
|
||||
fun SeqScope<Result<IdeaModuleInfo>>.collectByElement(element: PsiElement, file: PsiFile, virtualFile: VirtualFile)
|
||||
fun SeqScope<Result<IdeaModuleInfo>>.collectByFile(
|
||||
suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByElement(element: PsiElement, file: PsiFile, virtualFile: VirtualFile)
|
||||
suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByFile(
|
||||
project: Project,
|
||||
virtualFile: VirtualFile,
|
||||
isLibrarySource: Boolean,
|
||||
config: ModuleInfoProvider.Configuration,
|
||||
)
|
||||
|
||||
fun SeqScope<Module>.findContainingModules(project: Project, virtualFile: VirtualFile)
|
||||
suspend fun SequenceScope<Module>.findContainingModules(project: Project, virtualFile: VirtualFile)
|
||||
}
|
||||
|
||||
@Service(Service.Level.PROJECT)
|
||||
@@ -110,7 +110,7 @@ class ModuleInfoProvider(private val project: Project) {
|
||||
private val libraryInfoCache by lazy { LibraryInfoCache.getInstance(project) }
|
||||
|
||||
fun collect(element: PsiElement, config: Configuration = Configuration.Default): Sequence<Result<IdeaModuleInfo>> {
|
||||
return seq {
|
||||
return sequence {
|
||||
collectByElement(element, config)
|
||||
}
|
||||
}
|
||||
@@ -120,12 +120,12 @@ class ModuleInfoProvider(private val project: Project) {
|
||||
isLibrarySource: Boolean = false,
|
||||
config: Configuration = Configuration.Default,
|
||||
): Sequence<Result<IdeaModuleInfo>> {
|
||||
return seq {
|
||||
return sequence {
|
||||
collectByFile(virtualFile, isLibrarySource, config)
|
||||
}
|
||||
}
|
||||
|
||||
private fun SeqScope<Result<IdeaModuleInfo>>.collectByElement(element: PsiElement, config: Configuration) {
|
||||
private suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByElement(element: PsiElement, config: Configuration) {
|
||||
PsiUtilCore.ensureValid(element)
|
||||
val containingFile = element.containingFile
|
||||
|
||||
@@ -229,7 +229,7 @@ class ModuleInfoProvider(private val project: Project) {
|
||||
return if (config.createSourceLibraryInfoForLibraryBinaries) isCompiled else !isCompiled
|
||||
}
|
||||
|
||||
private fun SeqScope<Result<IdeaModuleInfo>>.collectByLightElement(element: KtLightElement<*, *>, config: Configuration) {
|
||||
private suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByLightElement(element: KtLightElement<*, *>, config: Configuration) {
|
||||
if (element.getNonStrictParentOfType<KtLightClassForDecompiledDeclaration>() != null) {
|
||||
val virtualFile = element.containingFile.virtualFile ?: error("Decompiled class should be build from physical file")
|
||||
collectByFile(virtualFile, isLibrarySource = false, config)
|
||||
@@ -248,7 +248,7 @@ class ModuleInfoProvider(private val project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun SeqScope<Result<IdeaModuleInfo>>.collectByFile(
|
||||
private suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByFile(
|
||||
virtualFile: VirtualFile,
|
||||
isLibrarySource: Boolean,
|
||||
config: Configuration,
|
||||
@@ -263,14 +263,12 @@ class ModuleInfoProvider(private val project: Project) {
|
||||
val visited = hashSetOf<IdeaModuleInfo>()
|
||||
val collectionRequest = VirtualFileCollectionRequest(virtualFile, isLibrarySource, config, visited, project)
|
||||
|
||||
yield {
|
||||
// Several libraries may include the same JAR files.
|
||||
// Below, we use an index for getting order entries for a file, but entries come in an arbitrary order.
|
||||
// So if we are already inside a library, we scan it first.
|
||||
// Several libraries may include the same JAR files.
|
||||
// Below, we use an index for getting order entries for a file, but entries come in an arbitrary order.
|
||||
// So if we are already inside a library, we scan it first.
|
||||
|
||||
val contextualModuleResult = contextByContextualBinaryModule(collectionRequest)
|
||||
contextualModuleResult?.let(Result.Companion::success)
|
||||
}
|
||||
val contextualModuleResult = contextByContextualBinaryModule(collectionRequest)
|
||||
contextualModuleResult?.let { yield(Result.success(it)) }
|
||||
|
||||
yieldAll(object : Iterable<Result<IdeaModuleInfo>> {
|
||||
override fun iterator(): Iterator<Result<IdeaModuleInfo>> {
|
||||
@@ -322,16 +320,16 @@ class ModuleInfoProvider(private val project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun SeqScope<Result<IdeaModuleInfo>>.collectSourceRelatedByFile(virtualFile: VirtualFile, config: Configuration) {
|
||||
private suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectSourceRelatedByFile(virtualFile: VirtualFile, config: Configuration) {
|
||||
yieldAll(object : Iterable<Result<IdeaModuleInfo>> {
|
||||
override fun iterator(): Iterator<Result<IdeaModuleInfo>> {
|
||||
val modules = seq {
|
||||
val modules = sequence {
|
||||
withCallExtensions(
|
||||
config = config,
|
||||
extensionBlock = { findContainingModules(project, virtualFile) },
|
||||
) {
|
||||
runReadAction { fileIndex.getModuleForFile(virtualFile) }?.let { module ->
|
||||
yield { module }
|
||||
yield(module)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -433,7 +431,7 @@ class ModuleInfoProvider(private val project: Project) {
|
||||
return service.hasDependentModule(this, contextualModuleInfo.module)
|
||||
}
|
||||
|
||||
private fun SeqScope<Result<IdeaModuleInfo>>.collectByUserData(container: UserDataModuleContainer) {
|
||||
private suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByUserData(container: UserDataModuleContainer) {
|
||||
register {
|
||||
val sourceRootType = container.customSourceRootType
|
||||
if (sourceRootType == null) return@register null
|
||||
|
||||
+4
-5
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.idea.base.projectStructure.ModuleInfoProviderExtensi
|
||||
import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo
|
||||
import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.base.projectStructure.register
|
||||
import org.jetbrains.kotlin.idea.base.util.SeqScope
|
||||
|
||||
/**
|
||||
* An extension to provide the correct [IdeaModuleInfo] for synthetic forward declaration files.
|
||||
@@ -21,7 +20,7 @@ import org.jetbrains.kotlin.idea.base.util.SeqScope
|
||||
* Results are tracked per-project by the [KotlinForwardDeclarationsFileOwnerTracker].
|
||||
*/
|
||||
internal class KotlinForwardDeclarationsModuleInfoProviderExtension : ModuleInfoProviderExtension {
|
||||
override fun SeqScope<Result<IdeaModuleInfo>>.collectByElement(
|
||||
override suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByElement(
|
||||
element: PsiElement,
|
||||
file: PsiFile,
|
||||
virtualFile: VirtualFile
|
||||
@@ -29,7 +28,7 @@ internal class KotlinForwardDeclarationsModuleInfoProviderExtension : ModuleInfo
|
||||
registerByVirtualFile(file.project, virtualFile)
|
||||
}
|
||||
|
||||
override fun SeqScope<Result<IdeaModuleInfo>>.collectByFile(
|
||||
override suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByFile(
|
||||
project: Project,
|
||||
virtualFile: VirtualFile,
|
||||
isLibrarySource: Boolean,
|
||||
@@ -39,9 +38,9 @@ internal class KotlinForwardDeclarationsModuleInfoProviderExtension : ModuleInfo
|
||||
}
|
||||
|
||||
// Kotlin/Native forward declarations can't belong to a module
|
||||
override fun SeqScope<Module>.findContainingModules(project: Project, virtualFile: VirtualFile) {}
|
||||
override suspend fun SequenceScope<Module>.findContainingModules(project: Project, virtualFile: VirtualFile) {}
|
||||
|
||||
private fun SeqScope<Result<IdeaModuleInfo>>.registerByVirtualFile(project: Project, virtualFile: VirtualFile) {
|
||||
private suspend fun SequenceScope<Result<IdeaModuleInfo>>.registerByVirtualFile(project: Project, virtualFile: VirtualFile) {
|
||||
if (!virtualFile.isValid) return
|
||||
KotlinForwardDeclarationsFileOwnerTracker.getInstance(project).getFileOwner(virtualFile)?.let { kaModule ->
|
||||
register(kaModule.moduleInfo)
|
||||
|
||||
@@ -1,39 +1,6 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.base.util
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun <T> seq(block: SeqScope<T>.() -> Unit): Sequence<T> = Sequence {
|
||||
val secScope = DefaultSeqScope<T>()
|
||||
block(secScope)
|
||||
val lazySequence = secScope.values
|
||||
SeqIterator(lazySequence)
|
||||
}
|
||||
|
||||
|
||||
private class DefaultSeqScope<T> : SeqScope<T>() {
|
||||
val values: MutableList<Iterable<T>> = mutableListOf()
|
||||
override fun yield(value: () -> T?) {
|
||||
values.add(object : Iterable<T> {
|
||||
override fun iterator(): Iterator<T> = object : TransformingIterator<T>() {
|
||||
private var provider: (() -> T?)? = value
|
||||
override fun calculateHasNext(): Boolean = provider != null
|
||||
|
||||
override fun calculateNext(): T? {
|
||||
val p = provider ?: throw NoSuchElementException()
|
||||
provider = null
|
||||
return p()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun yieldAll(value: Iterable<T>) {
|
||||
values.add(value)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TransformingIterator<T> : Iterator<T> {
|
||||
protected var next: T? = null
|
||||
@@ -75,40 +42,3 @@ class MappingIterator<K, T>(
|
||||
override fun calculateNext(): T? = mapping(iterator.next())
|
||||
}
|
||||
|
||||
private class SeqIterator<T>(providers: List<Iterable<T?>>) : TransformingIterator<T>() {
|
||||
private var providersIterator: Iterator<Iterable<T?>>? = providers.iterator()
|
||||
private var iterator: Iterator<T?>? = null
|
||||
override fun calculateHasNext(): Boolean {
|
||||
while (providersIterator != null) {
|
||||
if (iterator?.hasNext() == true) return true
|
||||
val providersIt = providersIterator
|
||||
if (providersIt?.hasNext() != true) {
|
||||
return false
|
||||
}
|
||||
val next = providersIt.next()
|
||||
val nextIterator = next.iterator()
|
||||
iterator = nextIterator
|
||||
if (nextIterator.hasNext()) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun calculateNext(): T? = iterator?.next()
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
val hasNext = super.hasNext()
|
||||
if (!hasNext) {
|
||||
iterator = null
|
||||
providersIterator = null
|
||||
}
|
||||
return hasNext
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
abstract class SeqScope<in T> internal constructor() {
|
||||
abstract fun yield(value: () -> T?)
|
||||
|
||||
abstract fun yieldAll(value: Iterable<T>)
|
||||
|
||||
}
|
||||
|
||||
+9
-13
@@ -21,16 +21,16 @@ import org.jetbrains.kotlin.idea.base.scripting.projectStructure.ScriptDependenc
|
||||
import org.jetbrains.kotlin.idea.base.scripting.projectStructure.ScriptModuleInfo
|
||||
import org.jetbrains.kotlin.idea.base.scripting.projectStructure.scriptLibraryDependencies
|
||||
import org.jetbrains.kotlin.idea.base.util.K1ModeProjectStructureApi
|
||||
import org.jetbrains.kotlin.idea.base.util.SeqScope
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptDependencyAware
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptRelatedModuleNameFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
||||
import org.jetbrains.kotlin.utils.yieldIfNotNull
|
||||
|
||||
@OptIn(K1ModeProjectStructureApi::class)
|
||||
internal class ScriptingModuleInfoProviderExtension : ModuleInfoProviderExtension {
|
||||
override fun SeqScope<Result<IdeaModuleInfo>>.collectByElement(
|
||||
override suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByElement(
|
||||
element: PsiElement,
|
||||
file: PsiFile,
|
||||
virtualFile: VirtualFile
|
||||
@@ -46,7 +46,7 @@ internal class ScriptingModuleInfoProviderExtension : ModuleInfoProviderExtensio
|
||||
}
|
||||
}
|
||||
|
||||
override fun SeqScope<Result<IdeaModuleInfo>>.collectByFile(
|
||||
override suspend fun SequenceScope<Result<IdeaModuleInfo>>.collectByFile(
|
||||
project: Project,
|
||||
virtualFile: VirtualFile,
|
||||
isLibrarySource: Boolean,
|
||||
@@ -57,7 +57,7 @@ internal class ScriptingModuleInfoProviderExtension : ModuleInfoProviderExtensio
|
||||
if (isBinary) {
|
||||
if (KotlinPluginModeProvider.isK2Mode()) {
|
||||
val scriptFile = (config.contextualModuleInfo as? ScriptModuleInfo)?.scriptFile
|
||||
scriptFile?.scriptLibraryDependencies(project)?.filter { virtualFile in it.contentScope }?.forEach(::register)
|
||||
scriptFile?.scriptLibraryDependencies(project)?.filter { virtualFile in it.contentScope }?.forEach { register(it) }
|
||||
} else if (ScriptDependencyAware.getInstance(project).getAllScriptsDependenciesClassFilesScope().contains(virtualFile)) {
|
||||
if (isLibrarySource) {
|
||||
register(ScriptDependenciesSourceInfo.ForProject(project))
|
||||
@@ -92,15 +92,11 @@ internal class ScriptingModuleInfoProviderExtension : ModuleInfoProviderExtensio
|
||||
}
|
||||
}
|
||||
|
||||
override fun SeqScope<Module>.findContainingModules(project: Project, virtualFile: VirtualFile) {
|
||||
yield {
|
||||
if (ScratchFileService.getInstance().getRootType(virtualFile) is ScratchRootType) {
|
||||
ScriptRelatedModuleNameFile[project, virtualFile]?.let { scratchModuleName ->
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
moduleManager.findModuleByName(scratchModuleName)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
override suspend fun SequenceScope<Module>.findContainingModules(project: Project, virtualFile: VirtualFile) {
|
||||
if (ScratchFileService.getInstance().getRootType(virtualFile) is ScratchRootType) {
|
||||
ScriptRelatedModuleNameFile[project, virtualFile]?.let { scratchModuleName ->
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
yieldIfNotNull(moduleManager.findModuleByName(scratchModuleName))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user