[maven][IDEA-365902] fix IDEA freezing when the module tag is empty

GitOrigin-RevId: 3d2564877d0aac7e261e400cf1ba2ff023649613
This commit is contained in:
Alexander Bubenchikov
2025-10-20 12:07:17 +00:00
committed by intellij-monorepo-bot
parent 073b80516d
commit 24c4e4b024
3 changed files with 77 additions and 27 deletions
@@ -212,10 +212,12 @@ class MavenProjectResolver(private val myProject: Project) {
val virtualFile = VirtualFileManager.getInstance().findFileByNioPath(file) ?: return@forEach
val aggregatorProject = tree.findProject(virtualFile) ?: return@forEach
modules.forEach modules@{ modulePath ->
val moduleFile = file.parent.resolve(modulePath).resolve("pom.xml")
val moduleVirtualFile = VirtualFileManager.getInstance().findFileByNioPath(moduleFile) ?: return@modules
val moduleProject = tree.findProject(moduleVirtualFile) ?: return@modules
tree.reconnect(aggregatorProject, moduleProject)
if (modulePath.isNotBlank()) {
val moduleFile = file.parent.resolve(modulePath).resolve("pom.xml")
val moduleVirtualFile = VirtualFileManager.getInstance().findFileByNioPath(moduleFile) ?: return@modules
val moduleProject = tree.findProject(moduleVirtualFile) ?: return@modules
tree.reconnect(aggregatorProject, moduleProject)
}
}
}
@@ -348,7 +348,7 @@ class MavenProjectsTree(val project: Project) {
force: Boolean,
generalSettings: MavenGeneralSettings,
mavenEmbedderWrappers: MavenEmbedderWrappers,
process: MavenProgressIndicator
process: MavenProgressIndicator,
) {
runBlockingMaybeCancellable { updateAll(force, generalSettings, mavenEmbedderWrappers, process.indicator) }
}
@@ -358,7 +358,7 @@ class MavenProjectsTree(val project: Project) {
force: Boolean,
generalSettings: MavenGeneralSettings,
mavenEmbedderWrappers: MavenEmbedderWrappers,
process: ProgressIndicator
process: ProgressIndicator,
): MavenProjectsTreeUpdateResult {
return updateAll(force, generalSettings, mavenEmbedderWrappers, toRawProgressReporter(process))
}
@@ -400,11 +400,13 @@ class MavenProjectsTree(val project: Project) {
return update(files, false, force, projectReader, progressReporter)
}
private suspend fun update(files: Collection<VirtualFile>,
updateModules: Boolean,
forceRead: Boolean,
projectReader: MavenProjectReader,
progressReporter: RawProgressReporter): MavenProjectsTreeUpdateResult {
private suspend fun update(
files: Collection<VirtualFile>,
updateModules: Boolean,
forceRead: Boolean,
projectReader: MavenProjectReader,
progressReporter: RawProgressReporter,
): MavenProjectsTreeUpdateResult {
val updateContext = MavenProjectsTreeUpdateContext(this)
val updater = MavenProjectsTreeUpdater(
@@ -419,7 +421,7 @@ class MavenProjectsTree(val project: Project) {
if (null == findProject(file)) {
filesToAddModules.add(file)
}
tracer.spanBuilder("updateProjectFile").useWithScope { updater.updateProjects(listOf(UpdateSpec(file, forceRead))) }
tracer.spanBuilder("updateProjectFile").useWithScope { updater.updateProjects(listOf(UpdateSpec(file, forceRead))) }
}
for (aggregator in projects) {
@@ -490,9 +492,11 @@ class MavenProjectsTree(val project: Project) {
return delete(projectReader, files, progressReporter)
}
private suspend fun delete(projectReader: MavenProjectReader,
files: Collection<VirtualFile>,
progressReporter: RawProgressReporter): MavenProjectsTreeUpdateResult {
private suspend fun delete(
projectReader: MavenProjectReader,
files: Collection<VirtualFile>,
progressReporter: RawProgressReporter,
): MavenProjectsTreeUpdateResult {
val updateContext = MavenProjectsTreeUpdateContext(this)
val inheritorsToUpdate: MutableSet<MavenProject> = HashSet()
@@ -583,7 +587,7 @@ class MavenProjectsTree(val project: Project) {
val prevAggregator = findAggregator(project)
if (prevAggregator === newAggregator) return false
if (newAggregator === project) return false
withWriteLock {
if (prevAggregator != null) {
removeModule(prevAggregator, project)
@@ -780,11 +784,16 @@ class MavenProjectsTree(val project: Project) {
private fun doFindRootProject(project: MavenProject): MavenProject {
var rootProject = project
val traversed = LinkedHashSet<MavenProject>().also { it.add(project) }
while (true) {
val aggregator = myModuleToAggregatorMapping[rootProject]
if (aggregator == null) {
return rootProject
}
if (!traversed.add(aggregator)) {
MavenLog.LOG.warn("Recursive aggregator definition: ${traversed.joinToString(" -> ") { it.mavenId.toString() }}")
return project
}
rootProject = aggregator
}
}
@@ -941,9 +950,11 @@ class MavenProjectsTree(val project: Project) {
fun profilesChanged() {
}
fun projectsIgnoredStateChanged(ignored: List<MavenProject>,
unignored: List<MavenProject>,
fromImport: Boolean) {
fun projectsIgnoredStateChanged(
ignored: List<MavenProject>,
unignored: List<MavenProject>,
fromImport: Boolean,
) {
}
fun projectsUpdated(updated: List<Pair<MavenProject, MavenProjectChanges>>, deleted: List<MavenProject>) {
@@ -951,8 +962,10 @@ class MavenProjectsTree(val project: Project) {
@Suppress("DEPRECATION")
@Deprecated("use projectResolved(Pair<MavenProject, MavenProjectChanges>)")
fun projectResolved(projectWithChanges: Pair<MavenProject, MavenProjectChanges>,
nativeMavenProject: NativeMavenProjectHolder?) {
fun projectResolved(
projectWithChanges: Pair<MavenProject, MavenProjectChanges>,
nativeMavenProject: NativeMavenProjectHolder?,
) {
}
@Suppress("DEPRECATION")
@@ -1152,8 +1165,10 @@ class MavenProjectsTree(val project: Project) {
}
@Throws(IOException::class)
private fun readProjectsRecursively(inputStream: DataInputStream,
tree: MavenProjectsTree): MutableList<MavenProject> {
private fun readProjectsRecursively(
inputStream: DataInputStream,
tree: MavenProjectsTree,
): MutableList<MavenProject> {
var count = inputStream.readInt()
val result: MutableList<MavenProject> = ArrayList(count)
while (count-- > 0) {
@@ -1176,9 +1191,11 @@ class MavenProjectsTree(val project: Project) {
return result
}
private fun updateExplicitProfiles(explicitProfiles: MutableCollection<String>,
temporarilyRemovedExplicitProfiles: MutableCollection<String>,
available: Set<String>) {
private fun updateExplicitProfiles(
explicitProfiles: MutableCollection<String>,
temporarilyRemovedExplicitProfiles: MutableCollection<String>,
available: Set<String>,
) {
val removedProfiles = HashSet(explicitProfiles)
removedProfiles.removeAll(available)
temporarilyRemovedExplicitProfiles.addAll(removedProfiles)
@@ -21,7 +21,6 @@ import com.intellij.build.events.BuildIssueEvent
import com.intellij.build.events.MessageEvent
import com.intellij.maven.testFramework.MavenMultiVersionImportingTestCase
import com.intellij.openapi.application.edtWriteAction
import com.intellij.openapi.util.registry.Registry
import com.intellij.testFramework.UsefulTestCase
import com.intellij.testFramework.replaceService
import kotlinx.coroutines.runBlocking
@@ -1009,6 +1008,38 @@ class InvalidProjectImportingTest : MavenMultiVersionImportingTestCase() {
assertProblems(root, "'settings.xml' has syntax errors")
}
@Test
fun testImportingWithEmptyPath() = runBlocking {
importProjectAsync("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module></module>
</modules>
""".trimIndent())
assertModules("project")
val rootProject = projectsManager.findProject(projectPom)
assertNotNull("Project should be found", rootProject)
val rootOfRoot = projectsManager.findRootProject(rootProject!!)
assertNotNull("Root of root should be null", rootOfRoot)
}
@Test
fun testImportingWithSelfInclusionInclusion() = runBlocking {
importProjectAsync("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>./pom.xml</module>
</modules>
""".trimIndent())
assertModules("project")
}
private val rootProjects: List<MavenProject>
get() = projectsTree.rootProjects