[jigsaw] KTIJ-3634 handle cyclic dependencies. change recursion to BFS

GitOrigin-RevId: 4803db4dae33d69df0f8726a4f08004215e966b6
This commit is contained in:
Aleksey Dobrynin
2025-12-03 13:10:53 +00:00
committed by intellij-monorepo-bot
parent c358db2629
commit 3a3493cff2
2 changed files with 36 additions and 5 deletions
@@ -502,12 +502,20 @@ public final class JavaPsiModuleUtil {
source = getPhysicalModule(source);
destination = getPhysicalModule(destination);
Collection<PsiJavaModule> nodes = myGraph.getNodes();
if (nodes.contains(destination) && nodes.contains(source)) {
if (!nodes.contains(destination) || !nodes.contains(source)) {
return false;
}
UniqueBuffer<PsiJavaModule> buffer = new UniqueBuffer<>();
buffer.add(destination);
while (!buffer.isEmpty()) {
destination = buffer.poll();
Iterator<PsiJavaModule> directReaders = myGraph.getOut(destination);
while (directReaders.hasNext()) {
PsiJavaModule next = directReaders.next();
if (source.equals(next) || myTransitiveEdges.contains(key(destination, next)) && !next.equals(destination) && reads(source, next)) {
return true;
if (source.equals(next)) return true;
if (myTransitiveEdges.contains(key(destination, next)) && !next.equals(destination)) {
buffer.add(next);
}
}
}
@@ -591,6 +599,29 @@ public final class JavaPsiModuleUtil {
if (origin.getModuleDeclaration() instanceof PsiJavaModule result) return result;
return from;
}
/**
* FIFO queue that prevents duplicate additions.
* Once added, an element cannot be added again even after being polled.
*/
private static class UniqueBuffer<T> {
private final Set<T> myUnique = new HashSet<>();
private final Queue<T> myBuffer = new ArrayDeque<>();
public void add(T value) {
if (myUnique.add(value)) {
myBuffer.add(value);
}
}
public T poll() {
return myBuffer.poll();
}
public boolean isEmpty() {
return myBuffer.isEmpty();
}
}
}
/**
@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.caches.resolve
@@ -74,7 +74,7 @@ class Java9MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() {
checkHighlightingInProject()
}
fun _testCyclicDependency() {
fun testCyclicDependency() {
val a = module("moduleA")
val b = module("moduleB")
val c = module("moduleC")