mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
don't schedule post-start-up activities under modal progress
GitOrigin-RevId: 2ac572b66cf0ad8bc28a5713bc71967a8700f19d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
aed14cb3c6
commit
57f7e14ea5
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.compiler;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
@@ -114,7 +114,7 @@ public final class CompilerConfigurationImpl extends CompilerConfiguration imple
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moduleAdded(@NotNull Project project, @NotNull Module module) {
|
||||
public void modulesAdded(@NotNull Project project, @NotNull List<Module> modules) {
|
||||
myProcessorsProfilesMap = null; // clear cache
|
||||
}
|
||||
|
||||
|
||||
@@ -1,96 +1,88 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.compiler;
|
||||
package com.intellij.compiler
|
||||
|
||||
import com.intellij.compiler.impl.ModuleCompileScope;
|
||||
import com.intellij.configurationStore.StoreUtilKt;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.intellij.compiler.impl.ModuleCompileScope
|
||||
import com.intellij.configurationStore.runInAllowSaveMode
|
||||
import com.intellij.ide.impl.runUnderModalProgressIfIsEdt
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.util.io.TestFileSystemBuilder
|
||||
import java.io.IOException
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.util.io.TestFileSystemBuilder.fs;
|
||||
|
||||
public class UnloadedModulesCompilationTest extends BaseCompilerTestCase {
|
||||
public void testDoNotCompileUnloadedModulesByDefault() {
|
||||
VirtualFile a = createFile("unloaded/src/A.java", "class A{ error }");
|
||||
Module unloaded = addModule("unloaded", a.getParent());
|
||||
List<String> unloadedList = Collections.singletonList(unloaded.getName());
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList);
|
||||
buildAllModules().assertUpToDate();
|
||||
class UnloadedModulesCompilationTest : BaseCompilerTestCase() {
|
||||
fun testDoNotCompileUnloadedModulesByDefault() {
|
||||
val a = createFile("unloaded/src/A.java", "class A{ error }")
|
||||
val unloaded = addModule("unloaded", a.parent)
|
||||
val unloadedList = listOf(unloaded.name)
|
||||
runUnderModalProgressIfIsEdt {
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList)
|
||||
}
|
||||
buildAllModules().assertUpToDate()
|
||||
}
|
||||
|
||||
public void testCompileUnloadedModulesIfExplicitlySpecified() {
|
||||
VirtualFile a = createFile("unloaded/src/A.java", "class A{}");
|
||||
Module unloaded = addModule("unloaded", a.getParent());
|
||||
File outputDir = getOutputDir(unloaded, false);
|
||||
|
||||
List<String> unloadedList = List.of(unloaded.getName());
|
||||
StoreUtilKt.runInAllowSaveMode(true, () -> {
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
make(createScopeWithUnloaded(Collections.emptyList(), unloadedList));
|
||||
fs().file("A.class").build().assertDirectoryEqual(outputDir);
|
||||
fun testCompileUnloadedModulesIfExplicitlySpecified() {
|
||||
val a = createFile("unloaded/src/A.java", "class A{}")
|
||||
val unloaded = addModule("unloaded", a.parent)
|
||||
val outputDir = getOutputDir(unloaded, false)
|
||||
val unloadedList = listOf(unloaded.name)
|
||||
runInAllowSaveMode(true) {
|
||||
runUnderModalProgressIfIsEdt {
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList)
|
||||
}
|
||||
}
|
||||
make(createScopeWithUnloaded(emptyList(), unloadedList))
|
||||
TestFileSystemBuilder.fs().file("A.class").build().assertDirectoryEqual(outputDir)
|
||||
}
|
||||
|
||||
public void testCompileUsagesOfConstantInUnloadedModules() throws IOException {
|
||||
VirtualFile utilFile = createFile("unloaded/src/Util.java", "class Util { public static final String FOO = \"foo\"; }");
|
||||
VirtualFile a = createFile("unloaded/src/A.java", "class A{ { System.out.println(Util.FOO); } }");
|
||||
Module unloaded = addModule("unloaded", a.getParent());
|
||||
buildAllModules();
|
||||
|
||||
List<String> unloadedList = Collections.singletonList(unloaded.getName());
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList);
|
||||
|
||||
changeFile(utilFile, VfsUtilCore.loadText(utilFile).replace("foo", "foo2"));
|
||||
|
||||
make(createScopeWithUnloaded(Collections.emptyList(), unloadedList)).assertGenerated("A.class", "Util.class");
|
||||
@Throws(IOException::class)
|
||||
fun testCompileUsagesOfConstantInUnloadedModules() {
|
||||
val utilFile = createFile("unloaded/src/Util.java", "class Util { public static final String FOO = \"foo\"; }")
|
||||
val a = createFile("unloaded/src/A.java", "class A{ { System.out.println(Util.FOO); } }")
|
||||
val unloaded = addModule("unloaded", a.parent)
|
||||
buildAllModules()
|
||||
val unloadedList = listOf(unloaded.name)
|
||||
runUnderModalProgressIfIsEdt {
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList)
|
||||
}
|
||||
changeFile(utilFile, VfsUtilCore.loadText(utilFile).replace("foo", "foo2"))
|
||||
make(createScopeWithUnloaded(emptyList(), unloadedList)).assertGenerated("A.class", "Util.class")
|
||||
}
|
||||
|
||||
public void testCompileUsagesOfConstantFromNormalModuleInInUnloadedModules() throws IOException {
|
||||
VirtualFile utilFile = createFile("util/src/Util.java", "class Util { public static final String FOO = \"foo\"; }");
|
||||
Module util = addModule("util", utilFile.getParent());
|
||||
VirtualFile a = createFile("unloaded/src/A.java", "class A{ { System.out.println(Util.FOO); } }");
|
||||
Module unloaded = addModule("unloaded", a.getParent());
|
||||
ModuleRootModificationUtil.addDependency(unloaded, util);
|
||||
buildAllModules();
|
||||
|
||||
List<String> unloadedList = Collections.singletonList(unloaded.getName());
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList);
|
||||
|
||||
changeFile(utilFile, VfsUtilCore.loadText(utilFile).replace("foo", "foo2"));
|
||||
|
||||
make(createScopeWithUnloaded(Collections.singletonList(util), unloadedList)).assertGenerated("A.class", "Util.class");
|
||||
@Throws(IOException::class)
|
||||
fun testCompileUsagesOfConstantFromNormalModuleInInUnloadedModules() {
|
||||
val utilFile = createFile("util/src/Util.java", "class Util { public static final String FOO = \"foo\"; }")
|
||||
val util = addModule("util", utilFile.parent)
|
||||
val a = createFile("unloaded/src/A.java", "class A{ { System.out.println(Util.FOO); } }")
|
||||
val unloaded = addModule("unloaded", a.parent)
|
||||
ModuleRootModificationUtil.addDependency(unloaded, util)
|
||||
buildAllModules()
|
||||
val unloadedList = listOf(unloaded.name)
|
||||
runUnderModalProgressIfIsEdt {
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList)
|
||||
}
|
||||
changeFile(utilFile, VfsUtilCore.loadText(utilFile).replace("foo", "foo2"))
|
||||
make(createScopeWithUnloaded(listOf(util), unloadedList)).assertGenerated("A.class", "Util.class")
|
||||
}
|
||||
|
||||
public void testCompileUnloadedModuleAfterBuildingAllLoadedModules() {
|
||||
VirtualFile utilFile = createFile("util/src/Util.java", "class Util { }");
|
||||
Module util = addModule("util", utilFile.getParent());
|
||||
VirtualFile a = createFile("unloaded/src/A.java", "class A { Util u = new Util(); }");
|
||||
Module unloaded = addModule("unloaded", a.getParent());
|
||||
ModuleRootModificationUtil.addDependency(unloaded, util);
|
||||
buildAllModules();
|
||||
|
||||
List<String> unloadedList = Collections.singletonList(unloaded.getName());
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList);
|
||||
|
||||
changeFile(utilFile, "class Util { Util(int i) {} }");
|
||||
buildAllModules().assertGenerated("Util.class");
|
||||
|
||||
compile(createScopeWithUnloaded(Collections.singletonList(util), unloadedList), false, true);
|
||||
fun testCompileUnloadedModuleAfterBuildingAllLoadedModules() {
|
||||
val utilFile = createFile("util/src/Util.java", "class Util { }")
|
||||
val util = addModule("util", utilFile.parent)
|
||||
val a = createFile("unloaded/src/A.java", "class A { Util u = new Util(); }")
|
||||
val unloaded = addModule("unloaded", a.parent)
|
||||
ModuleRootModificationUtil.addDependency(unloaded, util)
|
||||
buildAllModules()
|
||||
val unloadedList = listOf(unloaded.name)
|
||||
runUnderModalProgressIfIsEdt {
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(unloadedList)
|
||||
}
|
||||
changeFile(utilFile, "class Util { Util(int i) {} }")
|
||||
buildAllModules().assertGenerated("Util.class")
|
||||
compile(createScopeWithUnloaded(listOf(util), unloadedList), false, true)
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ModuleCompileScope createScopeWithUnloaded(List<Module> modules, List<String> unloaded) {
|
||||
return new ModuleCompileScope(myProject, modules, unloaded, true, false);
|
||||
private fun createScopeWithUnloaded(modules: List<Module>, unloaded: List<String>): ModuleCompileScope {
|
||||
return ModuleCompileScope(myProject, modules, unloaded, true, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ package com.intellij.compiler.progress
|
||||
import com.intellij.build.BuildWorkspaceConfiguration
|
||||
import com.intellij.compiler.BaseCompilerTestCase
|
||||
import com.intellij.compiler.CompilerWorkspaceConfiguration
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.compiler.CompilationStatusListener
|
||||
import com.intellij.openapi.compiler.CompileContext
|
||||
@@ -19,17 +18,15 @@ import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.testFramework.PlatformTestUtil
|
||||
import com.intellij.testFramework.PsiTestUtil.addSourceRoot
|
||||
import com.intellij.testFramework.RunAll
|
||||
import com.intellij.testFramework.common.runAll
|
||||
import com.intellij.testFramework.fixtures.BuildViewTestFixture
|
||||
import com.intellij.util.ThrowableRunnable
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootType
|
||||
|
||||
class CompilerBuildViewTest : BaseCompilerTestCase() {
|
||||
private lateinit var buildViewTestFixture: BuildViewTestFixture
|
||||
private val testDisposable: Disposable = Disposer.newDisposable()
|
||||
private val testDisposable = Disposer.newDisposable()
|
||||
|
||||
@Throws(Exception::class)
|
||||
public override fun setUp() {
|
||||
super.setUp()
|
||||
buildViewTestFixture = BuildViewTestFixture(project)
|
||||
@@ -37,11 +34,11 @@ class CompilerBuildViewTest : BaseCompilerTestCase() {
|
||||
}
|
||||
|
||||
public override fun tearDown() {
|
||||
RunAll(
|
||||
ThrowableRunnable { if (::buildViewTestFixture.isInitialized) buildViewTestFixture.tearDown() },
|
||||
ThrowableRunnable { Disposer.dispose(testDisposable) },
|
||||
ThrowableRunnable { super.tearDown() }
|
||||
).run()
|
||||
runAll (
|
||||
{ if (::buildViewTestFixture.isInitialized) buildViewTestFixture.tearDown() },
|
||||
{ Disposer.dispose(testDisposable) },
|
||||
{ super.tearDown() }
|
||||
)
|
||||
}
|
||||
|
||||
fun `test empty build`() {
|
||||
@@ -70,7 +67,7 @@ class CompilerBuildViewTest : BaseCompilerTestCase() {
|
||||
|
||||
runWithProgressExIndicatorSupport { rebuildProject() }
|
||||
buildViewTestFixture.assertBuildViewTreeEquals("-\n rebuild finished")
|
||||
buildViewTestFixture.assertBuildViewSelectedNode("rebuild finished", false) { output: String? ->
|
||||
buildViewTestFixture.assertBuildViewSelectedNode("rebuild finished", false) { output ->
|
||||
assertThat(output).startsWith("Clearing build system data...\n" +
|
||||
"Executing pre-compile tasks...\n" +
|
||||
"Cleaning output directories…\n" +
|
||||
@@ -91,7 +88,7 @@ class CompilerBuildViewTest : BaseCompilerTestCase() {
|
||||
|
||||
runWithProgressExIndicatorSupport { rebuild(module) }
|
||||
buildViewTestFixture.assertBuildViewTreeEquals("-\n recompile finished")
|
||||
buildViewTestFixture.assertBuildViewSelectedNode("recompile finished", false) { output: String? ->
|
||||
buildViewTestFixture.assertBuildViewSelectedNode("recompile finished", false) { output ->
|
||||
assertThat(output).startsWith("Executing pre-compile tasks...\n" +
|
||||
"Cleaning output directories…\n" +
|
||||
"Running 'before' tasks\n" +
|
||||
|
||||
@@ -122,7 +122,7 @@ public final class SnippetEditorDecorator implements EditorNotificationProvider
|
||||
myBusConnection = project.getMessageBus().connect();
|
||||
myBusConnection.subscribe(ProjectTopics.MODULES, new ModuleListener() {
|
||||
@Override
|
||||
public void moduleAdded(@NotNull Project project, @NotNull Module module) {
|
||||
public void modulesAdded(@NotNull Project project, @NotNull List<Module> modules) {
|
||||
reloadModules();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.configurationStore
|
||||
|
||||
import com.intellij.ProjectTopics
|
||||
@@ -78,7 +78,7 @@ class LoadProjectTest {
|
||||
val fooModule = ModuleManager.getInstance(project).modules.single()
|
||||
assertThat(fooModule.name).isEqualTo("foo")
|
||||
runWriteActionAndWait {
|
||||
val model = ModuleManager.getInstance(project).modifiableModel
|
||||
val model = ModuleManager.getInstance(project).getModifiableModel()
|
||||
model.loadModule("${project.basePath}/bar/bar.iml")
|
||||
model.commit()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.configurationStore
|
||||
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
@@ -43,7 +43,7 @@ class SaveProjectTest {
|
||||
val module = projectModel.createModule("foo")
|
||||
fun setGroupPath(path: Array<String>?) {
|
||||
runWriteActionAndWait {
|
||||
val model = projectModel.moduleManager.modifiableModel
|
||||
val model = projectModel.moduleManager.getModifiableModel()
|
||||
model.setModuleGroupPath(module, path)
|
||||
model.commit()
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class SaveProjectTest {
|
||||
|
||||
@Test
|
||||
fun `save renamed module`() {
|
||||
val model = runReadAction { projectModel.moduleManager.modifiableModel }
|
||||
val model = runReadAction { projectModel.moduleManager.getModifiableModel() }
|
||||
val module = projectModel.createModule("foo", model)
|
||||
model.renameModule(module, "bar")
|
||||
runWriteActionAndWait { model.commit() }
|
||||
|
||||
+45
-43
@@ -1,51 +1,53 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.roots.impl;
|
||||
package com.intellij.openapi.roots.impl
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.roots.DependencyScope;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ide.impl.runUnderModalProgressIfIsEdt
|
||||
import com.intellij.openapi.module.ModuleManager.Companion.getInstance
|
||||
import com.intellij.openapi.roots.DependencyScope
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.testFramework.HeavyPlatformTestCase
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DirectoryIndexForUnloadedModuleTest extends DirectoryIndexTestCase {
|
||||
public void testUnloadedModule() throws IOException {
|
||||
Module unloadedModule = createModule("unloaded");
|
||||
final File root = createTempDirectory();
|
||||
VirtualFile contentRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(root);
|
||||
ModuleRootModificationUtil.addContentRoot(unloadedModule, contentRoot.getPath());
|
||||
VirtualFile file = createChildData(contentRoot, "a.txt");
|
||||
assertInProject(file);
|
||||
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(Arrays.asList("unloaded"));
|
||||
|
||||
assertFromUnloadedModule(file, "unloaded");
|
||||
assertFromUnloadedModule(contentRoot, "unloaded");
|
||||
class DirectoryIndexForUnloadedModuleTest : DirectoryIndexTestCase() {
|
||||
@Throws(IOException::class)
|
||||
fun testUnloadedModule() {
|
||||
val unloadedModule = createModule("unloaded")
|
||||
val root = createTempDirectory()
|
||||
val contentRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(root)
|
||||
ModuleRootModificationUtil.addContentRoot(unloadedModule, contentRoot!!.path)
|
||||
val file = HeavyPlatformTestCase.createChildData(contentRoot, "a.txt")
|
||||
assertInProject(file)
|
||||
runUnderModalProgressIfIsEdt {
|
||||
getInstance(myProject).setUnloadedModules(Arrays.asList("unloaded"))
|
||||
}
|
||||
assertFromUnloadedModule(file, "unloaded")
|
||||
assertFromUnloadedModule(contentRoot, "unloaded")
|
||||
}
|
||||
|
||||
public void testDependentUnloadedModules() {
|
||||
Module unloadedModule = createModule("unloaded");
|
||||
Module main = createModule("main");
|
||||
Module util = createModule("util");
|
||||
Module common = createModule("common");
|
||||
ModuleRootModificationUtil.addDependency(unloadedModule, main);
|
||||
ModuleRootModificationUtil.addDependency(main, util);
|
||||
ModuleRootModificationUtil.addDependency(main, common, DependencyScope.COMPILE, true);
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(Arrays.asList("unloaded"));
|
||||
|
||||
assertSameElements(myIndex.getDependentUnloadedModules(main), "unloaded");
|
||||
assertEmpty(myIndex.getDependentUnloadedModules(util));
|
||||
assertSameElements(myIndex.getDependentUnloadedModules(common), "unloaded");
|
||||
fun testDependentUnloadedModules() {
|
||||
val unloadedModule = createModule("unloaded")
|
||||
val main = createModule("main")
|
||||
val util = createModule("util")
|
||||
val common = createModule("common")
|
||||
ModuleRootModificationUtil.addDependency(unloadedModule, main)
|
||||
ModuleRootModificationUtil.addDependency(main, util)
|
||||
ModuleRootModificationUtil.addDependency(main, common, DependencyScope.COMPILE, true)
|
||||
runUnderModalProgressIfIsEdt {
|
||||
getInstance(myProject).setUnloadedModules(Arrays.asList("unloaded"))
|
||||
}
|
||||
UsefulTestCase.assertSameElements(myIndex.getDependentUnloadedModules(main), "unloaded")
|
||||
UsefulTestCase.assertEmpty(myIndex.getDependentUnloadedModules(util))
|
||||
UsefulTestCase.assertSameElements(myIndex.getDependentUnloadedModules(common), "unloaded")
|
||||
}
|
||||
|
||||
private void assertFromUnloadedModule(VirtualFile file, String moduleName) {
|
||||
DirectoryInfo info = myIndex.getInfoForFile(file);
|
||||
assertTrue(info.toString(), info.isExcluded(file));
|
||||
assertNull(info.getModule());
|
||||
assertEquals(moduleName, info.getUnloadedModuleName());
|
||||
private fun assertFromUnloadedModule(file: VirtualFile?, moduleName: String) {
|
||||
val info = myIndex.getInfoForFile(file!!)
|
||||
assertTrue(info.toString(), info.isExcluded(file))
|
||||
assertNull(info.module)
|
||||
assertEquals(moduleName, info.unloadedModuleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-5
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.roots.ui.configuration.actions;
|
||||
|
||||
import com.intellij.ide.projectView.ProjectView;
|
||||
@@ -15,7 +15,6 @@ import com.intellij.testFramework.HeavyPlatformTestCase;
|
||||
import com.intellij.testFramework.MapDataContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ModuleDeleteProviderTest extends HeavyPlatformTestCase {
|
||||
@@ -56,7 +55,7 @@ public class ModuleDeleteProviderTest extends HeavyPlatformTestCase {
|
||||
|
||||
public void testUnloaded() {
|
||||
createModule("a");
|
||||
getModuleManager().setUnloadedModules(Arrays.asList("a"));
|
||||
getModuleManager().setUnloadedModulesSync(List.of("a"));
|
||||
assertNotNull(getModuleManager().getUnloadedModuleDescription("a"));
|
||||
deleteModules("a");
|
||||
assertNull(getModuleManager().getUnloadedModuleDescription("a"));
|
||||
@@ -66,7 +65,7 @@ public class ModuleDeleteProviderTest extends HeavyPlatformTestCase {
|
||||
Module a = createModule("a");
|
||||
Module b = createModule("b");
|
||||
ModuleRootModificationUtil.addDependency(a, b);
|
||||
getModuleManager().setUnloadedModules(Arrays.asList("b"));
|
||||
getModuleManager().setUnloadedModulesSync(List.of("b"));
|
||||
assertSameElements(ModuleRootManager.getInstance(a).getDependencyModuleNames(), "b");
|
||||
deleteModules("b");
|
||||
assertEmpty(ModuleRootManager.getInstance(a).getDependencyModuleNames());
|
||||
@@ -78,7 +77,7 @@ public class ModuleDeleteProviderTest extends HeavyPlatformTestCase {
|
||||
ModuleRootModificationUtil.addDependency(a, b);
|
||||
ModuleRootModificationUtil.addDependency(myModule, a);
|
||||
ModuleRootModificationUtil.addDependency(myModule, b);
|
||||
getModuleManager().setUnloadedModules(Arrays.asList("a"));
|
||||
getModuleManager().setUnloadedModulesSync(List.of("a"));
|
||||
assertSameElements(ModuleRootManager.getInstance(myModule).getDependencyModuleNames(), "a", "b");
|
||||
deleteModules("a", "b");
|
||||
assertNull(getModuleManager().findModuleByName("a"));
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.projectView
|
||||
|
||||
import com.intellij.ide.highlighter.ModuleFileType
|
||||
import com.intellij.ide.impl.runUnderModalProgressIfIsEdt
|
||||
import com.intellij.openapi.application.WriteAction
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
@@ -55,18 +56,20 @@ class ModulesInProjectViewTest : BaseProjectViewTestCase() {
|
||||
""".trimIndent()
|
||||
assertStructureEqual(expected)
|
||||
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(listOf("unloaded", "unloaded-inner"))
|
||||
runUnderModalProgressIfIsEdt {
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(listOf("unloaded", "unloaded-inner"))
|
||||
}
|
||||
assertStructureEqual("""
|
||||
Project
|
||||
loaded
|
||||
unloaded-inner
|
||||
subdir
|
||||
y.txt
|
||||
unloaded
|
||||
loaded-inner
|
||||
subdir
|
||||
z.txt
|
||||
""".trimIndent())
|
||||
Project
|
||||
loaded
|
||||
unloaded-inner
|
||||
subdir
|
||||
y.txt
|
||||
unloaded
|
||||
loaded-inner
|
||||
subdir
|
||||
z.txt
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun `test unloaded module with qualified name`() {
|
||||
@@ -93,7 +96,9 @@ class ModulesInProjectViewTest : BaseProjectViewTestCase() {
|
||||
""".trimIndent()
|
||||
assertStructureEqual(expected)
|
||||
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(listOf("unloaded"))
|
||||
runUnderModalProgressIfIsEdt {
|
||||
ModuleManager.getInstance(myProject).setUnloadedModules(listOf("unloaded"))
|
||||
}
|
||||
assertStructureEqual(expected)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.roots
|
||||
|
||||
import com.intellij.facet.FacetManager
|
||||
import com.intellij.facet.mock.MockFacetType
|
||||
import com.intellij.facet.mock.registerFacetType
|
||||
import com.intellij.ide.impl.runUnderModalProgressIfIsEdt
|
||||
import com.intellij.idea.TestFor
|
||||
import com.intellij.openapi.application.ex.PathManagerEx
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.module.StdModuleTypes
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
@@ -46,12 +45,16 @@ class UnloadedModulesConfigurationTest : JavaModuleTestCase() {
|
||||
ModuleRootModificationUtil.addContentRoot(a, contentRootPath)
|
||||
ModuleRootModificationUtil.addDependency(a, b)
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
moduleManager.setUnloadedModules(listOf("a"))
|
||||
runUnderModalProgressIfIsEdt {
|
||||
moduleManager.setUnloadedModules(listOf("a"))
|
||||
}
|
||||
assertEquals("a", assertOneElement(moduleManager.unloadedModuleDescriptions).name)
|
||||
assertNull(moduleManager.findModuleByName("a"))
|
||||
assertNotNull(moduleManager.findModuleByName("b"))
|
||||
|
||||
moduleManager.setUnloadedModules(listOf("b"))
|
||||
runUnderModalProgressIfIsEdt {
|
||||
moduleManager.setUnloadedModules(listOf("b"))
|
||||
}
|
||||
assertEquals("b", assertOneElement(moduleManager.unloadedModuleDescriptions).name)
|
||||
val newA = moduleManager.findModuleByName("a")
|
||||
assertNotNull(newA)
|
||||
@@ -73,12 +76,16 @@ class UnloadedModulesConfigurationTest : JavaModuleTestCase() {
|
||||
}
|
||||
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
moduleManager.setUnloadedModules(listOf("a"))
|
||||
runUnderModalProgressIfIsEdt {
|
||||
moduleManager.setUnloadedModules(listOf("a"))
|
||||
}
|
||||
assertEquals("a", assertOneElement(moduleManager.unloadedModuleDescriptions).name)
|
||||
assertNull(moduleManager.findModuleByName("a"))
|
||||
assertNotNull(moduleManager.findModuleByName("b"))
|
||||
|
||||
moduleManager.setUnloadedModules(listOf())
|
||||
runUnderModalProgressIfIsEdt {
|
||||
moduleManager.setUnloadedModules(listOf())
|
||||
}
|
||||
|
||||
val moduleA = ModuleManager.getInstance(project).findModuleByName("a")!!
|
||||
val allFacets = FacetManager.getInstance(moduleA).allFacets
|
||||
@@ -92,7 +99,9 @@ class UnloadedModulesConfigurationTest : JavaModuleTestCase() {
|
||||
val a = createModule("a")
|
||||
val aImlPath = a.moduleFilePath
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
moduleManager.setUnloadedModules(listOf("a"))
|
||||
runUnderModalProgressIfIsEdt {
|
||||
moduleManager.setUnloadedModules(listOf("a"))
|
||||
}
|
||||
assertEquals("a", assertOneElement(moduleManager.unloadedModuleDescriptions).name)
|
||||
|
||||
runWriteAction {
|
||||
@@ -105,16 +114,16 @@ class UnloadedModulesConfigurationTest : JavaModuleTestCase() {
|
||||
createModule("a")
|
||||
val b = createModule("b")
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
moduleManager.setUnloadedModules(listOf("a"))
|
||||
runUnderModalProgressIfIsEdt {
|
||||
moduleManager.setUnloadedModules(listOf("a"))
|
||||
}
|
||||
assertEquals("a", assertOneElement(moduleManager.unloadedModuleDescriptions).name)
|
||||
|
||||
runWriteAction {
|
||||
val model = moduleManager.modifiableModel
|
||||
val model = moduleManager.getModifiableModel()
|
||||
model.renameModule(b, "a")
|
||||
model.commit()
|
||||
}
|
||||
assertEmpty(moduleManager.unloadedModuleDescriptions)
|
||||
}
|
||||
|
||||
private fun getProjectManager() = ProjectManagerEx.getInstanceEx() as ProjectManagerImpl
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2000-2021 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.
|
||||
@file:Suppress("ReplaceGetOrSet")
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplaceGetOrSet", "ReplacePutWithAssignment")
|
||||
package com.intellij.serviceContainer
|
||||
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor
|
||||
|
||||
+6
-4
@@ -153,12 +153,14 @@ class SourceFolderManagerImpl(private val project: Project) : SourceFolderManage
|
||||
})
|
||||
|
||||
project.messageBus.connect().subscribe(ProjectTopics.MODULES, object : ModuleListener {
|
||||
override fun moduleAdded(project: Project, module: Module) {
|
||||
override fun modulesAdded(project: Project, modules: List<Module>) {
|
||||
synchronized(mutex) {
|
||||
moduleNamesToSourceFolderState[module.name].forEach {
|
||||
loadSourceFolderState(it, module)
|
||||
for (module in modules) {
|
||||
moduleNamesToSourceFolderState[module.name].forEach {
|
||||
loadSourceFolderState(it, module)
|
||||
}
|
||||
moduleNamesToSourceFolderState.remove(module.name)
|
||||
}
|
||||
moduleNamesToSourceFolderState.remove(module.name)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.externalSystem.service.project.manage
|
||||
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
@@ -103,7 +103,7 @@ class SourceFolderManagerTest: HeavyPlatformTestCase() {
|
||||
|
||||
private fun createModuleWithContentRoot(dir: File, moduleName: String = "topModule"): Module {
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
val modifiableModel = moduleManager.modifiableModel
|
||||
val modifiableModel = moduleManager.getModifiableModel()
|
||||
val newModule: Module =
|
||||
try {
|
||||
modifiableModel.newModule(dir.toPath().resolve(moduleName).toAbsolutePath(), ModuleTypeId.JAVA_MODULE)
|
||||
|
||||
@@ -2,7 +2,6 @@ project.configuration.save.file.not.found={0} not found
|
||||
project.load.undefined.path.variables.message=There are undefined path variables in project configuration files.
|
||||
project.load.default.error=Error Loading Default Project
|
||||
project.loading.components=Loading components...
|
||||
project.preparing.workspace=Preparing workspace...
|
||||
project.configure.path.variables.title=Configure Path Variables
|
||||
project.open.select.from.multiple.processors.dialog.title=Open or Import Project
|
||||
project.open.select.from.multiple.processors.dialog.description.line1=Found {0} project configurations in ''{1}''.
|
||||
|
||||
@@ -105,7 +105,7 @@ val Project.modules: Array<Module>
|
||||
get() = ModuleManager.getInstance(this).modules
|
||||
|
||||
inline fun <T> Project.modifyModules(crossinline task: ModifiableModuleModel.() -> T): T {
|
||||
val model = ModuleManager.getInstance(this).modifiableModel
|
||||
val model = ModuleManager.getInstance(this).getModifiableModel()
|
||||
val result = model.task()
|
||||
runWriteAction {
|
||||
model.commit()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.facet.impl
|
||||
|
||||
import com.intellij.ProjectTopics
|
||||
@@ -13,7 +13,6 @@ import com.intellij.openapi.project.ModuleListener
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
|
||||
@Service
|
||||
internal class FacetEventsPublisher(private val project: Project) {
|
||||
@@ -23,8 +22,10 @@ internal class FacetEventsPublisher(private val project: Project) {
|
||||
init {
|
||||
val connection = project.messageBus.connect()
|
||||
connection.subscribe(ProjectTopics.MODULES, object : ModuleListener {
|
||||
override fun moduleAdded(project: Project, module: Module) {
|
||||
onModuleAdded(module)
|
||||
override fun modulesAdded(project: Project, modules: MutableList<Module>) {
|
||||
for (module in modules) {
|
||||
onModuleAdded(module)
|
||||
}
|
||||
}
|
||||
|
||||
override fun moduleRemoved(project: Project, module: Module) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.facet.impl;
|
||||
|
||||
import com.intellij.ProjectTopics;
|
||||
@@ -46,7 +46,7 @@ public final class ProjectFacetManagerImpl extends ProjectFacetManagerEx impleme
|
||||
}, project);
|
||||
project.getMessageBus().connect().subscribe(ProjectTopics.MODULES, new ModuleListener() {
|
||||
@Override
|
||||
public void moduleAdded(@NotNull Project project, @NotNull Module module) {
|
||||
public void modulesAdded(@NotNull Project project, @NotNull List<Module> modules) {
|
||||
myIndex = null;
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.facet.impl.pointers;
|
||||
|
||||
import com.intellij.facet.pointers.FacetPointersManager;
|
||||
@@ -10,18 +10,18 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FacetPointerModuleListener implements ModuleListener {
|
||||
|
||||
final class FacetPointerModuleListener implements ModuleListener {
|
||||
private final Project myProject;
|
||||
|
||||
public FacetPointerModuleListener(Project project) { myProject = project; }
|
||||
FacetPointerModuleListener(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moduleAdded(@NotNull Project project, @NotNull Module module) {
|
||||
public void modulesAdded(@NotNull Project project, @NotNull List<Module> modules) {
|
||||
FacetPointersManager manager = FacetPointersManager.getInstance(myProject);
|
||||
if (manager instanceof FacetPointersManagerImpl) {
|
||||
FacetPointersManagerImpl managerImpl = (FacetPointersManagerImpl)manager;
|
||||
managerImpl.refreshPointers();
|
||||
((FacetPointersManagerImpl)manager).refreshPointers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -18,6 +18,7 @@ import com.intellij.workspaceModel.storage.EntityStorage
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleDependencyItem
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleId
|
||||
import com.intellij.xml.util.XmlStringUtil
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* If some modules were unloaded and new modules appears after loading project configuration, automatically unloads those which
|
||||
@@ -119,7 +120,9 @@ internal class AutomaticModuleUnloaderImpl(private val project: Project) : Simpl
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
moduleManager.unloadedModuleDescriptions.mapTo(unloaded) { it.name }
|
||||
action(unloaded)
|
||||
moduleManager.setUnloadedModules(unloaded)
|
||||
project.coroutineScope.launch {
|
||||
moduleManager.setUnloadedModules(unloaded)
|
||||
}
|
||||
notification.expire()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.intellij.openapi.components.impl.stores.IComponentStore;
|
||||
import com.intellij.openapi.components.impl.stores.ModuleStore;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleComponent;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.impl.scopes.ModuleScopeProviderImpl;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
@@ -197,10 +196,10 @@ public class ModuleImpl extends ComponentManagerImpl implements ModuleEx {
|
||||
|
||||
@Override
|
||||
public void projectOpened() {
|
||||
//noinspection deprecation
|
||||
processInitializedComponents(ModuleComponent.class, (component, __) -> {
|
||||
//noinspection removal,UnnecessaryFullyQualifiedName
|
||||
processInitializedComponents(com.intellij.openapi.module.ModuleComponent.class, (component, __) -> {
|
||||
try {
|
||||
//noinspection deprecation
|
||||
//noinspection removal
|
||||
component.projectOpened();
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -212,17 +211,17 @@ public class ModuleImpl extends ComponentManagerImpl implements ModuleEx {
|
||||
|
||||
@Override
|
||||
public void projectClosed() {
|
||||
//noinspection deprecation
|
||||
List<ModuleComponent> components = new ArrayList<>();
|
||||
//noinspection deprecation
|
||||
processInitializedComponents(ModuleComponent.class, (component, __) -> {
|
||||
@SuppressWarnings({"removal", "UnnecessaryFullyQualifiedName"})
|
||||
List<com.intellij.openapi.module.ModuleComponent> components = new ArrayList<>();
|
||||
//noinspection removal,UnnecessaryFullyQualifiedName
|
||||
processInitializedComponents(com.intellij.openapi.module.ModuleComponent.class, (component, __) -> {
|
||||
components.add(component);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
for (int i = components.size() - 1; i >= 0; i--) {
|
||||
try {
|
||||
//noinspection deprecation
|
||||
//noinspection removal
|
||||
components.get(i).projectClosed();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
@@ -251,9 +250,9 @@ public class ModuleImpl extends ComponentManagerImpl implements ModuleEx {
|
||||
@Override
|
||||
public void moduleAdded() {
|
||||
isModuleAdded = true;
|
||||
//noinspection deprecation
|
||||
processInitializedComponents(ModuleComponent.class, (component, __) -> {
|
||||
//noinspection deprecation
|
||||
//noinspection removal,UnnecessaryFullyQualifiedName
|
||||
processInitializedComponents(com.intellij.openapi.module.ModuleComponent.class, (component, __) -> {
|
||||
//noinspection removal
|
||||
component.moduleAdded();
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
+6
-7
@@ -67,6 +67,8 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen
|
||||
|
||||
private final static ExtensionPointName<WatchedRootsProvider> WATCHED_ROOTS_PROVIDER_EP_NAME = new ExtensionPointName<>("com.intellij.roots.watchedRootsProvider");
|
||||
|
||||
private boolean isStartupActivityPerformed;
|
||||
|
||||
private final ExecutorService myExecutor = ApplicationManager.getApplication().isUnitTestMode()
|
||||
? ConcurrencyUtil.newSameThreadExecutorService()
|
||||
: AppExecutorUtil.createBoundedApplicationPoolExecutor("Project Root Manager", 1);
|
||||
@@ -119,7 +121,7 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen
|
||||
}
|
||||
});
|
||||
|
||||
StartupManager.getInstance(myProject).registerStartupActivity(() -> myStartupActivityPerformed = true);
|
||||
StartupManager.getInstance(myProject).registerStartupActivity(() -> isStartupActivityPerformed = true);
|
||||
|
||||
connection.subscribe(BatchUpdateListener.TOPIC, new BatchUpdateListener() {
|
||||
@Override
|
||||
@@ -209,7 +211,9 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen
|
||||
isFiringEvent = false;
|
||||
}
|
||||
|
||||
synchronizeRoots(indexingInfos);
|
||||
if (isStartupActivityPerformed) {
|
||||
EntityIndexingService.getInstance().indexChanges(myProject, indexingInfos);
|
||||
}
|
||||
addRootsToWatch();
|
||||
}
|
||||
|
||||
@@ -294,11 +298,6 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen
|
||||
}
|
||||
}
|
||||
|
||||
private void synchronizeRoots(@NotNull List<? extends RootsChangeRescanningInfo> indexingInfos) {
|
||||
if (!myStartupActivityPerformed) return;
|
||||
EntityIndexingService.getInstance().indexChanges(myProject, indexingInfos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearScopesCaches() {
|
||||
super.clearScopesCaches();
|
||||
|
||||
+5
-1
@@ -30,6 +30,7 @@ import com.intellij.util.graph.*
|
||||
import com.intellij.util.ui.GridBag
|
||||
import com.intellij.util.ui.tree.TreeUtil
|
||||
import com.intellij.xml.util.XmlStringUtil
|
||||
import kotlinx.coroutines.launch
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
import java.awt.GridBagConstraints
|
||||
@@ -198,7 +199,10 @@ class ConfigureUnloadedModulesDialog(private val project: Project, selectedModul
|
||||
}
|
||||
|
||||
override fun doOKAction() {
|
||||
ModuleManager.getInstance(project).setUnloadedModules(unloadedModulesTree.getAllModules().map { it.name })
|
||||
val unloadedModuleNames = unloadedModulesTree.getAllModules().map { it.name }
|
||||
project.coroutineScope.launch {
|
||||
ModuleManager.getInstance(project).setUnloadedModules(unloadedModuleNames)
|
||||
}
|
||||
super.doOKAction()
|
||||
}
|
||||
}
|
||||
|
||||
+7
-6
@@ -1,7 +1,8 @@
|
||||
// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.workspaceModel.ide.impl.legacyBridge.module
|
||||
|
||||
import com.intellij.configurationStore.RenameableStateStorageManager
|
||||
import com.intellij.facet.Facet
|
||||
import com.intellij.facet.FacetManager
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl
|
||||
@@ -23,16 +24,17 @@ import com.intellij.workspaceModel.ide.impl.legacyBridge.module.ModuleManagerBri
|
||||
import com.intellij.workspaceModel.ide.legacyBridge.ModuleBridge
|
||||
import com.intellij.workspaceModel.ide.toPath
|
||||
import com.intellij.workspaceModel.storage.EntityChange
|
||||
import com.intellij.workspaceModel.storage.MutableEntityStorage
|
||||
import com.intellij.workspaceModel.storage.VersionedEntityStorage
|
||||
import com.intellij.workspaceModel.storage.VersionedStorageChange
|
||||
import com.intellij.workspaceModel.storage.MutableEntityStorage
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.addModuleCustomImlDataEntity
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleEntity
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleId
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.modifyEntity
|
||||
import com.intellij.workspaceModel.storage.impl.VersionedEntityStorageOnStorage
|
||||
import com.intellij.workspaceModel.storage.url.VirtualFileUrl
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.modifyEntity
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
internal class ModuleBridgeImpl(
|
||||
override var moduleEntityId: ModuleId,
|
||||
name: String,
|
||||
@@ -97,7 +99,7 @@ internal class ModuleBridgeImpl(
|
||||
}
|
||||
|
||||
override fun initFacets() {
|
||||
FacetManager.getInstance(this).allFacets.forEach { it.initFacet() }
|
||||
FacetManager.getInstance(this).allFacets.forEach(Facet<*>::initFacet)
|
||||
}
|
||||
|
||||
override fun registerComponents(corePlugin: IdeaPluginDescriptor?,
|
||||
@@ -163,6 +165,7 @@ internal class ModuleBridgeImpl(
|
||||
}
|
||||
}
|
||||
else {
|
||||
@Suppress("DEPRECATION")
|
||||
if (getOptionValue(key) != value) {
|
||||
WriteAction.runAndWait<RuntimeException> {
|
||||
WorkspaceModel.getInstance(project).updateProjectModel { builder ->
|
||||
@@ -177,6 +180,4 @@ internal class ModuleBridgeImpl(
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
override fun getOptionsModificationCount(): Long = 0
|
||||
}
|
||||
+34
-24
@@ -24,37 +24,52 @@ import com.intellij.workspaceModel.ide.impl.legacyBridge.project.ProjectRootMana
|
||||
import com.intellij.workspaceModel.storage.EntitySource
|
||||
import com.intellij.workspaceModel.storage.EntityStorage
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleEntity
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
internal class ModuleBridgeLoaderService(private val project: Project) {
|
||||
companion object {
|
||||
private val LOG = logger<ModuleBridgeLoaderService>()
|
||||
}
|
||||
|
||||
private var storeToEntitySources: Pair<EntityStorage, List<EntitySource>>? = null
|
||||
private var activity: Activity? = null
|
||||
|
||||
private val loadModuleJob: Job
|
||||
|
||||
init {
|
||||
if (!project.isDefault) {
|
||||
val workspaceModel = WorkspaceModel.getInstance(project) as WorkspaceModelImpl
|
||||
if (project.isDefault) {
|
||||
loadModuleJob = CompletableDeferred(value = null)
|
||||
}
|
||||
else {
|
||||
val projectModelSynchronizer = JpsProjectModelSynchronizer.getInstance(project)
|
||||
if (projectModelSynchronizer != null) {
|
||||
if (workspaceModel.loadedFromCache && projectModelSynchronizer.hasNoSerializedJpsModules()) {
|
||||
LOG.warn("Loaded from cache, but no serialized modules found. Workspace model cache will be ignored, project structure will be recreated.")
|
||||
workspaceModel.ignoreCache() // sets `WorkspaceModelImpl#loadedFromCache` to `false`
|
||||
project.putUserData(PROJECT_LOADED_FROM_CACHE_BUT_HAS_NO_MODULES, true)
|
||||
if (projectModelSynchronizer == null) {
|
||||
loadModuleJob = CompletableDeferred(value = null)
|
||||
}
|
||||
else {
|
||||
val workspaceModel = WorkspaceModel.getInstance(project) as WorkspaceModelImpl
|
||||
if (workspaceModel.loadedFromCache) {
|
||||
if (projectModelSynchronizer.hasNoSerializedJpsModules()) {
|
||||
LOG.warn("Loaded from cache, but no serialized modules found. Workspace model cache will be ignored, project structure will be recreated.")
|
||||
workspaceModel.ignoreCache() // sets `WorkspaceModelImpl#loadedFromCache` to `false`
|
||||
project.putUserData(PROJECT_LOADED_FROM_CACHE_BUT_HAS_NO_MODULES, true)
|
||||
}
|
||||
|
||||
activity = StartUpMeasurer.startActivity("modules loading with cache", ActivityCategory.DEFAULT)
|
||||
loadModuleJob = project.coroutineScope.async {
|
||||
loadModules()
|
||||
}
|
||||
}
|
||||
if (!workspaceModel.loadedFromCache) {
|
||||
else {
|
||||
LOG.info("Workspace model loaded without cache. Loading real project state into workspace model. ${Thread.currentThread()}")
|
||||
activity = StartUpMeasurer.startActivity("modules loading without cache", ActivityCategory.DEFAULT)
|
||||
storeToEntitySources = projectModelSynchronizer.loadProjectToEmptyStorage(project)
|
||||
}
|
||||
else {
|
||||
activity = StartUpMeasurer.startActivity("modules loading with cache", ActivityCategory.DEFAULT)
|
||||
loadModules()
|
||||
loadModuleJob = CompletableDeferred(value = null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadModules() {
|
||||
private suspend fun loadModules() {
|
||||
val childActivity = activity?.startChild("modules instantiation")
|
||||
val moduleManager = ModuleManager.getInstance(project) as ModuleManagerComponentBridge
|
||||
val entities = moduleManager.entityStore.current.entities(ModuleEntity::class.java)
|
||||
@@ -72,8 +87,11 @@ internal class ModuleBridgeLoaderService(private val project: Project) {
|
||||
override suspend fun serviceCreated(project: Project) {
|
||||
LOG.debug { "Project component initialized" }
|
||||
val workspaceModel = WorkspaceModel.getInstance(project) as WorkspaceModelImpl
|
||||
|
||||
val moduleLoaderService = project.getService(ModuleBridgeLoaderService::class.java)
|
||||
moduleLoaderService.loadModuleJob.join()
|
||||
|
||||
if (!workspaceModel.loadedFromCache) {
|
||||
val moduleLoaderService = project.getService(ModuleBridgeLoaderService::class.java)
|
||||
val projectModelSynchronizer = JpsProjectModelSynchronizer.getInstance(project) ?: return
|
||||
projectModelSynchronizer.applyLoadedStorage(moduleLoaderService.storeToEntitySources)
|
||||
project.messageBus.syncPublisher(JpsProjectLoadedListener.LOADED).loaded()
|
||||
@@ -88,13 +106,5 @@ internal class ModuleBridgeLoaderService(private val project: Project) {
|
||||
}
|
||||
WorkspaceModelTopics.getInstance(project).notifyModulesAreLoaded()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = logger<ModuleBridgeProjectServiceInitializedListener>()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = logger<ModuleBridgeLoaderService>()
|
||||
}
|
||||
}
|
||||
+38
-23
@@ -1,22 +1,25 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.workspaceModel.ide.impl.legacyBridge.module
|
||||
|
||||
import com.intellij.ProjectTopics
|
||||
import com.intellij.diagnostic.ActivityCategory
|
||||
import com.intellij.diagnostic.StartUpMeasurer
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.components.ServiceDescriptor
|
||||
import com.intellij.openapi.components.impl.stores.IComponentStore
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.module.AutomaticModuleUnloader
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.module.impl.ModuleEx
|
||||
import com.intellij.openapi.module.impl.NonPersistentModuleStore
|
||||
import com.intellij.openapi.module.impl.UnloadedModulesListStorage
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.openapi.project.ProjectManagerListener
|
||||
import com.intellij.openapi.startup.InitProjectActivity
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.serviceContainer.ComponentManagerImpl
|
||||
@@ -32,32 +35,50 @@ import com.intellij.workspaceModel.ide.impl.legacyBridge.module.roots.ModuleRoot
|
||||
import com.intellij.workspaceModel.ide.impl.legacyBridge.project.ProjectRootsChangeListener
|
||||
import com.intellij.workspaceModel.ide.impl.legacyBridge.watcher.VirtualFileUrlWatcher
|
||||
import com.intellij.workspaceModel.ide.legacyBridge.ModuleBridge
|
||||
import com.intellij.workspaceModel.storage.*
|
||||
import com.intellij.workspaceModel.storage.EntityChange
|
||||
import com.intellij.workspaceModel.storage.MutableEntityStorage
|
||||
import com.intellij.workspaceModel.storage.VersionedEntityStorage
|
||||
import com.intellij.workspaceModel.storage.VersionedStorageChange
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.*
|
||||
import com.intellij.workspaceModel.storage.url.VirtualFileUrl
|
||||
import com.intellij.workspaceModel.storage.url.VirtualFileUrlManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.IOException
|
||||
import java.nio.file.Paths
|
||||
|
||||
class ModuleManagerComponentBridge(private val project: Project) : ModuleManagerBridgeImpl(project) {
|
||||
private val virtualFileManager: VirtualFileUrlManager = VirtualFileUrlManager.getInstance(project)
|
||||
|
||||
internal class ModuleManagerInitProjectActivity : InitProjectActivity {
|
||||
override suspend fun run(project: Project) {
|
||||
val activity = StartUpMeasurer.startActivity("firing modules_added event", ActivityCategory.DEFAULT)
|
||||
val moduleManager = ModuleManager.getInstance(project) as ModuleManagerComponentBridge
|
||||
val modules = moduleManager.modules().toList()
|
||||
withContext(Dispatchers.EDT) {
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
for (module in modules) {
|
||||
if (!module.isLoaded) {
|
||||
module.moduleAdded()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moduleManager.fireModulesAdded(modules)
|
||||
|
||||
for (module in modules) {
|
||||
module.projectOpened()
|
||||
}
|
||||
}
|
||||
activity.end()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
// default project doesn't have modules
|
||||
if (!project.isDefault) {
|
||||
val busConnection = project.messageBus.connect(this)
|
||||
busConnection.subscribe(ProjectManager.TOPIC, object : ProjectManagerListener {
|
||||
override fun projectOpened(eventProject: Project) {
|
||||
val activity = StartUpMeasurer.startActivity("firing modules_added event", ActivityCategory.DEFAULT)
|
||||
if (project == eventProject) {
|
||||
fireModulesAdded()
|
||||
for (module in modules()) {
|
||||
module.projectOpened()
|
||||
}
|
||||
}
|
||||
activity.end()
|
||||
}
|
||||
|
||||
override fun projectClosed(eventProject: Project) {
|
||||
if (project == eventProject) {
|
||||
for (module in modules()) {
|
||||
@@ -172,7 +193,7 @@ class ModuleManagerComponentBridge(private val project: Project) : ModuleManager
|
||||
oldModuleNames: MutableMap<Module, String>, event: VersionedStorageChange) {
|
||||
when (change) {
|
||||
is EntityChange.Removed -> {
|
||||
// It's possible case then idToModule doesn't contain element e.g if unloaded module was removed
|
||||
// It's possible case then idToModule doesn't contain element e.g. if unloaded module was removed
|
||||
val module = event.storageBefore.findModuleByEntity(change.entity)
|
||||
if (module != null) {
|
||||
fireEventAndDisposeModule(module)
|
||||
@@ -271,23 +292,17 @@ class ModuleManagerComponentBridge(private val project: Project) : ModuleManager
|
||||
|
||||
private fun List<EntityChange<LibraryEntity>>.filterModuleLibraryChanges() = filter { it.isModuleLibrary() }
|
||||
|
||||
private fun fireModulesAdded() {
|
||||
for (module in modules()) {
|
||||
fireModuleAddedInWriteAction(module)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fireModuleAddedInWriteAction(module: ModuleEx) {
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
if (!module.isLoaded) {
|
||||
module.moduleAdded()
|
||||
fireModuleAdded(module)
|
||||
fireModulesAdded(listOf(module))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fireModuleAdded(module: Module) {
|
||||
project.messageBus.syncPublisher(ProjectTopics.MODULES).moduleAdded(project, module)
|
||||
private fun fireModulesAdded(modules: List<Module>) {
|
||||
project.messageBus.syncPublisher(ProjectTopics.MODULES).modulesAdded(project, modules)
|
||||
}
|
||||
|
||||
override fun registerNonPersistentModuleStore(module: ModuleBridge) {
|
||||
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.roots
|
||||
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
@@ -260,7 +260,7 @@ class ModuleDependencyInRootModelTest {
|
||||
val a = projectModel.createModule("a")
|
||||
val model = createModifiableModel(mainModule)
|
||||
model.addModuleOrderEntry(a)
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.modifiableModel }
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.getModifiableModel() }
|
||||
moduleModel.renameModule(a, "b")
|
||||
val entry = dropModuleSourceEntry(model, 1).single() as ModuleOrderEntry
|
||||
assertThat(entry.module).isEqualTo(a)
|
||||
@@ -300,7 +300,7 @@ class ModuleDependencyInRootModelTest {
|
||||
|
||||
@Test
|
||||
fun `add not yet committed module`() {
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.modifiableModel }
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.getModifiableModel() }
|
||||
val a = projectModel.createModule("a", moduleModel)
|
||||
run {
|
||||
val model = createModifiableModel(mainModule)
|
||||
@@ -319,7 +319,7 @@ class ModuleDependencyInRootModelTest {
|
||||
|
||||
@Test
|
||||
fun `add not yet committed module and do not commit it`() {
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.modifiableModel }
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.getModifiableModel() }
|
||||
val a = projectModel.createModule("a", moduleModel)
|
||||
run {
|
||||
val model = createModifiableModel(mainModule)
|
||||
@@ -339,7 +339,7 @@ class ModuleDependencyInRootModelTest {
|
||||
|
||||
@Test
|
||||
fun `add not yet committed module with configuration accessor`() {
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.modifiableModel }
|
||||
val moduleModel = runReadAction { projectModel.moduleManager.getModifiableModel() }
|
||||
val a = projectModel.createModule("a", moduleModel)
|
||||
run {
|
||||
val model = createModifiableModel(mainModule, object : RootConfigurationAccessor() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.roots
|
||||
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
@@ -306,7 +306,7 @@ class ModuleModelTest {
|
||||
assertThat(modules[0].name).isEqualTo(antModuleName)
|
||||
|
||||
runWriteActionAndWait {
|
||||
moduleManager.modifiableModel.let { model ->
|
||||
moduleManager.getModifiableModel().let { model ->
|
||||
model.renameModule(antModule, mavenModuleName)
|
||||
model.renameModule(antModule, gradleModuleName)
|
||||
model.commit()
|
||||
@@ -373,7 +373,7 @@ class ModuleModelTest {
|
||||
private fun createModifiableModuleModel(): @NotNull ModifiableModuleModel {
|
||||
//we need to get module manager outside of read action because it may lazily initialize the project requiring write action
|
||||
val moduleManager = projectModel.moduleManager
|
||||
return runReadAction { moduleManager.modifiableModel }
|
||||
return runReadAction { moduleManager.getModifiableModel() }
|
||||
}
|
||||
|
||||
private fun getSortedModules() = runReadAction { projectModel.moduleManager.sortedModules }
|
||||
|
||||
@@ -1849,7 +1849,6 @@ notification.group.system.messages=System messages
|
||||
action.text.install.keymap=Install {0} Keymap
|
||||
action.text.search.for.keymap=Search for {0} Keymap plugin
|
||||
action.separator.file.templates=File templates
|
||||
startup.indicator.text.running.startup.activities=Running startup activities\u2026
|
||||
notification.configurable.display.name.notifications=Notifications
|
||||
dumb.balloon.this.action=This action
|
||||
dumb.balloon.none.of.the.following.actions=None of the following actions
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplaceGetOrSet")
|
||||
|
||||
package com.intellij.ide
|
||||
|
||||
import com.intellij.openapi.components.BaseState
|
||||
@@ -60,7 +62,7 @@ class RecentProjectManagerState : BaseState() {
|
||||
|
||||
fun validateRecentProjects(modCounter: AtomicLong) {
|
||||
val limit = AdvancedSettings.getInt("ide.max.recent.projects")
|
||||
if (additionalInfo.size <= limit) {
|
||||
if (additionalInfo.size <= limit || limit < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -68,7 +70,7 @@ class RecentProjectManagerState : BaseState() {
|
||||
val iterator = additionalInfo.keys.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val path = iterator.next()
|
||||
if (!additionalInfo[path]!!.opened) {
|
||||
if (!additionalInfo.get(path)!!.opened) {
|
||||
iterator.remove()
|
||||
break
|
||||
}
|
||||
|
||||
@@ -21,10 +21,12 @@ import com.intellij.openapi.application.ex.ApplicationManagerEx
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.diagnostic.runAndLogException
|
||||
import com.intellij.openapi.extensions.ExtensionNotApplicableException
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ProjectManagerListener
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx
|
||||
import com.intellij.openapi.project.impl.*
|
||||
import com.intellij.openapi.startup.ProjectPostStartupActivity
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
@@ -317,10 +319,6 @@ open class RecentProjectsManagerBase : RecentProjectsManager, PersistentStateCom
|
||||
}
|
||||
}
|
||||
|
||||
fun setLastOpenedProject(path: String) {
|
||||
state.lastOpenedProject = path
|
||||
}
|
||||
|
||||
fun getLastOpenedProject() = state.lastOpenedProject
|
||||
|
||||
init {
|
||||
@@ -336,28 +334,42 @@ open class RecentProjectsManagerBase : RecentProjectsManager, PersistentStateCom
|
||||
}, AWTEvent.WINDOW_EVENT_MASK)
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
suspend fun runProjectPostStartupActivity(project: Project) {
|
||||
if (disableUpdatingRecentInfo.get() || LightEdit.owns(project)) {
|
||||
return
|
||||
}
|
||||
|
||||
val projectPath = getProjectPath(project) ?: return
|
||||
synchronized(stateLock) {
|
||||
findAndRemoveNewlyClonedProject(projectPath)
|
||||
markPathRecent(projectPath, project)
|
||||
state.lastOpenedProject = projectPath
|
||||
|
||||
updateProjectOpenedState(project, updateTime = true)
|
||||
state.validateRecentProjects(modCounter)
|
||||
}
|
||||
|
||||
withContext(Dispatchers.EDT) {
|
||||
updateSystemDockMenu()
|
||||
}
|
||||
}
|
||||
|
||||
internal class MyProjectPostStartupActivity : ProjectPostStartupActivity {
|
||||
init {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
throw ExtensionNotApplicableException.create()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun execute(project: Project) {
|
||||
getInstanceEx().runProjectPostStartupActivity(project)
|
||||
}
|
||||
}
|
||||
|
||||
@Internal
|
||||
@VisibleForTesting
|
||||
class MyProjectListener : ProjectManagerListener {
|
||||
override fun projectOpened(project: Project) {
|
||||
val manager = getInstanceEx()
|
||||
if (manager.disableUpdatingRecentInfo.get() || LightEdit.owns(project)) {
|
||||
return
|
||||
}
|
||||
|
||||
manager.getProjectPath(project)?.let { path ->
|
||||
synchronized(manager.stateLock) {
|
||||
manager.findAndRemoveNewlyClonedProject(path)
|
||||
manager.markPathRecent(path, project)
|
||||
manager.setLastOpenedProject(path)
|
||||
|
||||
manager.updateProjectOpenedState(project, updateTime = true)
|
||||
manager.state.validateRecentProjects(manager.modCounter)
|
||||
}
|
||||
}
|
||||
updateSystemDockMenu()
|
||||
}
|
||||
|
||||
override fun projectClosing(project: Project) {
|
||||
val app = ApplicationManagerEx.getApplicationEx()
|
||||
if (app.isExitInProgress) {
|
||||
@@ -385,7 +397,7 @@ open class RecentProjectsManagerBase : RecentProjectsManager, PersistentStateCom
|
||||
fun getRecentPaths(): List<String> {
|
||||
synchronized(stateLock) {
|
||||
state.validateRecentProjects(modCounter)
|
||||
return state.additionalInfo.keys.toList().asReversed()
|
||||
return state.additionalInfo.keys.reversed()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide;
|
||||
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.project.ProjectManagerListener;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.openapi.wm.StatusBar;
|
||||
import com.intellij.openapi.wm.impl.ProjectFrameHelper;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.BitUtil;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.accessibility.Accessible;
|
||||
import javax.accessibility.AccessibleContext;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.CaretListener;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.text.AbstractDocument;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.HierarchyEvent;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* This class listens event from ProjectManager and cleanup some
|
||||
* internal Swing references.
|
||||
*
|
||||
* @author Vladimir Kondratyev
|
||||
*/
|
||||
public final class SwingCleanuper {
|
||||
private final Alarm myAlarm;
|
||||
|
||||
public SwingCleanuper(@NotNull Application application) {
|
||||
myAlarm = new Alarm(application);
|
||||
application.getMessageBus().connect().subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
|
||||
@Override
|
||||
public void projectOpened(@NotNull final Project project) {
|
||||
myAlarm.cancelAllRequests();
|
||||
}
|
||||
// Swing keeps references to the last focused component inside DefaultKeyboardFocusManager.realOppositeComponent
|
||||
// which is used to compose next focus event. Actually this component could be an editors or a tool window. To fix this
|
||||
// memory leak we (if the project was closed and a new one was not opened yet) request focus to the status bar and after
|
||||
// the focus events have passed the queue, we put 'null' to the DefaultKeyboardFocusManager.realOppositeComponent field.
|
||||
@Override
|
||||
public void projectClosed(@NotNull final Project project){
|
||||
myAlarm.cancelAllRequests();
|
||||
myAlarm.addRequest(
|
||||
() -> {
|
||||
// request focus into some focusable component inside IdeFrame
|
||||
ProjectFrameHelper frame = ProjectFrameHelper.getFrameHelper(KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow());
|
||||
if (frame != null) {
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
if (app != null && app.isActive()) {
|
||||
StatusBar statusBar = frame.getStatusBar();
|
||||
if (statusBar != null) {
|
||||
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(() -> IdeFocusManager.getGlobalInstance().requestFocus((JComponent)statusBar, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
2500
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (SystemInfo.isMac) {
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener(event -> {
|
||||
if (!Registry.is("ide.mac.fix.accessibleLeak")) return;
|
||||
|
||||
HierarchyEvent he = (HierarchyEvent)event;
|
||||
if (BitUtil.isSet(he.getChangeFlags(), HierarchyEvent.SHOWING_CHANGED)) {
|
||||
if (he.getComponent() != null && !he.getComponent().isShowing()) {
|
||||
Component c = he.getComponent();
|
||||
if (c instanceof JTextComponent) {
|
||||
JTextComponent textComponent = (JTextComponent)c;
|
||||
|
||||
CaretListener[] carets = textComponent.getListeners(CaretListener.class);
|
||||
for (CaretListener each : carets) {
|
||||
if (isCAccessibleListener(each)) {
|
||||
textComponent.removeCaretListener(each);
|
||||
}
|
||||
}
|
||||
|
||||
Document document = textComponent.getDocument();
|
||||
if (document instanceof AbstractDocument) {
|
||||
DocumentListener[] documentListeners = ((AbstractDocument)document).getDocumentListeners();
|
||||
for (DocumentListener each : documentListeners) {
|
||||
if (isCAccessibleListener(each)) {
|
||||
document.removeDocumentListener(each);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c instanceof JProgressBar) {
|
||||
JProgressBar bar = (JProgressBar)c;
|
||||
ChangeListener[] changeListeners = bar.getChangeListeners();
|
||||
for (ChangeListener each : changeListeners) {
|
||||
if (isCAccessibleListener(each)) {
|
||||
bar.removeChangeListener(each);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c instanceof JSlider) {
|
||||
JSlider slider = (JSlider)c;
|
||||
ChangeListener[] changeListeners = slider.getChangeListeners();
|
||||
for (ChangeListener each : changeListeners) {
|
||||
if (isCAccessibleListener(each)) {
|
||||
slider.removeChangeListener(each);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Field nativeAXResource_Field = null;
|
||||
Field accessibleContext_Field = null;
|
||||
try {
|
||||
nativeAXResource_Field = ReflectionUtil.findField(AccessibleContext.class, Object.class, "nativeAXResource");
|
||||
accessibleContext_Field = ReflectionUtil.findField(Component.class, AccessibleContext.class, "accessibleContext");
|
||||
}
|
||||
catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
|
||||
if (accessibleContext_Field != null) {
|
||||
try {
|
||||
// Component's AccessibleContext is not necessarily initialized. In this case we don't want to force its creation.
|
||||
// So, first we check the Component.accessibleContext field. The field has a protected access and it's a common
|
||||
// Swing pattern to set it in the Component.getAccessibleContext() method when it's overriden by a subclass
|
||||
// (and we're to follow it).
|
||||
AccessibleContext ac = (AccessibleContext)accessibleContext_Field.get(c);
|
||||
if (ac != null) {
|
||||
// The getter may have a side effect, so call it to get the up-to-date context.
|
||||
ac = c.getAccessibleContext();
|
||||
if (ac != null) {
|
||||
Object resource = nativeAXResource_Field.get(ac);
|
||||
if (resource != null && isCAccessible(resource)) {
|
||||
Field accessible = ReflectionUtil.findField(resource.getClass(), Accessible.class, "accessible");
|
||||
accessible.set(resource, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, AWTEvent.HIERARCHY_EVENT_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCAccessible(Object resource) {
|
||||
final String name = resource.getClass().getName();
|
||||
return isCAccessible(name);
|
||||
}
|
||||
|
||||
static boolean isCAccessible(String name) {
|
||||
return name.equals("apple.awt.CAccessible") || name.equals("sun.lwawt.macosx.CAccessible");
|
||||
}
|
||||
|
||||
private static boolean isCAccessibleListener(EventListener listener) {
|
||||
return listener != null && listener.toString().contains("AXTextChangeNotifier");
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ide.actions.project
|
||||
|
||||
import com.intellij.CommonBundle
|
||||
@@ -174,7 +174,7 @@ internal class ConvertModuleGroupsToQualifiedNamesDialog(val project: Project) :
|
||||
|
||||
val renamingScheme = getRenamingScheme()
|
||||
if (renamingScheme.isNotEmpty()) {
|
||||
val model = ModuleManager.getInstance(project).modifiableModel
|
||||
val model = ModuleManager.getInstance(project).getModifiableModel()
|
||||
val byName = modules.associateBy { it.name }
|
||||
for (entry in renamingScheme) {
|
||||
model.renameModule(byName[entry.key]!!, entry.value)
|
||||
|
||||
+63
-72
@@ -1,88 +1,79 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ide.lightEdit.project;
|
||||
package com.intellij.ide.lightEdit.project
|
||||
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.project.ProjectManagerListener;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.util.TimeoutUtil;
|
||||
import kotlin.coroutines.EmptyCoroutineContext;
|
||||
import kotlinx.coroutines.BuildersKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import com.intellij.ide.impl.runUnderModalProgressIfIsEdt
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl
|
||||
import com.intellij.openapi.actionSystem.ActionManager
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.openapi.project.ProjectManagerListener
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.util.TimeoutUtil
|
||||
|
||||
public final class LightEditProjectManager {
|
||||
private static final Logger LOG = Logger.getInstance(LightEditProjectManager.class);
|
||||
private static final Object LOCK = new Object();
|
||||
class LightEditProjectManager {
|
||||
companion object {
|
||||
private val LOG = logger<LightEditProjectManager>()
|
||||
private val LOCK = Any()
|
||||
|
||||
private volatile LightEditProjectImpl myProject;
|
||||
private fun fireProjectOpened(project: Project) {
|
||||
val app = ApplicationManager.getApplication()
|
||||
val fireRunnable = Runnable {
|
||||
// similar to com.intellij.openapi.project.impl.ProjectManagerExImplKt.openProject
|
||||
app.messageBus.syncPublisher(ProjectManager.TOPIC).projectOpened(project)
|
||||
runUnderModalProgressIfIsEdt {
|
||||
val startupManager = StartupManager.getInstance(project) as StartupManagerImpl
|
||||
startupManager.initProject(null)
|
||||
startupManager.runStartupActivities()
|
||||
}
|
||||
}
|
||||
if (app.isDispatchThread || app.isUnitTestMode) {
|
||||
fireRunnable.run()
|
||||
}
|
||||
else {
|
||||
// Initialize ActionManager out of EDT to pass "assert !app.isDispatchThread()" in ActionManagerImpl
|
||||
ActionManager.getInstance()
|
||||
app.invokeLater(fireRunnable)
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable Project getProject() {
|
||||
return myProject;
|
||||
private fun createProject(): LightEditProjectImpl {
|
||||
val start = System.nanoTime()
|
||||
val project = LightEditProjectImpl()
|
||||
LOG.info(LightEditProjectImpl::class.java.simpleName + " loaded in " + TimeoutUtil.getDurationMillis(start) + " ms")
|
||||
return project
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull Project getOrCreateProject() {
|
||||
LightEditProjectImpl project = myProject;
|
||||
@Volatile
|
||||
private var projectImpl: LightEditProjectImpl? = null
|
||||
|
||||
val project: Project?
|
||||
get() = projectImpl
|
||||
|
||||
fun getOrCreateProject(): Project {
|
||||
var project = projectImpl
|
||||
if (project == null) {
|
||||
boolean created = false;
|
||||
synchronized (LOCK) {
|
||||
if (myProject == null) {
|
||||
myProject = createProject();
|
||||
created = true;
|
||||
var created = false
|
||||
synchronized(LOCK) {
|
||||
if (projectImpl == null) {
|
||||
projectImpl = createProject()
|
||||
created = true
|
||||
}
|
||||
project = myProject;
|
||||
project = projectImpl
|
||||
}
|
||||
if (created) {
|
||||
fireProjectOpened(project);
|
||||
ApplicationManager.getApplication().getMessageBus().connect().subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
|
||||
@Override
|
||||
public void projectClosed(@NotNull Project project) {
|
||||
if (project == myProject) {
|
||||
synchronized (LOCK) {
|
||||
myProject = null;
|
||||
}
|
||||
fireProjectOpened(project!!)
|
||||
ApplicationManager.getApplication().messageBus.connect().subscribe(ProjectManager.TOPIC, object : ProjectManagerListener {
|
||||
override fun projectClosed(project: Project) {
|
||||
if (project === projectImpl) {
|
||||
synchronized(LOCK) { projectImpl = null }
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
return project;
|
||||
return project!!
|
||||
}
|
||||
|
||||
private static void fireProjectOpened(@NotNull Project project) {
|
||||
Application app = ApplicationManager.getApplication();
|
||||
Runnable fireRunnable = () -> {
|
||||
// similar to com.intellij.openapi.project.impl.ProjectManagerExImplKt.openProject
|
||||
app.getMessageBus().syncPublisher(ProjectManager.TOPIC).projectOpened(project);
|
||||
try {
|
||||
BuildersKt.runBlocking(EmptyCoroutineContext.INSTANCE, (scope, continuation) -> {
|
||||
((StartupManagerImpl)StartupManager.getInstance(project)).projectOpened(null, continuation);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
if (app.isDispatchThread() || app.isUnitTestMode()) {
|
||||
fireRunnable.run();
|
||||
}
|
||||
else {
|
||||
// Initialize ActionManager out of EDT to pass "assert !app.isDispatchThread()" in ActionManagerImpl
|
||||
ActionManager.getInstance();
|
||||
app.invokeLater(fireRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
private static @NotNull LightEditProjectImpl createProject() {
|
||||
long start = System.nanoTime();
|
||||
LightEditProjectImpl project = new LightEditProjectImpl();
|
||||
LOG.info(LightEditProjectImpl.class.getSimpleName() + " loaded in " + TimeoutUtil.getDurationMillis(start) + " ms");
|
||||
return project;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,9 +75,7 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
if (activity is DumbAware) {
|
||||
project.coroutineScope.launch {
|
||||
if (activity is ProjectPostStartupActivity) {
|
||||
DumbService.getInstance(project).runWithWaitForSmartModeDisabled().use {
|
||||
startupManager.runActivityAndMeasureDuration(activity, descriptor.pluginId, project !is LightEditCompatible)
|
||||
}
|
||||
startupManager.runActivityAndMeasureDuration(activity, descriptor.pluginId, project !is LightEditCompatible)
|
||||
}
|
||||
else {
|
||||
startupManager.runActivityAndMeasureDuration(activity, pluginId)
|
||||
@@ -95,7 +93,7 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
}
|
||||
|
||||
private val lock = Any()
|
||||
private val startupActivities = ArrayDeque<Runnable>()
|
||||
private val initProjectStartupActivities = ArrayDeque<Runnable>()
|
||||
private val postStartupActivities = ArrayDeque<Runnable>()
|
||||
|
||||
@MagicConstant(intValues = [0, DUMB_AWARE_PASSED.toLong(), ALL_PASSED.toLong()])
|
||||
@@ -104,7 +102,7 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
private val allActivitiesPassed = CompletableDeferred<Any?>()
|
||||
|
||||
@Volatile
|
||||
private var isStartupActivitiesPassed = false
|
||||
private var isInitProjectActivitiesPassed = false
|
||||
|
||||
private fun checkNonDefaultProject() {
|
||||
LOG.assertTrue(!project.isDefault, "Please don't register startup activities for the default project: they won't ever be run")
|
||||
@@ -112,9 +110,9 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
|
||||
override fun registerStartupActivity(runnable: Runnable) {
|
||||
checkNonDefaultProject()
|
||||
LOG.assertTrue(!isStartupActivitiesPassed, "Registering startup activity that will never be run")
|
||||
LOG.assertTrue(!isInitProjectActivitiesPassed, "Registering startup activity that will never be run")
|
||||
synchronized(lock) {
|
||||
startupActivities.add(runnable)
|
||||
initProjectStartupActivities.add(runnable)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,12 +133,12 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
LOG.error("Registering post-startup activity that will never be run (" +
|
||||
" disposed=${project.isDisposed}" +
|
||||
", open=${project.isOpen}" +
|
||||
", passed=$isStartupActivitiesPassed"
|
||||
", passed=$isInitProjectActivitiesPassed"
|
||||
+ ")")
|
||||
}
|
||||
}
|
||||
|
||||
override fun startupActivityPassed() = isStartupActivitiesPassed
|
||||
override fun startupActivityPassed() = isInitProjectActivitiesPassed
|
||||
|
||||
override fun postStartupActivityPassed(): Boolean {
|
||||
return when (postStartupActivitiesPassed) {
|
||||
@@ -152,17 +150,18 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
|
||||
override fun getAllActivitiesPassedFuture() = allActivitiesPassed
|
||||
|
||||
suspend fun projectOpened(indicator: ProgressIndicator?) {
|
||||
val app = ApplicationManager.getApplication()
|
||||
suspend fun initProject(indicator: ProgressIndicator?) {
|
||||
// see https://github.com/JetBrains/intellij-community/blob/master/platform/service-container/overview.md#startup-activity
|
||||
LOG.assertTrue(!isStartupActivitiesPassed)
|
||||
LOG.assertTrue(!isInitProjectActivitiesPassed)
|
||||
runActivity("project startup") {
|
||||
tracer.spanBuilder("run startup activities").useWithScope {
|
||||
runStartUpActivities(indicator, app)
|
||||
isStartupActivitiesPassed = true
|
||||
tracer.spanBuilder("run init project activities").useWithScope {
|
||||
runInitProjectActivities(indicator)
|
||||
isInitProjectActivitiesPassed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun runStartupActivities() {
|
||||
// opened on startup
|
||||
StartUpMeasurer.compareAndSetCurrentState(LoadingState.COMPONENTS_LOADED, LoadingState.PROJECT_OPENED)
|
||||
// opened from the welcome screen
|
||||
@@ -170,6 +169,7 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
|
||||
coroutineContext.ensureActive()
|
||||
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (app.isUnitTestMode && !app.isDispatchThread) {
|
||||
runPostStartupActivities()
|
||||
}
|
||||
@@ -180,14 +180,14 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
}
|
||||
if (app.isUnitTestMode) {
|
||||
LOG.assertTrue(app.isDispatchThread)
|
||||
@Suppress("TestOnlyProblems")
|
||||
waitAndProcessInvocationEventsInIdeEventQueue(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun runStartUpActivities(indicator: ProgressIndicator?, app: Application) {
|
||||
runActivities(startupActivities)
|
||||
private suspend fun runInitProjectActivities(indicator: ProgressIndicator?) {
|
||||
runActivities(initProjectStartupActivities)
|
||||
val app = ApplicationManager.getApplication()
|
||||
val extensionPoint = (app.extensionArea as ExtensionsAreaImpl).getExtensionPoint<StartupActivity>("com.intellij.startupActivity")
|
||||
|
||||
// do not create extension if not allow-listed
|
||||
@@ -224,7 +224,7 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
// Must be executed in a pooled thread outside of project loading modal task. The only exclusion - test mode.
|
||||
private suspend fun runPostStartupActivities() {
|
||||
try {
|
||||
LOG.assertTrue(isStartupActivitiesPassed)
|
||||
LOG.assertTrue(isInitProjectActivitiesPassed)
|
||||
val snapshot = PerformanceWatcher.takeSnapshot()
|
||||
// strictly speaking, the activity is not sequential, because sub-activities are performed in different threads
|
||||
// (depending on dumb-awareness), but because there is no other concurrent phase, we measure it as a sequential activity
|
||||
@@ -237,36 +237,33 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
val isProjectLightEditCompatible = project is LightEditCompatible
|
||||
StartupActivity.POST_STARTUP_ACTIVITY.processExtensions { activity, pluginDescriptor ->
|
||||
if (activity is ProjectPostStartupActivity) {
|
||||
runActivityAndMeasureDuration(activity, pluginDescriptor.pluginId, isProjectLightEditCompatible)
|
||||
return@processExtensions
|
||||
}
|
||||
|
||||
@Suppress("SSBasedInspection")
|
||||
if (activity is DumbAware) {
|
||||
dumbService.runWithWaitForSmartModeDisabled().use {
|
||||
runActivityAndMeasureDuration(activity, pluginDescriptor.pluginId, isProjectLightEditCompatible)
|
||||
runActivityAndMeasureDuration(activity, pluginDescriptor.pluginId)
|
||||
}
|
||||
return@processExtensions
|
||||
}
|
||||
else {
|
||||
@Suppress("SSBasedInspection")
|
||||
if (activity is DumbAware) {
|
||||
dumbService.runWithWaitForSmartModeDisabled().use {
|
||||
runActivityAndMeasureDuration(activity, pluginDescriptor.pluginId)
|
||||
}
|
||||
return@processExtensions
|
||||
if (edtActivity.get() == null) {
|
||||
edtActivity.set(StartUpMeasurer.startActivity("project post-startup edt activities"))
|
||||
}
|
||||
else {
|
||||
if (edtActivity.get() == null) {
|
||||
edtActivity.set(StartUpMeasurer.startActivity("project post-startup edt activities"))
|
||||
}
|
||||
|
||||
// DumbService.unsafeRunWhenSmart throws an assertion in LightEdit mode, see LightEditDumbService.unsafeRunWhenSmart
|
||||
if (!isProjectLightEditCompatible) {
|
||||
counter.incrementAndGet()
|
||||
val traceContext = Context.current()
|
||||
dumbService.unsafeRunWhenSmart {
|
||||
traceContext.makeCurrent()
|
||||
val duration = runActivityAndMeasureDuration(activity, pluginDescriptor.pluginId)
|
||||
if (duration > EDT_WARN_THRESHOLD_IN_NANO) {
|
||||
reportUiFreeze(uiFreezeWarned)
|
||||
}
|
||||
dumbUnawarePostActivitiesPassed(edtActivity, counter.decrementAndGet())
|
||||
// DumbService.unsafeRunWhenSmart throws an assertion in LightEdit mode, see LightEditDumbService.unsafeRunWhenSmart
|
||||
if (!isProjectLightEditCompatible) {
|
||||
counter.incrementAndGet()
|
||||
val traceContext = Context.current()
|
||||
dumbService.unsafeRunWhenSmart {
|
||||
traceContext.makeCurrent()
|
||||
val duration = runActivityAndMeasureDuration(activity, pluginDescriptor.pluginId)
|
||||
if (duration > EDT_WARN_THRESHOLD_IN_NANO) {
|
||||
reportUiFreeze(uiFreezeWarned)
|
||||
}
|
||||
dumbUnawarePostActivitiesPassed(edtActivity, counter.decrementAndGet())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -324,7 +321,7 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
activity: ProjectPostStartupActivity,
|
||||
pluginId: PluginId,
|
||||
isProjectLightEditCompatible: Boolean
|
||||
): Long {
|
||||
) {
|
||||
val startTime = StartUpMeasurer.getCurrentTime()
|
||||
tracer.spanBuilder("run activity")
|
||||
.setAttribute(AttributeKey.stringKey("class"), activity.javaClass.name)
|
||||
@@ -334,7 +331,7 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
activity.execute(project)
|
||||
}
|
||||
}
|
||||
return addCompletedActivity(startTime = startTime, runnableClass = activity.javaClass, pluginId = pluginId)
|
||||
addCompletedActivity(startTime = startTime, runnableClass = activity.javaClass, pluginId = pluginId)
|
||||
}
|
||||
|
||||
private suspend fun runPostStartupActivitiesRegisteredDynamically() {
|
||||
@@ -464,7 +461,7 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
@Synchronized
|
||||
fun prepareForNextTest() {
|
||||
synchronized(lock) {
|
||||
startupActivities.clear()
|
||||
initProjectStartupActivities.clear()
|
||||
postStartupActivities.clear()
|
||||
}
|
||||
}
|
||||
@@ -474,7 +471,7 @@ open class StartupManagerImpl(private val project: Project) : StartupManagerEx()
|
||||
fun checkCleared() {
|
||||
try {
|
||||
synchronized(lock) {
|
||||
assert(startupActivities.isEmpty()) { "Activities: $startupActivities" }
|
||||
assert(initProjectStartupActivities.isEmpty()) { "Activities: $initProjectStartupActivities" }
|
||||
assert(postStartupActivities.isEmpty()) { "DumbAware Post Activities: $postStartupActivities" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,6 @@ fun initApplication(rawArgs: List<String>, prepareUiFuture: Deferred<Any>) {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private suspend fun prepareStart(app: ApplicationImpl, initAppActivity: Activity, pluginSet: PluginSet, mainScope: CoroutineScope) {
|
||||
coroutineScope {
|
||||
app.preloadServices(
|
||||
@@ -243,10 +242,9 @@ private suspend fun prepareStart(app: ApplicationImpl, initAppActivity: Activity
|
||||
createAppLocatorFile()
|
||||
}
|
||||
|
||||
if (!app.isUnitTestMode && !app.isHeadlessEnvironment &&
|
||||
java.lang.Boolean.parseBoolean(System.getProperty("enable.activity.preloading", "true"))) {
|
||||
if (!app.isUnitTestMode && !app.isHeadlessEnvironment && System.getProperty("enable.activity.preloading", "true").toBoolean()) {
|
||||
// do not execute as a single long task, make sure that other more important tasks may slip in between
|
||||
launchAndMeasure("preloading activity executing", Dispatchers.Default.limitedParallelism(1)) {
|
||||
launchAndMeasure("preloading activity executing") {
|
||||
executePreloadActivities(app)
|
||||
}
|
||||
}
|
||||
|
||||
+12
-15
@@ -197,17 +197,10 @@ public abstract class FileEditorManagerImpl extends FileEditorManagerEx implemen
|
||||
}
|
||||
});
|
||||
connection.subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
|
||||
@Override
|
||||
public void projectOpened(@NotNull Project project) {
|
||||
if (project == myProject) {
|
||||
FileEditorManagerImpl.this.projectOpened(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectClosing(@NotNull Project project) {
|
||||
if (project == myProject) {
|
||||
// Dispose created editors. We do not use use closeEditor method because
|
||||
// Dispose created editors. We do not use closeEditor method because
|
||||
// it fires event and changes history.
|
||||
closeAllFiles();
|
||||
}
|
||||
@@ -545,6 +538,7 @@ public abstract class FileEditorManagerImpl extends FileEditorManagerEx implemen
|
||||
getActiveSplittersAsync().onSuccess(splitters -> splitters.updateFileName(null));
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
@Override
|
||||
public VirtualFile getFile(@NotNull FileEditor editor) {
|
||||
EditorComposite editorComposite = getComposite(editor);
|
||||
@@ -940,7 +934,7 @@ public abstract class FileEditorManagerImpl extends FileEditorManagerEx implemen
|
||||
|
||||
/**
|
||||
* @param file to be opened. Unlike openFile method, file can be
|
||||
* invalid. For example, all file were invalidate and they are being
|
||||
* invalid. For example, all file where invalidate, and they are being
|
||||
* removed one by one. If we have removed one invalid file, then another
|
||||
* invalid file become selected. That's why we do not require that
|
||||
* passed file is valid.
|
||||
@@ -1202,7 +1196,7 @@ public abstract class FileEditorManagerImpl extends FileEditorManagerEx implemen
|
||||
}
|
||||
if (state == null && newEditor) {
|
||||
// We have to try to get state from the history only in case
|
||||
// if editor is not opened. Otherwise history entry might have a state
|
||||
// if editor is not opened. Otherwise, history entry might have a state
|
||||
// out of sync with the current editor state.
|
||||
state = EditorHistoryManager.getInstance(myProject).getState(file, provider);
|
||||
}
|
||||
@@ -1415,7 +1409,7 @@ public abstract class FileEditorManagerImpl extends FileEditorManagerEx implemen
|
||||
return getSelectedTextEditor(false);
|
||||
}
|
||||
|
||||
public Editor getSelectedTextEditor(boolean lockfree) {
|
||||
public Editor getSelectedTextEditor(boolean isLockFree) {
|
||||
if (!ClientId.isCurrentlyUnderLocalId()) {
|
||||
ClientFileEditorManager clientManager = getClientFileEditorManager();
|
||||
if (clientManager == null) {
|
||||
@@ -1425,11 +1419,11 @@ public abstract class FileEditorManagerImpl extends FileEditorManagerEx implemen
|
||||
return selectedEditor instanceof TextEditor ? ((TextEditor)selectedEditor).getEditor() : null;
|
||||
}
|
||||
|
||||
if (!lockfree) {
|
||||
if (!isLockFree) {
|
||||
assertDispatchThread();
|
||||
}
|
||||
|
||||
EditorWindow currentWindow = lockfree ? getMainSplitters().getCurrentWindow() : getSplitters().getCurrentWindow();
|
||||
EditorWindow currentWindow = isLockFree ? getMainSplitters().getCurrentWindow() : getSplitters().getCurrentWindow();
|
||||
if (currentWindow != null) {
|
||||
EditorComposite selectedEditor = currentWindow.getSelectedComposite();
|
||||
if (selectedEditor != null && selectedEditor.getSelectedEditor() instanceof TextEditor) {
|
||||
@@ -1686,7 +1680,8 @@ public abstract class FileEditorManagerImpl extends FileEditorManagerEx implemen
|
||||
myListenerList.remove(listener);
|
||||
}
|
||||
|
||||
protected void projectOpened(@NotNull MessageBusConnection connection) {
|
||||
@ApiStatus.Internal
|
||||
public final void init() {
|
||||
//myFocusWatcher.install(myWindows.getComponent ());
|
||||
getMainSplitters().startListeningFocus();
|
||||
|
||||
@@ -1695,6 +1690,8 @@ public abstract class FileEditorManagerImpl extends FileEditorManagerEx implemen
|
||||
// updates tabs colors
|
||||
fileStatusManager.addFileStatusListener(new MyFileStatusListener(), myProject);
|
||||
}
|
||||
|
||||
MessageBusConnection connection = myProject.getMessageBus().connect(this);
|
||||
connection.subscribe(FileTypeManager.TOPIC, new MyFileTypeListener());
|
||||
connection.subscribe(ProjectTopics.PROJECT_ROOTS, new MyRootsListener());
|
||||
connection.subscribe(AdditionalLibraryRootsListener.TOPIC, new MyRootsListener());
|
||||
@@ -2127,7 +2124,7 @@ public abstract class FileEditorManagerImpl extends FileEditorManagerEx implemen
|
||||
|
||||
/**
|
||||
* Gets notifications from UISetting component to track changes of RECENT_FILES_LIMIT
|
||||
* and EDITOR_TAB_LIMIT, etc values.
|
||||
* and EDITOR_TAB_LIMIT, etc. values.
|
||||
*/
|
||||
private final class MyUISettingsListener implements UISettingsListener {
|
||||
@Override
|
||||
|
||||
@@ -18,12 +18,17 @@ import com.intellij.openapi.project.isNotificationSilentMode
|
||||
import com.intellij.openapi.startup.InitProjectActivity
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
internal class OpenFilesActivity : InitProjectActivity {
|
||||
override suspend fun run(project: Project) {
|
||||
ProgressManager.getInstance().progressIndicator?.text = IdeBundle.message("progress.text.reopening.files")
|
||||
|
||||
val fileEditorManager = FileEditorManager.getInstance(project) as? FileEditorManagerImpl ?: return
|
||||
withContext(Dispatchers.EDT) {
|
||||
fileEditorManager.init()
|
||||
}
|
||||
|
||||
val editorSplitters = fileEditorManager.mainSplitters
|
||||
val panel = editorSplitters.restoreEditors()
|
||||
(project as ProjectEx).coroutineScope.launch(Dispatchers.EDT + ModalityState.NON_MODAL.asContextElement()) {
|
||||
|
||||
@@ -4,6 +4,7 @@ package com.intellij.openapi.project.impl
|
||||
import com.intellij.configurationStore.runInAutoSaveDisabledMode
|
||||
import com.intellij.configurationStore.saveSettings
|
||||
import com.intellij.diagnostic.ActivityCategory
|
||||
import com.intellij.diagnostic.LoadingState
|
||||
import com.intellij.diagnostic.PluginException
|
||||
import com.intellij.diagnostic.StartUpMeasurer
|
||||
import com.intellij.ide.impl.runUnderModalProgressIfIsEdt
|
||||
@@ -358,7 +359,7 @@ open class ProjectImpl(filePath: Path, projectName: String?)
|
||||
override fun getContainerDescriptor(pluginDescriptor: IdeaPluginDescriptorImpl) = pluginDescriptor.projectContainerDescriptor
|
||||
|
||||
override fun setProgressDuringInit(indicator: ProgressIndicator) {
|
||||
indicator.fraction = getPercentageOfComponentsLoaded() / if (ourClassesAreLoaded) 10 else 2
|
||||
indicator.fraction = getPercentageOfComponentsLoaded() / if (LoadingState.PROJECT_OPENED.isOccurred) 10 else 2
|
||||
}
|
||||
|
||||
override fun save() {
|
||||
|
||||
+44
-62
@@ -97,10 +97,11 @@ open class ProjectManagerImpl : ProjectManagerEx(), Disposable {
|
||||
init {
|
||||
val connection = ApplicationManager.getApplication().messageBus.connect()
|
||||
connection.subscribe(TOPIC, object : ProjectManagerListener {
|
||||
@Suppress("removal")
|
||||
override fun projectOpened(project: Project) {
|
||||
for (listener in getAllListeners(project)) {
|
||||
try {
|
||||
@Suppress("DEPRECATION")
|
||||
@Suppress("DEPRECATION", "removal")
|
||||
listener.projectOpened(project)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
@@ -292,6 +293,7 @@ open class ProjectManagerImpl : ProjectManagerEx(), Disposable {
|
||||
}
|
||||
|
||||
app.assertIsWriteThread()
|
||||
@Suppress("TestOnlyProblems")
|
||||
if (isLight(project)) {
|
||||
// if we close project at the end of the test, just mark it closed;
|
||||
// if we are shutting down the entire test framework, proceed to full dispose
|
||||
@@ -562,18 +564,10 @@ open class ProjectManagerImpl : ProjectManagerEx(), Disposable {
|
||||
throw CancellationException("not trusted")
|
||||
}
|
||||
|
||||
val waitEdtActivity = StartUpMeasurer.startActivity("placing calling projectOpened on event queue")
|
||||
val indicator = ProgressManager.getInstance().progressIndicator
|
||||
if (indicator != null) {
|
||||
indicator.text = if (ApplicationManager.getApplication().isInternal) "Waiting on event queue..." // NON-NLS (internal mode)
|
||||
else ProjectBundle.message("project.preparing.workspace")
|
||||
indicator.isIndeterminate = true
|
||||
}
|
||||
|
||||
tracer.spanBuilder("open project")
|
||||
.setAttribute(AttributeKey.stringKey("project"), project.name)
|
||||
.useWithScope {
|
||||
runStartupActivities(project, indicator, isRunStartUpActivitiesEnabled(project), waitEdtActivity)
|
||||
runInitProjectActivities(project)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,6 +607,11 @@ open class ProjectManagerImpl : ProjectManagerEx(), Disposable {
|
||||
disableAutoSaveToken.finish()
|
||||
}
|
||||
|
||||
if (isRunStartUpActivitiesEnabled(project)) {
|
||||
(StartupManager.getInstance(project) as StartupManagerImpl).runStartupActivities()
|
||||
}
|
||||
LifecycleUsageTriggerCollector.onProjectOpened(project)
|
||||
|
||||
options.callback?.projectOpened(project, module ?: ModuleManager.getInstance(project).modules[0])
|
||||
return project
|
||||
}
|
||||
@@ -848,69 +847,51 @@ private fun message(e: Throwable): String {
|
||||
|
||||
@Internal
|
||||
@VisibleForTesting
|
||||
suspend fun runStartupActivities(project: Project,
|
||||
indicator: ProgressIndicator?,
|
||||
runStartUpActivities: Boolean,
|
||||
waitEdtActivity: Activity?) {
|
||||
suspend fun runInitProjectActivities(project: Project) {
|
||||
val traceContext = Context.current()
|
||||
withContext(Dispatchers.EDT) {
|
||||
waitEdtActivity?.end()
|
||||
|
||||
if (indicator != null && ApplicationManager.getApplication().isInternal) {
|
||||
indicator.text = "Running project opened tasks..." // NON-NLS (internal mode)
|
||||
coroutineScope {
|
||||
launch {
|
||||
(StartupManager.getInstance(project) as StartupManagerImpl).initProject(null)
|
||||
}
|
||||
|
||||
LOG.debug("projectOpened")
|
||||
val waitEdtActivity = StartUpMeasurer.startActivity("placing calling projectOpened on event queue")
|
||||
launch(Dispatchers.EDT) {
|
||||
waitEdtActivity.end()
|
||||
|
||||
val activity = StartUpMeasurer.startActivity("project opened callbacks")
|
||||
|
||||
runActivity("projectOpened event executing") {
|
||||
tracer.spanBuilder("execute projectOpened handlers").setParent(traceContext).useWithScope {
|
||||
@Suppress("DEPRECATION")
|
||||
ApplicationManager.getApplication().messageBus.syncPublisher(ProjectManager.TOPIC).projectOpened(project)
|
||||
}
|
||||
}
|
||||
|
||||
coroutineContext.ensureActive()
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
(project as ComponentManagerImpl)
|
||||
.processInitializedComponents(com.intellij.openapi.components.ProjectComponent::class.java) { component, pluginDescriptor ->
|
||||
coroutineContext.ensureActive()
|
||||
try {
|
||||
val componentActivity = StartUpMeasurer.startActivity(component.javaClass.name, ActivityCategory.PROJECT_OPEN_HANDLER,
|
||||
pluginDescriptor.pluginId.idString)
|
||||
component.projectOpened()
|
||||
componentActivity.end()
|
||||
}
|
||||
catch (e: CancellationException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error(e)
|
||||
val activity = StartUpMeasurer.startActivity("project opened callbacks")
|
||||
runActivity("projectOpened event executing") {
|
||||
tracer.spanBuilder("execute projectOpened handlers").setParent(traceContext).useWithScope {
|
||||
@Suppress("DEPRECATION", "removal")
|
||||
ApplicationManager.getApplication().messageBus.syncPublisher(ProjectManager.TOPIC).projectOpened(project)
|
||||
}
|
||||
}
|
||||
|
||||
activity.end()
|
||||
}
|
||||
coroutineContext.ensureActive()
|
||||
|
||||
ProjectImpl.ourClassesAreLoaded = true
|
||||
@Suppress("DEPRECATION")
|
||||
(project as ComponentManagerImpl)
|
||||
.processInitializedComponents(com.intellij.openapi.components.ProjectComponent::class.java) { component, pluginDescriptor ->
|
||||
coroutineContext.ensureActive()
|
||||
try {
|
||||
val componentActivity = StartUpMeasurer.startActivity(component.javaClass.name, ActivityCategory.PROJECT_OPEN_HANDLER,
|
||||
pluginDescriptor.pluginId.idString)
|
||||
component.projectOpened()
|
||||
componentActivity.end()
|
||||
}
|
||||
catch (e: CancellationException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
if (runStartUpActivities) {
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (indicator != null && app.isInternal) {
|
||||
indicator.text = IdeBundle.message("startup.indicator.text.running.startup.activities")
|
||||
}
|
||||
|
||||
tracer.spanBuilder("StartupManager.projectOpened").useWithScope {
|
||||
(StartupManager.getInstance(project) as StartupManagerImpl).projectOpened(indicator)
|
||||
activity.end()
|
||||
}
|
||||
}
|
||||
|
||||
LifecycleUsageTriggerCollector.onProjectOpened(project)
|
||||
}
|
||||
|
||||
private val LOG = logger<ProjectManagerImpl>()
|
||||
@@ -992,6 +973,7 @@ private fun ensureCouldCloseIfUnableToSave(project: Project): Boolean {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("HardCodedStringLiteral")
|
||||
return Messages.showYesNoDialog(project, message.toString(),
|
||||
IdeUICustomization.getInstance().projectMessage("dialog.title.unsaved.project"),
|
||||
Messages.getWarningIcon()) == Messages.YES
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ui.mac;
|
||||
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.RecentProjectListActionProvider;
|
||||
import com.intellij.ide.RecentProjectsManager;
|
||||
import com.intellij.ide.ReopenProjectAction;
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
@@ -15,7 +14,6 @@ import com.intellij.openapi.wm.impl.SystemDock;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Denis Fokin
|
||||
@@ -57,14 +55,9 @@ public final class MacDockDelegate implements SystemDock.Delegate {
|
||||
|
||||
@Override
|
||||
public void updateRecentProjectsMenu () {
|
||||
RecentProjectsManager projectsManager = RecentProjectsManager.getInstance();
|
||||
if (projectsManager == null) {
|
||||
return;
|
||||
}
|
||||
List<AnAction> recentProjectActions = RecentProjectListActionProvider.getInstance().getActions(false);
|
||||
recentProjectsMenu.removeAll();
|
||||
|
||||
for (AnAction action : recentProjectActions) {
|
||||
for (AnAction action : RecentProjectListActionProvider.getInstance().getActions(false)) {
|
||||
MenuItem menuItem = new MenuItem(((ReopenProjectAction)action).getProjectNameToDisplay());
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
<applicationService serviceInterface="com.intellij.openapi.project.impl.ProjectStoreFactory"
|
||||
serviceImplementation="com.intellij.configurationStore.PlatformLangProjectStoreFactory"
|
||||
overrides="true"/>
|
||||
|
||||
<projectService serviceImplementation="com.intellij.workspaceModel.ide.impl.legacyBridge.module.ModuleBridgeLoaderService" preload="true"/>
|
||||
<projectServiceContainerInitializedListener implementation="com.intellij.workspaceModel.ide.impl.legacyBridge.module.ModuleBridgeLoaderService$ModuleBridgeProjectServiceInitializedListener"/>
|
||||
<projectService serviceInterface="com.intellij.openapi.module.AutomaticModuleUnloader"
|
||||
serviceImplementation="com.intellij.openapi.module.impl.AutomaticModuleUnloaderImpl" overrides="true"/>
|
||||
<projectService serviceInterface="com.intellij.openapi.roots.ProjectRootManager"
|
||||
serviceImplementation="com.intellij.workspaceModel.ide.impl.legacyBridge.project.ProjectRootManagerBridge" preload="await"/>
|
||||
|
||||
@@ -106,11 +111,6 @@
|
||||
<applicationService serviceInterface="com.intellij.ui.ExperimentalUI"
|
||||
serviceImplementation="com.intellij.ui.ExperimentalUIImpl"/>
|
||||
|
||||
<projectService serviceImplementation="com.intellij.workspaceModel.ide.impl.legacyBridge.module.ModuleBridgeLoaderService" preload="await"/>
|
||||
<projectServiceContainerInitializedListener implementation="com.intellij.workspaceModel.ide.impl.legacyBridge.module.ModuleBridgeLoaderService$ModuleBridgeProjectServiceInitializedListener"/>
|
||||
<projectService serviceInterface="com.intellij.openapi.module.AutomaticModuleUnloader"
|
||||
serviceImplementation="com.intellij.openapi.module.impl.AutomaticModuleUnloaderImpl" overrides="true"/>
|
||||
|
||||
<actionConfigurationCustomizer implementation="com.intellij.tools.ToolManager$MyActionTuner"/>
|
||||
|
||||
<projectService serviceInterface="com.intellij.pom.PomModel"
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<startupActivity
|
||||
implementation="com.intellij.workspaceModel.ide.impl.legacyBridge.module.ModuleManagerComponentBridge$ModuleManagerInitProjectActivity"
|
||||
order="first"/>
|
||||
|
||||
<applicationService serviceInterface="com.intellij.openapi.command.undo.UndoManager"
|
||||
serviceImplementation="com.intellij.openapi.command.impl.UndoManagerImpl" preload="await"/>
|
||||
|
||||
@@ -125,6 +129,8 @@
|
||||
<applicationService serviceImplementation="com.intellij.ide.IdeTooltipManager" preload="notHeadless"/>
|
||||
|
||||
<applicationService serviceInterface="com.intellij.refactoring.RefactoringUiService" serviceImplementation="com.intellij.refactoring.RefactoringUiServiceImpl"/>
|
||||
|
||||
<postStartupActivity implementation="com.intellij.ide.RecentProjectsManagerBase$MyProjectPostStartupActivity"/>
|
||||
</extensions>
|
||||
|
||||
<!--suppress PluginXmlDynamicPlugin -->
|
||||
|
||||
@@ -1,19 +1,5 @@
|
||||
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.module
|
||||
|
||||
import com.intellij.ide.projectView.impl.ModuleGroup
|
||||
@@ -68,7 +54,7 @@ class ExplicitModuleGroupTest : HeavyPlatformTestCase() {
|
||||
|
||||
private fun createModuleInGroup(name: String, vararg path: String): Module {
|
||||
val module = createModule(name)
|
||||
val model = ModuleManager.getInstance(myProject).modifiableModel
|
||||
val model = ModuleManager.getInstance(myProject).getModifiableModel()
|
||||
model.setModuleGroupPath(module, path)
|
||||
runWriteAction { model.commit() }
|
||||
return module
|
||||
|
||||
+41
-21
@@ -6,6 +6,7 @@ package com.intellij.openapi.project.impl
|
||||
import com.intellij.ide.*
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx
|
||||
import com.intellij.project.stateStore
|
||||
import com.intellij.testFramework.*
|
||||
import com.intellij.testFramework.assertions.Assertions.assertThat
|
||||
@@ -13,12 +14,13 @@ import com.intellij.ui.DeferredIconImpl
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.util.messages.SimpleMessageBusConnection
|
||||
import com.intellij.util.ui.EmptyIcon
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.ClassRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExternalResource
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.util.*
|
||||
|
||||
class RecentProjectsTest {
|
||||
companion object {
|
||||
@@ -44,7 +46,7 @@ class RecentProjectsTest {
|
||||
val tempDir = TemporaryDirectory()
|
||||
|
||||
@Test
|
||||
fun testMostRecentOnTop() {
|
||||
fun testMostRecentOnTop() = runBlocking {
|
||||
val p1 = createAndOpenProject("p1")
|
||||
val p2 = createAndOpenProject("p2")
|
||||
val p3 = createAndOpenProject("p3")
|
||||
@@ -57,7 +59,7 @@ class RecentProjectsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGroupsOrder() {
|
||||
fun testGroupsOrder() = runBlocking {
|
||||
val p1 = createAndOpenProject("p1")
|
||||
val p2 = createAndOpenProject("p2")
|
||||
val p3 = createAndOpenProject("p3")
|
||||
@@ -81,19 +83,24 @@ class RecentProjectsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun timestampForOpenProjectUpdatesWhenGetStateCalled() {
|
||||
fun timestampForOpenProjectUpdatesWhenGetStateCalled(): Unit = runBlocking {
|
||||
val z1 = tempDir.newPath("z1")
|
||||
var project = PlatformTestUtil.loadAndOpenProject(z1, disposableRule.disposable)
|
||||
val projectManager = ProjectManagerEx.getInstanceEx()
|
||||
var project = projectManager.openProjectAsync(z1, createTestOpenProjectOptions(runPostStartUpActivities = false))!!
|
||||
try {
|
||||
val recentProjectManager = RecentProjectsManagerBase.getInstanceEx()
|
||||
recentProjectManager.runProjectPostStartupActivity(project)
|
||||
|
||||
val timestamp = getProjectOpenTimestamp("z1")
|
||||
PlatformTestUtil.forceCloseProjectWithoutSaving(project)
|
||||
project = PlatformTestUtil.loadAndOpenProject(z1, disposableRule.disposable)
|
||||
RecentProjectsManagerBase.getInstanceEx().updateLastProjectPath()
|
||||
projectManager.forceCloseProjectAsync(project)
|
||||
project = projectManager.openProjectAsync(z1, createTestOpenProjectOptions(runPostStartUpActivities = false))!!
|
||||
recentProjectManager.runProjectPostStartupActivity(project)
|
||||
recentProjectManager.updateLastProjectPath()
|
||||
// "Timestamp for opened project has not been updated"
|
||||
assertThat(getProjectOpenTimestamp("z1")).isGreaterThan(timestamp)
|
||||
}
|
||||
finally {
|
||||
PlatformTestUtil.forceCloseProjectWithoutSaving(project)
|
||||
projectManager.forceCloseProjectAsync(project)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +109,7 @@ class RecentProjectsTest {
|
||||
// For Rider
|
||||
val rpm = (RecentProjectsManager.getInstance() as RecentProjectsManagerBase)
|
||||
|
||||
val projectDir = Paths.get("${PlatformTestUtil.getPlatformTestDataPath()}/recentProjects/dotNetSampleRecent/Povysh")
|
||||
val projectDir = Path.of("${PlatformTestUtil.getPlatformTestDataPath()}/recentProjects/dotNetSampleRecent/Povysh")
|
||||
val slnFile = projectDir.resolve("Povysh.sln")
|
||||
|
||||
val icon = (rpm.getProjectIcon(slnFile.toString(), false) as DeferredIconImpl<*>).evaluate()
|
||||
@@ -120,15 +127,24 @@ class RecentProjectsTest {
|
||||
return -1
|
||||
}
|
||||
|
||||
private fun doReopenCloseAndCheck(projectPath: Path, vararg results: String) {
|
||||
val project = PlatformTestUtil.loadAndOpenProject(projectPath, disposableRule.disposable)
|
||||
PlatformTestUtil.forceCloseProjectWithoutSaving(project)
|
||||
private suspend fun doReopenCloseAndCheck(projectPath: Path, vararg results: String) {
|
||||
openProjectAndClose(projectPath)
|
||||
checkRecents(*results)
|
||||
}
|
||||
|
||||
private fun doReopenCloseAndCheckGroups(projectPath: Path, results: List<String>) {
|
||||
val project = PlatformTestUtil.loadAndOpenProject(projectPath, disposableRule.disposable)
|
||||
PlatformTestUtil.forceCloseProjectWithoutSaving(project)
|
||||
private suspend fun openProjectAndClose(projectPath: Path) {
|
||||
val projectManager = ProjectManagerEx.getInstanceEx()
|
||||
val project = projectManager.openProjectAsync(projectPath, createTestOpenProjectOptions(runPostStartUpActivities = false))!!
|
||||
try {
|
||||
RecentProjectsManagerBase.getInstanceEx().runProjectPostStartupActivity(project)
|
||||
}
|
||||
finally {
|
||||
projectManager.forceCloseProjectAsync(project)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun doReopenCloseAndCheckGroups(projectPath: Path, results: List<String>) {
|
||||
openProjectAndClose(projectPath)
|
||||
checkGroups(results)
|
||||
}
|
||||
|
||||
@@ -150,17 +166,21 @@ class RecentProjectsTest {
|
||||
assertThat(recentGroups).isEqualTo(groups)
|
||||
}
|
||||
|
||||
private fun createAndOpenProject(name: String): Path {
|
||||
private suspend fun createAndOpenProject(name: String): Path {
|
||||
val path = tempDir.newPath(name)
|
||||
var project = PlatformTestUtil.loadAndOpenProject(path, disposableRule.disposable)
|
||||
val projectManager = ProjectManagerEx.getInstanceEx()
|
||||
var project = projectManager.openProjectAsync(path, createTestOpenProjectOptions(runPostStartUpActivities = false))!!
|
||||
try {
|
||||
val recentProjectManager = RecentProjectsManagerBase.getInstanceEx()
|
||||
recentProjectManager.runProjectPostStartupActivity(project)
|
||||
project.stateStore.saveComponent(RecentProjectsManager.getInstance() as RecentProjectsManagerBase)
|
||||
PlatformTestUtil.forceCloseProjectWithoutSaving(project)
|
||||
project = PlatformTestUtil.loadAndOpenProject(path, disposableRule.disposable)
|
||||
projectManager.forceCloseProjectAsync(project)
|
||||
project = projectManager.openProjectAsync(path, createTestOpenProjectOptions(runPostStartUpActivities = false))!!
|
||||
recentProjectManager.runProjectPostStartupActivity(project)
|
||||
return path
|
||||
}
|
||||
finally {
|
||||
PlatformTestUtil.forceCloseProjectWithoutSaving(project)
|
||||
projectManager.forceCloseProjectAsync(project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -3,6 +3,7 @@
|
||||
|
||||
package com.intellij.openapi.project.impl.navigation
|
||||
|
||||
import com.intellij.ide.RecentProjectsManagerBase
|
||||
import com.intellij.navigation.areOriginsEqual
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.JBProtocolCommand
|
||||
@@ -61,18 +62,17 @@ class JBNavigateCommandTest : NavigationTestBase() {
|
||||
@Test
|
||||
fun pathOpenProject(): Unit = runBlocking {
|
||||
val projectManager = ProjectManagerEx.getInstanceEx()
|
||||
val prevProjects = projectManager.openProjects.toHashSet()
|
||||
|
||||
createOrLoadProject(tempDir, useDefaultProjectSettings = false) { project ->
|
||||
setUpProject(project)
|
||||
RecentProjectsManagerBase.getInstanceEx().runProjectPostStartupActivity(project)
|
||||
}
|
||||
|
||||
val prevProjects = projectManager.openProjects.toHashSet()
|
||||
try {
|
||||
ProjectManagerEx.getInstanceEx().forceCloseProjectAsync(project)
|
||||
val result = withContext(Dispatchers.EDT) {
|
||||
navigate(mapOf("path" to "A.java"))
|
||||
}
|
||||
assertThat(result).isNull()
|
||||
yield()
|
||||
withContext(Dispatchers.EDT) {
|
||||
yield()
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.roots.impl.indexing
|
||||
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
@@ -21,7 +21,6 @@ import com.intellij.util.indexing.FileBasedIndexEx
|
||||
import com.intellij.util.indexing.FileBasedIndexImpl
|
||||
import com.intellij.util.indexing.IndexableSetContributor
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
@@ -347,9 +346,9 @@ class IndexableFilesRegularTest : IndexableFilesBaseTest() {
|
||||
}
|
||||
}
|
||||
assertIndexableFiles(contentFileToUnload.file, contentFileToRetain.file)
|
||||
ModuleManager.getInstance(project).setUnloadedModules(Arrays.asList("moduleToUnload"))
|
||||
ModuleManager.getInstance(project).setUnloadedModulesSync(listOf("moduleToUnload"))
|
||||
assertIndexableFiles(contentFileToRetain.file)
|
||||
ModuleManager.getInstance(project).setUnloadedModules(Collections.emptyList())
|
||||
ModuleManager.getInstance(project).setUnloadedModulesSync(emptyList())
|
||||
assertIndexableFiles(contentFileToUnload.file, contentFileToRetain.file)
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.roots.impl.indexing
|
||||
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
@@ -287,7 +287,7 @@ private fun createJavaModule(project: Project, moduleName: String, moduleRootDir
|
||||
val type = ModuleTypeManager.getInstance().findByID(ModuleTypeId.JAVA_MODULE)
|
||||
return WriteCommandAction.writeCommandAction(project).compute(
|
||||
ThrowableComputable<Module, RuntimeException> {
|
||||
val moduleModel = ModuleManager.getInstance(project).modifiableModel
|
||||
val moduleModel = ModuleManager.getInstance(project).getModifiableModel()
|
||||
val module = moduleModel.newModule(moduleRootDirectory.resolve("$moduleName.iml"), type.id)
|
||||
moduleModel.commit()
|
||||
module
|
||||
|
||||
@@ -11,16 +11,14 @@ import com.intellij.openapi.project.Project;
|
||||
* {@link #initComponent()}, {@link #moduleAdded()} methods will be called for each module even if user doesn't use
|
||||
* any feature of your plugin. Also, plugins declaring module components do not support dynamic loading.
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
public interface ModuleComponent extends BaseComponent {
|
||||
/**
|
||||
* Invoked when the project corresponding to this component instance is opened.<p>
|
||||
* Note that components may be created for even unopened projects and this method can be never
|
||||
* invoked for a particular component instance (for example for default project).
|
||||
*
|
||||
* @deprecated Please use {@link com.intellij.openapi.project.ProjectManager#TOPIC} ({@link com.intellij.openapi.project.ProjectManagerListener#projectOpened(Project)} (Project, Module)})
|
||||
* @deprecated Do not use.
|
||||
* <a href=" https://plugins.jetbrains.com/docs/intellij/plugin-components.html#comintellijpoststartupactivity">Post start-up activity</a>
|
||||
* maybe an alternative.
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
default void projectOpened() {
|
||||
}
|
||||
|
||||
@@ -31,7 +29,7 @@ public interface ModuleComponent extends BaseComponent {
|
||||
*
|
||||
* @deprecated Please use {@link com.intellij.openapi.project.ProjectManager#TOPIC} ({@link com.intellij.openapi.project.ProjectManagerListener#projectClosed(Project)} (Project, Module)})
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
default void projectClosed() {
|
||||
}
|
||||
|
||||
@@ -41,7 +39,7 @@ public interface ModuleComponent extends BaseComponent {
|
||||
*
|
||||
* @deprecated Consider to use {@link com.intellij.ProjectTopics#MODULES} ({@link com.intellij.openapi.project.ModuleListener#moduleAdded(Project, Module)})
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
default void moduleAdded() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,33 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.module;
|
||||
package com.intellij.openapi.module
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.SimpleModificationTracker;
|
||||
import com.intellij.util.graph.Graph;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.SimpleModificationTracker
|
||||
import com.intellij.util.graph.Graph
|
||||
import org.jdom.JDOMException
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.nio.file.Path
|
||||
|
||||
/**
|
||||
* Provides services for working with the modules of a project.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public abstract class ModuleManager extends SimpleModificationTracker {
|
||||
/**
|
||||
* Returns the module manager instance for the current project.
|
||||
*
|
||||
* @param project the project for which the module manager is requested.
|
||||
* @return the module manager instance.
|
||||
*/
|
||||
public static ModuleManager getInstance(@NotNull Project project) {
|
||||
return project.getComponent(ModuleManager.class);
|
||||
abstract class ModuleManager : SimpleModificationTracker() {
|
||||
companion object {
|
||||
/**
|
||||
* Returns the module manager instance for the current project.
|
||||
*
|
||||
* @param project the project for which the module manager is requested.
|
||||
* @return the module manager instance.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getInstance(project: Project): ModuleManager = project.getComponent(ModuleManager::class.java)
|
||||
|
||||
fun getInstanceIfDefined(project: Project): ModuleManager? = project.getComponent(ModuleManager::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,32 +38,29 @@ public abstract class ModuleManager extends SimpleModificationTracker {
|
||||
* @param moduleTypeId the ID of the module type to create.
|
||||
* @return the module instance.
|
||||
*/
|
||||
public abstract @NotNull Module newModule(@NotNull @NonNls String filePath, @NotNull String moduleTypeId);
|
||||
abstract fun newModule(filePath: @NonNls String, moduleTypeId: String): Module
|
||||
|
||||
public @NotNull Module newModule(@NotNull Path file, @NotNull String moduleTypeId) {
|
||||
return newModule(file.toString().replace(File.separatorChar, '/'), moduleTypeId);
|
||||
fun newModule(file: Path, moduleTypeId: String): Module {
|
||||
return newModule(file.toString().replace(File.separatorChar, '/'), moduleTypeId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a non-persistent module of the specified type and adds it to the project
|
||||
* to which the module manager is related. {@link #commit()} must be called to
|
||||
* to which the module manager is related. [.commit] must be called to
|
||||
* bring the changes in effect.
|
||||
*
|
||||
* In contrast with modules created by {@link #newModule(String, String)},
|
||||
* In contrast with modules created by [.newModule],
|
||||
* non-persistent modules aren't stored on a filesystem and aren't being written
|
||||
* in a project XML file. When IDE closes, all non-persistent modules vanishes out.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
@NotNull
|
||||
public Module newNonPersistentModule(@NotNull String moduleName, @NotNull String id) {
|
||||
throw new UnsupportedOperationException();
|
||||
open fun newNonPersistentModule(moduleName: String, id: String): Module {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #loadModule(Path)}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract @NotNull Module loadModule(@NotNull String filePath) throws IOException, JDOMException, ModuleWithNameAlreadyExists;
|
||||
@Deprecated("Use {@link #loadModule(Path)}")
|
||||
@Throws(IOException::class, JDOMException::class, ModuleWithNameAlreadyExists::class)
|
||||
abstract fun loadModule(filePath: String): Module
|
||||
|
||||
/**
|
||||
* Loads a module from an .iml file with the specified path and adds it to the project.
|
||||
@@ -76,21 +70,22 @@ public abstract class ModuleManager extends SimpleModificationTracker {
|
||||
* @throws IOException if an I/O error occurred when loading the module file.
|
||||
* @throws ModuleWithNameAlreadyExists if a module with such a name already exists in the project.
|
||||
*/
|
||||
public abstract @NotNull Module loadModule(@NotNull Path file) throws IOException, ModuleWithNameAlreadyExists;
|
||||
@Throws(IOException::class, ModuleWithNameAlreadyExists::class)
|
||||
abstract fun loadModule(file: Path): Module
|
||||
|
||||
/**
|
||||
* Disposes of the specified module and removes it from the project.
|
||||
*
|
||||
* @param module the module to remove.
|
||||
*/
|
||||
public abstract void disposeModule(@NotNull Module module);
|
||||
abstract fun disposeModule(module: Module)
|
||||
|
||||
/**
|
||||
* Returns the list of all modules in the project.
|
||||
*
|
||||
* @return the array of modules.
|
||||
*/
|
||||
public abstract Module @NotNull [] getModules();
|
||||
abstract val modules: Array<Module>
|
||||
|
||||
/**
|
||||
* Returns the project module with the specified name.
|
||||
@@ -98,8 +93,7 @@ public abstract class ModuleManager extends SimpleModificationTracker {
|
||||
* @param name the name of the module to find.
|
||||
* @return the module instance, or null if no module with such name exists.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract Module findModuleByName(@NonNls @NotNull String name);
|
||||
abstract fun findModuleByName(name: @NonNls String): Module?
|
||||
|
||||
/**
|
||||
* Returns the list of modules sorted by dependency (the modules which do not depend
|
||||
@@ -108,7 +102,7 @@ public abstract class ModuleManager extends SimpleModificationTracker {
|
||||
*
|
||||
* @return the sorted array of modules.
|
||||
*/
|
||||
public abstract Module @NotNull [] getSortedModules();
|
||||
abstract val sortedModules: Array<Module>
|
||||
|
||||
/**
|
||||
* Returns the module comparator which can be used for sorting modules by dependency
|
||||
@@ -117,35 +111,32 @@ public abstract class ModuleManager extends SimpleModificationTracker {
|
||||
*
|
||||
* @return the module comparator instance.
|
||||
*/
|
||||
@NotNull
|
||||
public abstract Comparator<Module> moduleDependencyComparator();
|
||||
abstract fun moduleDependencyComparator(): Comparator<Module>
|
||||
|
||||
/**
|
||||
* Returns the list of modules which directly depend on the specified module.
|
||||
*
|
||||
* @param module the module for which the list of dependent modules is requested.
|
||||
* @return list of <i>modules that depend on</i> given module.
|
||||
* @see ModuleUtilCore#getAllDependentModules(Module)
|
||||
* @return list of *modules that depend on* given module.
|
||||
* @see ModuleUtilCore.getAllDependentModules
|
||||
*/
|
||||
@NotNull
|
||||
public abstract List<Module> getModuleDependentModules(@NotNull Module module);
|
||||
abstract fun getModuleDependentModules(module: Module): List<Module>
|
||||
|
||||
/**
|
||||
* Checks if one of the specified modules directly depends on the other module.
|
||||
*
|
||||
* @param module the module to check the dependency for.
|
||||
* @param onModule the module on which {@code module} may depend.
|
||||
* @return true if {@code module} directly depends on {@code onModule}, false otherwise.
|
||||
* @param onModule the module on which `module` may depend.
|
||||
* @return true if `module` directly depends on `onModule`, false otherwise.
|
||||
*/
|
||||
public abstract boolean isModuleDependent(@NotNull Module module, @NotNull Module onModule);
|
||||
abstract fun isModuleDependent(module: Module, onModule: Module): Boolean
|
||||
|
||||
/**
|
||||
* Returns the graph of dependencies between modules in the project.
|
||||
*
|
||||
* @return the module dependency graph.
|
||||
*/
|
||||
@NotNull
|
||||
public abstract Graph<Module> moduleGraph();
|
||||
abstract fun moduleGraph(): Graph<Module>
|
||||
|
||||
/**
|
||||
* Returns the graph of dependencies between modules in the project.
|
||||
@@ -153,8 +144,7 @@ public abstract class ModuleManager extends SimpleModificationTracker {
|
||||
* @param includeTests whether test-only dependencies should be included
|
||||
* @return the module dependency graph.
|
||||
*/
|
||||
@NotNull
|
||||
public abstract Graph<Module> moduleGraph(boolean includeTests);
|
||||
abstract fun moduleGraph(includeTests: Boolean): Graph<Module>
|
||||
|
||||
/**
|
||||
* Returns the model for the list of modules in the project, which can be used to add,
|
||||
@@ -162,49 +152,48 @@ public abstract class ModuleManager extends SimpleModificationTracker {
|
||||
*
|
||||
* @return the modifiable model instance.
|
||||
*/
|
||||
@NotNull
|
||||
public abstract ModifiableModuleModel getModifiableModel();
|
||||
|
||||
abstract fun getModifiableModel(): ModifiableModuleModel
|
||||
|
||||
/**
|
||||
* Returns the path to the group to which the specified module belongs, as an array of group names starting from the project root.
|
||||
* <p>
|
||||
* <strong>Use {@link ModuleGrouper#getGroupPath(Module)} instead.</strong> Explicit module groups will be replaced
|
||||
* by automatic module grouping accordingly to qualified names of modules, see <a href="https://youtrack.jetbrains.com/issue/IDEA-166061">IDEA-166061</a> for details.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* **Use [ModuleGrouper.getGroupPath] instead.** Explicit module groups will be replaced
|
||||
* by automatic module grouping accordingly to qualified names of modules, see [IDEA-166061](https://youtrack.jetbrains.com/issue/IDEA-166061) for details.
|
||||
*
|
||||
* @param module the module for which the path is requested.
|
||||
* @return the path to the group for the module, or null if the module does not belong to any group.
|
||||
*/
|
||||
public abstract @NlsSafe String @Nullable [] getModuleGroupPath(@NotNull Module module);
|
||||
abstract fun getModuleGroupPath(module: Module): Array<String>?
|
||||
|
||||
public abstract boolean hasModuleGroups();
|
||||
abstract fun hasModuleGroups(): Boolean
|
||||
|
||||
/**
|
||||
* @return description of all modules in the project including unloaded
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
@NotNull
|
||||
public abstract Collection<ModuleDescription> getAllModuleDescriptions();
|
||||
@get:ApiStatus.Experimental
|
||||
abstract val allModuleDescriptions: Collection<ModuleDescription>
|
||||
|
||||
@get:ApiStatus.Experimental
|
||||
abstract val unloadedModuleDescriptions: Collection<UnloadedModuleDescription>
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@NotNull
|
||||
public abstract Collection<UnloadedModuleDescription> getUnloadedModuleDescriptions();
|
||||
abstract fun getUnloadedModuleDescription(moduleName: String): UnloadedModuleDescription?
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@Nullable
|
||||
public abstract UnloadedModuleDescription getUnloadedModuleDescription(@NotNull String moduleName);
|
||||
|
||||
@NotNull
|
||||
public abstract ModuleGrouper getModuleGrouper(@Nullable ModifiableModuleModel model);
|
||||
abstract fun getModuleGrouper(model: ModifiableModuleModel?): ModuleGrouper
|
||||
|
||||
/**
|
||||
* Specify list of modules which will be unloaded from the project.
|
||||
* @see UnloadedModuleDescription
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public abstract void setUnloadedModules(@NotNull List<String> unloadedModuleNames);
|
||||
abstract suspend fun setUnloadedModules(unloadedModuleNames: List<String>)
|
||||
|
||||
@Deprecated("Use setUnloadedModules")
|
||||
@TestOnly
|
||||
abstract fun setUnloadedModulesSync(unloadedModuleNames: List<String>)
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public void removeUnloadedModules(@NotNull Collection<? extends UnloadedModuleDescription> unloadedModules) {
|
||||
open fun removeUnloadedModules(unloadedModules: Collection<UnloadedModuleDescription>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.project;
|
||||
|
||||
import com.intellij.ProjectTopics;
|
||||
@@ -21,6 +21,12 @@ public interface ModuleListener extends EventListener {
|
||||
default void moduleAdded(@NotNull Project project, @NotNull Module module) {
|
||||
}
|
||||
|
||||
default void modulesAdded(@NotNull Project project, @NotNull List<Module> modules) {
|
||||
for (Module module : modules) {
|
||||
moduleAdded(project, module);
|
||||
}
|
||||
}
|
||||
|
||||
default void beforeModuleRemoved(@NotNull Project project, @NotNull Module module) {
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ public interface ProjectManagerListener extends EventListener {
|
||||
* <a href=" https://plugins.jetbrains.com/docs/intellij/plugin-components.html#comintellijpoststartupactivity">Post start-up activity</a>
|
||||
* maybe an alternative.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
default void projectOpened(@NotNull Project project) {
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ public abstract class ProjectRootManagerEx extends ProjectRootManager {
|
||||
|
||||
public abstract void makeRootsChange(@NotNull Runnable runnable, @NotNull RootsChangeRescanningInfo changes);
|
||||
|
||||
public abstract @NotNull AutoCloseable withRootsChange(@NotNull RootsChangeRescanningInfo changes);
|
||||
|
||||
public abstract void markRootsForRefresh();
|
||||
|
||||
public abstract void mergeRootsChangesDuring(@NotNull Runnable runnable);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.module
|
||||
|
||||
import com.intellij.openapi.module.impl.createGrouper
|
||||
@@ -18,11 +18,13 @@ class EmptyModuleManager(private val project: Project) : ModuleManager() {
|
||||
override fun disposeModule(module: Module) {
|
||||
}
|
||||
|
||||
override fun getModules(): Array<Module> = emptyArray<Module>()
|
||||
override val modules: Array<Module>
|
||||
get() = emptyArray()
|
||||
|
||||
override fun findModuleByName(name: String): Nothing? = null
|
||||
|
||||
override fun getSortedModules(): Array<Module> = emptyArray<Module>()
|
||||
override val sortedModules: Array<Module>
|
||||
get() = emptyArray()
|
||||
|
||||
override fun moduleDependencyComparator(): Nothing = throw UnsupportedOperationException()
|
||||
|
||||
@@ -36,21 +38,27 @@ class EmptyModuleManager(private val project: Project) : ModuleManager() {
|
||||
|
||||
override fun getModifiableModel(): Nothing = throw UnsupportedOperationException()
|
||||
|
||||
override fun getModuleGroupPath(module: Module): Array<String> = emptyArray<String>()
|
||||
override fun getModuleGroupPath(module: Module): Array<String> = emptyArray()
|
||||
|
||||
override fun setUnloadedModules(unloadedModuleNames: MutableList<String>) {
|
||||
override suspend fun setUnloadedModules(unloadedModuleNames: List<String>) {
|
||||
}
|
||||
|
||||
override fun setUnloadedModulesSync(unloadedModuleNames: List<String>) {
|
||||
}
|
||||
|
||||
override fun getModuleGrouper(model: ModifiableModuleModel?): ModuleGrouper {
|
||||
return createGrouper(project, model)
|
||||
}
|
||||
|
||||
override fun getAllModuleDescriptions(): List<ModuleDescription> = emptyList<ModuleDescription>()
|
||||
override val allModuleDescriptions: List<ModuleDescription>
|
||||
get() = emptyList()
|
||||
|
||||
override fun getUnloadedModuleDescriptions(): List<UnloadedModuleDescription> = emptyList<UnloadedModuleDescription>()
|
||||
|
||||
override val unloadedModuleDescriptions: List<UnloadedModuleDescription>
|
||||
get() = emptyList()
|
||||
|
||||
override fun getUnloadedModuleDescription(moduleName: String): Nothing? = null
|
||||
|
||||
override fun removeUnloadedModules(unloadedModules: MutableCollection<out UnloadedModuleDescription>) {
|
||||
override fun removeUnloadedModules(unloadedModules: Collection<UnloadedModuleDescription>) {
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -33,14 +33,12 @@ class ModulePointerManagerImpl(private val project: Project) : ModulePointerMana
|
||||
unregisterPointer(module)
|
||||
}
|
||||
|
||||
override fun moduleAdded(project: Project, module: Module) {
|
||||
moduleAppears(module)
|
||||
override fun modulesAdded(project: Project, modules: List<Module>) {
|
||||
modulesAppears(modules)
|
||||
}
|
||||
|
||||
override fun modulesRenamed(project: Project, modules: List<Module>, oldNameProvider: Function<in Module, String>) {
|
||||
for (module in modules) {
|
||||
moduleAppears(module)
|
||||
}
|
||||
modulesAppears(modules)
|
||||
val renamedOldToNew = modules.associateBy({ oldNameProvider.`fun`(it) }, { it.name })
|
||||
for (entry in oldToNewName.entries) {
|
||||
val newValue = renamedOldToNew.get(entry.value)
|
||||
@@ -95,11 +93,13 @@ class ModulePointerManagerImpl(private val project: Project) : ModulePointerMana
|
||||
}
|
||||
}
|
||||
|
||||
private fun moduleAppears(module: Module) {
|
||||
private fun modulesAppears(modules: List<Module>) {
|
||||
lock.write {
|
||||
unresolved.remove(module.name)?.forEach {
|
||||
it.moduleAdded(module)
|
||||
registerPointer(module, it)
|
||||
for (module in modules) {
|
||||
unresolved.remove(module.name)?.forEach {
|
||||
it.moduleAdded(module)
|
||||
registerPointer(module, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,8 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.module.impl
|
||||
|
||||
import com.intellij.ide.highlighter.ModuleFileType
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.util.io.URLUtil
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectLoader
|
||||
import com.intellij.util.PathUtilRt
|
||||
|
||||
/**
|
||||
* Path here must be system-independent.
|
||||
@@ -33,41 +15,5 @@ data class ModulePath(val path: String, val group: String?) {
|
||||
}
|
||||
|
||||
fun getModuleNameByFilePath(path: String): String {
|
||||
return PathUtil.getFileName(path).removeSuffix(ModuleFileType.DOT_DEFAULT_EXTENSION)
|
||||
}
|
||||
|
||||
internal abstract class SaveItem {
|
||||
protected abstract val moduleName: String
|
||||
protected abstract val moduleFilePath: String
|
||||
|
||||
protected abstract val groupPathString: String?
|
||||
|
||||
fun writeExternal(parentElement: Element) {
|
||||
val moduleFilePath = moduleFilePath
|
||||
// moduleFilePath is empty for non-persistent modules. Such modules should disappear when IDE exits,
|
||||
// hence they should not be mentioned in `modules.xml`.
|
||||
if (moduleFilePath.isNotEmpty()) {
|
||||
val moduleElement = Element(JpsProjectLoader.MODULE_TAG)
|
||||
val url = VirtualFileManager.constructUrl(URLUtil.FILE_PROTOCOL, moduleFilePath)
|
||||
moduleElement.setAttribute(JpsProjectLoader.FILE_URL_ATTRIBUTE, url)
|
||||
// support for older builds
|
||||
moduleElement.setAttribute(JpsProjectLoader.FILE_PATH_ATTRIBUTE, moduleFilePath)
|
||||
|
||||
groupPathString?.let {
|
||||
moduleElement.setAttribute(JpsProjectLoader.GROUP_ATTRIBUTE, it)
|
||||
}
|
||||
parentElement.addContent(moduleElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ModulePathSaveItem(private val modulePath: ModulePath) : SaveItem() {
|
||||
override val groupPathString: String?
|
||||
get() = modulePath.group
|
||||
|
||||
override val moduleFilePath: String
|
||||
get() = modulePath.path
|
||||
|
||||
override val moduleName: String
|
||||
get() = modulePath.moduleName
|
||||
return PathUtilRt.getFileName(path).removeSuffix(ModuleFileType.DOT_DEFAULT_EXTENSION)
|
||||
}
|
||||
+6
-1
@@ -49,7 +49,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Pers
|
||||
|
||||
private final OrderRootsCache myRootsCache;
|
||||
|
||||
protected boolean myStartupActivityPerformed;
|
||||
private boolean myStateLoaded;
|
||||
|
||||
@ApiStatus.Internal
|
||||
@@ -450,6 +449,12 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Pers
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull AutoCloseable withRootsChange(@NotNull RootsChangeRescanningInfo changes) {
|
||||
myRootsChanged.beforeRootsChanged();
|
||||
return () -> myRootsChanged.rootsChanged(changes);
|
||||
}
|
||||
|
||||
protected boolean isFiringEvent;
|
||||
|
||||
private void fireBeforeRootsChanged(boolean fileTypes) {
|
||||
|
||||
+86
-57
@@ -5,8 +5,9 @@ import com.intellij.ProjectTopics
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.WriteAction
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.application.asContextElement
|
||||
import com.intellij.openapi.components.impl.stores.IComponentStore
|
||||
import com.intellij.openapi.components.impl.stores.ModuleStore
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
@@ -14,6 +15,8 @@ import com.intellij.openapi.diagnostic.getOrLogException
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.module.*
|
||||
import com.intellij.openapi.module.impl.*
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.impl.CoreProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.RootsChangeRescanningInfo
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
@@ -25,7 +28,6 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager
|
||||
import com.intellij.serviceContainer.PrecomputedExtensionModel
|
||||
import com.intellij.serviceContainer.precomputeExtensionModel
|
||||
import com.intellij.util.graph.*
|
||||
import com.intellij.util.io.systemIndependentPath
|
||||
import com.intellij.workspaceModel.ide.*
|
||||
import com.intellij.workspaceModel.ide.impl.legacyBridge.module.roots.ModuleLibraryTableBridgeImpl
|
||||
import com.intellij.workspaceModel.ide.impl.legacyBridge.module.roots.ModuleRootComponentBridge
|
||||
@@ -33,22 +35,20 @@ import com.intellij.workspaceModel.ide.legacyBridge.ModuleBridge
|
||||
import com.intellij.workspaceModel.storage.*
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.*
|
||||
import com.intellij.workspaceModel.storage.url.VirtualFileUrl
|
||||
import kotlinx.coroutines.*
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectLoader
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.ForkJoinTask
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
@ApiStatus.Internal
|
||||
abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleManagerEx(), Disposable {
|
||||
protected val unloadedModules: MutableMap<String, UnloadedModuleDescription> = LinkedHashMap()
|
||||
|
||||
override fun dispose() {
|
||||
modules().forEach {
|
||||
Disposer.dispose(it)
|
||||
}
|
||||
modules().forEach(Disposer::dispose)
|
||||
}
|
||||
|
||||
protected fun modules(): Sequence<ModuleBridge> {
|
||||
@@ -80,7 +80,7 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
|
||||
val entityStore = WorkspaceModel.getInstance(project).entityStorage
|
||||
|
||||
fun loadModules(entities: Sequence<ModuleEntity>) {
|
||||
suspend fun loadModules(entities: Sequence<ModuleEntity>) {
|
||||
val unloadedModuleNames = UnloadedModulesListStorage.getInstance(project).unloadedModuleNames
|
||||
val (unloadedEntities, loadedEntities) = entities.partition { it.name in unloadedModuleNames }
|
||||
LOG.debug { "Loading modules for ${loadedEntities.size} entities" }
|
||||
@@ -88,26 +88,27 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
val precomputedExtensionModel = precomputeExtensionModel()
|
||||
|
||||
val tasks = loadedEntities.map { moduleEntity ->
|
||||
ForkJoinTask.adapt(Callable {
|
||||
project.coroutineScope.async {
|
||||
runCatching {
|
||||
val module = createModuleInstance(moduleEntity, entityStore, null, false, precomputedExtensionModel)
|
||||
moduleEntity to module
|
||||
}.getOrLogException(LOG)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
ForkJoinTask.invokeAll(tasks)
|
||||
val result = tasks.awaitAll()
|
||||
|
||||
UnloadedModuleDescriptionBridge.createDescriptions(unloadedEntities).associateByTo(unloadedModules) { it.name }
|
||||
|
||||
val modules = HashSet<ModuleBridge>()
|
||||
val modules = LinkedHashSet<ModuleBridge>(result.size)
|
||||
WorkspaceModel.getInstance(project).updateProjectModelSilent { builder ->
|
||||
val moduleMap = builder.mutableModuleMap
|
||||
for (task in tasks) {
|
||||
val (entity, module) = task.rawResult ?: continue
|
||||
modules += module
|
||||
for (item in result) {
|
||||
val (entity, module) = item ?: continue
|
||||
modules.add(module)
|
||||
moduleMap.addMapping(entity, module)
|
||||
(ModuleRootComponentBridge.getInstance(
|
||||
module).getModuleLibraryTable() as ModuleLibraryTableBridgeImpl).registerModuleLibraryInstances(builder)
|
||||
(ModuleRootComponentBridge.getInstance(module).getModuleLibraryTable() as ModuleLibraryTableBridgeImpl)
|
||||
.registerModuleLibraryInstances(builder)
|
||||
}
|
||||
}
|
||||
// Facets that are loaded from the cache do not generate "EntityAdded" event and aren't initialized
|
||||
@@ -115,7 +116,7 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
//
|
||||
// Possible issue - if we'll initialize facets here and after that we'll get "EntityAdded" event, the facet will be initialized twice
|
||||
// But 1. That seems impossible as we don't create facets before the modules are loaded 2. I hope that facets initialization is idempotent
|
||||
modules.forEach { module -> module.initFacets() }
|
||||
modules.forEach(ModuleBridge::initFacets)
|
||||
}
|
||||
|
||||
override fun unloadNewlyAddedModulesIfPossible(storage: EntityStorage) {
|
||||
@@ -133,7 +134,7 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
|
||||
override fun newModule(filePath: String, moduleTypeId: String): Module {
|
||||
incModificationCount()
|
||||
val modifiableModel = modifiableModel
|
||||
val modifiableModel = getModifiableModel()
|
||||
val module = modifiableModel.newModule(filePath, moduleTypeId)
|
||||
modifiableModel.commit()
|
||||
return module
|
||||
@@ -141,7 +142,7 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
|
||||
override fun newNonPersistentModule(moduleName: String, id: String): Module {
|
||||
incModificationCount()
|
||||
val modifiableModel = modifiableModel
|
||||
val modifiableModel = getModifiableModel()
|
||||
val module = modifiableModel.newNonPersistentModule(moduleName, id)
|
||||
modifiableModel.commit()
|
||||
return module
|
||||
@@ -149,7 +150,8 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
|
||||
override fun getModuleDependentModules(module: Module): List<Module> = modules.filter { isModuleDependent(it, module) }
|
||||
|
||||
override fun getUnloadedModuleDescriptions(): Collection<UnloadedModuleDescription> = unloadedModules.values
|
||||
override val unloadedModuleDescriptions: Collection<UnloadedModuleDescription>
|
||||
get() = unloadedModules.values
|
||||
|
||||
override fun getFailedModulePaths(): Collection<ModulePath> = emptyList()
|
||||
|
||||
@@ -157,20 +159,22 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
|
||||
override fun isModuleDependent(module: Module, onModule: Module): Boolean = ModuleRootManager.getInstance(module).isDependsOn(onModule)
|
||||
|
||||
override fun getAllModuleDescriptions(): Collection<ModuleDescription> {
|
||||
return (modules().map { LoadedModuleDescriptionImpl(it) } + unloadedModuleDescriptions).toList()
|
||||
}
|
||||
override val allModuleDescriptions: Collection<ModuleDescription>
|
||||
get() = (modules().map { LoadedModuleDescriptionImpl(it) } + unloadedModuleDescriptions).toList()
|
||||
|
||||
override fun getModuleGroupPath(module: Module): Array<String>? = getModuleGroupPath(module, entityStore)
|
||||
|
||||
override fun getModuleGrouper(model: ModifiableModuleModel?): ModuleGrouper = createGrouper(project, model)
|
||||
|
||||
override fun loadModule(file: Path): Module {
|
||||
return loadModule(file.systemIndependentPath)
|
||||
val model = getModifiableModel()
|
||||
val module = model.loadModule(file)
|
||||
model.commit()
|
||||
return module
|
||||
}
|
||||
|
||||
override fun loadModule(filePath: String): Module {
|
||||
val model = modifiableModel
|
||||
val model = getModifiableModel()
|
||||
val module = model.loadModule(filePath)
|
||||
model.commit()
|
||||
return module
|
||||
@@ -182,7 +186,8 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
modules(storage).toList().toTypedArray()
|
||||
}
|
||||
|
||||
override fun getModules(): Array<Module> = entityStore.cachedValue(modulesArrayValue)
|
||||
override val modules: Array<Module>
|
||||
get() = entityStore.cachedValue(modulesArrayValue)
|
||||
|
||||
private val sortedModulesValue = CachedValue { storage ->
|
||||
val allModules = modules(storage).toList().toTypedArray<Module>()
|
||||
@@ -190,7 +195,8 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
allModules
|
||||
}
|
||||
|
||||
override fun getSortedModules(): Array<Module> = entityStore.cachedValue(sortedModulesValue)
|
||||
override val sortedModules: Array<Module>
|
||||
get() = entityStore.cachedValue(sortedModulesValue)
|
||||
|
||||
override fun findModuleByName(name: String): Module? {
|
||||
val entity = entityStore.current.resolve(ModuleId(name)) ?: return null
|
||||
@@ -198,13 +204,14 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
}
|
||||
|
||||
override fun disposeModule(module: Module) = ApplicationManager.getApplication().runWriteAction {
|
||||
val modifiableModel = modifiableModel
|
||||
val modifiableModel = getModifiableModel()
|
||||
modifiableModel.disposeModule(module)
|
||||
modifiableModel.commit()
|
||||
}
|
||||
|
||||
override fun setUnloadedModules(unloadedModuleNames: List<String>) {
|
||||
if (unloadedModules.keys == unloadedModuleNames) { // optimization
|
||||
override suspend fun setUnloadedModules(unloadedModuleNames: List<String>) {
|
||||
// optimization
|
||||
if (unloadedModules.keys == unloadedModuleNames) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -238,38 +245,60 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
project.save()
|
||||
}
|
||||
|
||||
runWriteAction {
|
||||
ProjectRootManagerEx.getInstanceEx(project).makeRootsChange({
|
||||
for ((moduleEntity, module) in modulesToUnload) {
|
||||
fireBeforeModuleRemoved(module)
|
||||
withContext(Dispatchers.EDT) {
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
ProjectRootManagerEx.getInstanceEx(project).withRootsChange(RootsChangeRescanningInfo.NO_RESCAN_NEEDED).use {
|
||||
for ((moduleEntity, module) in modulesToUnload) {
|
||||
fireBeforeModuleRemoved(module)
|
||||
|
||||
val description = LoadedModuleDescriptionImpl(module)
|
||||
val modulePath = getModulePath(module, entityStore)
|
||||
val pointerManager = VirtualFilePointerManager.getInstance()
|
||||
val contentRoots = ModuleRootManager.getInstance(module).contentRootUrls.map { url ->
|
||||
pointerManager.create(url, this, null)
|
||||
val description = LoadedModuleDescriptionImpl(module)
|
||||
val modulePath = getModulePath(module, entityStore)
|
||||
val pointerManager = VirtualFilePointerManager.getInstance()
|
||||
val contentRoots = ModuleRootManager.getInstance(
|
||||
module).contentRootUrls.map { url ->
|
||||
pointerManager.create(url, this@ModuleManagerBridgeImpl, null)
|
||||
}
|
||||
val unloadedModuleDescription = UnloadedModuleDescriptionImpl(
|
||||
modulePath, description.dependencyModuleNames, contentRoots)
|
||||
unloadedModules[module.name] = unloadedModuleDescription
|
||||
WorkspaceModel.getInstance(project).updateProjectModelSilent {
|
||||
it.mutableModuleMap.removeMapping(moduleEntity)
|
||||
}
|
||||
fireEventAndDisposeModule(module)
|
||||
}
|
||||
val unloadedModuleDescription = UnloadedModuleDescriptionImpl(modulePath, description.dependencyModuleNames, contentRoots)
|
||||
unloadedModules[module.name] = unloadedModuleDescription
|
||||
WorkspaceModel.getInstance(project).updateProjectModelSilent {
|
||||
it.mutableModuleMap.removeMapping(moduleEntity)
|
||||
}
|
||||
fireEventAndDisposeModule(module)
|
||||
}
|
||||
|
||||
// Remove Facet bridges to recreate them. String constant is taken from
|
||||
// com.intellij.workspaceModel.ide.impl.legacyBridge.facet.FacetModelBridge.FACET_BRIDGE_MAPPING_ID
|
||||
WorkspaceModel.getInstance(project).updateProjectModelSilent { builder ->
|
||||
moduleEntitiesToLoad.flatMap { it.facets }.forEach {
|
||||
builder.getMutableExternalMapping<Any>("intellij.facets.bridge").removeMapping(it)
|
||||
// Remove Facet bridges to recreate them. String constant is taken from
|
||||
// com.intellij.workspaceModel.ide.impl.legacyBridge.facet.FacetModelBridge.FACET_BRIDGE_MAPPING_ID
|
||||
WorkspaceModel.getInstance(
|
||||
project).updateProjectModelSilent { builder ->
|
||||
moduleEntitiesToLoad.flatMap { it.facets }.forEach {
|
||||
builder.getMutableExternalMapping<Any>(
|
||||
"intellij.facets.bridge").removeMapping(it)
|
||||
}
|
||||
}
|
||||
// todo why we load modules in a write action
|
||||
runBlocking {
|
||||
loadModules(moduleEntitiesToLoad.asSequence())
|
||||
}
|
||||
}
|
||||
loadModules(moduleEntitiesToLoad.asSequence())
|
||||
}, RootsChangeRescanningInfo.NO_RESCAN_NEEDED)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun removeUnloadedModules(unloadedModules: MutableCollection<out UnloadedModuleDescription>) {
|
||||
override fun setUnloadedModulesSync(unloadedModuleNames: List<String>) {
|
||||
if (!ApplicationManager.getApplication().isDispatchThread) {
|
||||
return runBlocking(CoreProgressManager.getCurrentThreadProgressModality().asContextElement()) { setUnloadedModules(unloadedModuleNames) }
|
||||
}
|
||||
|
||||
ProgressManager.getInstance().runProcessWithProgressSynchronously(Runnable {
|
||||
val modalityState = CoreProgressManager.getCurrentThreadProgressModality()
|
||||
runBlocking(modalityState.asContextElement()) {
|
||||
setUnloadedModules(unloadedModuleNames)
|
||||
}
|
||||
}, "", true, project)
|
||||
}
|
||||
|
||||
override fun removeUnloadedModules(unloadedModules: Collection<UnloadedModuleDescription>) {
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed()
|
||||
|
||||
unloadedModules.forEach { this.unloadedModules.remove(it.name) }
|
||||
@@ -437,8 +466,8 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
|
||||
else {
|
||||
VirtualFileManager.extractPath(fileUrlValue)
|
||||
}
|
||||
paths.add(ModulePath(FileUtilRt.toSystemIndependentName(Objects.requireNonNull(filepath)),
|
||||
moduleElement.getAttributeValue(JpsProjectLoader.GROUP_ATTRIBUTE)))
|
||||
paths.add(ModulePath(path = FileUtilRt.toSystemIndependentName(filepath!!),
|
||||
group = moduleElement.getAttributeValue(JpsProjectLoader.GROUP_ATTRIBUTE)))
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.module
|
||||
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
@@ -39,7 +25,7 @@ fun <T> runWithQualifiedModuleNamesEnabled(action: () -> T): T {
|
||||
}
|
||||
|
||||
fun renameModule(module: Module, newName: String) {
|
||||
val model = ModuleManager.getInstance(module.project).modifiableModel
|
||||
val model = ModuleManager.getInstance(module.project).getModifiableModel()
|
||||
model.renameModule(module, newName)
|
||||
runWriteAction { model.commit() }
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import com.intellij.ide.impl.OpenProjectTask
|
||||
import com.intellij.ide.impl.ProjectUtil
|
||||
import com.intellij.ide.impl.runUnderModalProgressIfIsEdt
|
||||
import com.intellij.ide.startup.StartupManagerEx
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.AccessToken
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
@@ -17,12 +18,12 @@ import com.intellij.openapi.command.impl.UndoManagerImpl
|
||||
import com.intellij.openapi.command.undo.UndoManager
|
||||
import com.intellij.openapi.components.StorageScheme
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ex.ProjectEx
|
||||
import com.intellij.openapi.project.impl.ProjectImpl
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl
|
||||
import com.intellij.openapi.project.impl.runStartupActivities
|
||||
import com.intellij.openapi.project.impl.runInitProjectActivities
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.testFramework.LeakHunter
|
||||
import com.intellij.testFramework.TestApplicationManager.Companion.publishHeapDump
|
||||
@@ -31,7 +32,6 @@ import com.intellij.util.containers.UnsafeWeakList
|
||||
import com.intellij.util.ref.GCUtil
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -118,13 +118,12 @@ open class TestProjectManager : ProjectManagerImpl() {
|
||||
}
|
||||
|
||||
val app = ApplicationManager.getApplication()
|
||||
|
||||
try {
|
||||
runUnderModalProgressIfIsEdt {
|
||||
runStartupActivities(project = project,
|
||||
indicator = ProgressManager.getInstance().progressIndicator,
|
||||
runStartUpActivities = isRunStartUpActivitiesEnabled(project),
|
||||
waitEdtActivity = null)
|
||||
runInitProjectActivities(project = project)
|
||||
if (isRunStartUpActivitiesEnabled(project)) {
|
||||
(StartupManager.getInstance(project) as StartupManagerImpl).runStartupActivities()
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
@@ -142,7 +141,7 @@ open class TestProjectManager : ProjectManagerImpl() {
|
||||
return project
|
||||
}
|
||||
|
||||
private fun trackProject(project: @NotNull Project) {
|
||||
private fun trackProject(project: Project) {
|
||||
if (isTracking) {
|
||||
synchronized(this) {
|
||||
if (isTracking) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.testFramework.rules
|
||||
|
||||
import com.intellij.facet.Facet
|
||||
@@ -173,7 +173,7 @@ open class ProjectModelRule(private val forceEnableWorkspaceModel: Boolean = fal
|
||||
}
|
||||
|
||||
fun renameModule(module: Module, newName: String) {
|
||||
val model = runReadAction { moduleManager.modifiableModel }
|
||||
val model = runReadAction { moduleManager.getModifiableModel() }
|
||||
model.renameModule(module, newName)
|
||||
runWriteActionAndWait { model.commit() }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.vcs.impl;
|
||||
|
||||
import com.intellij.ProjectTopics;
|
||||
@@ -22,10 +21,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ModuleDefaultVcsRootPolicy extends DefaultVcsRootPolicy {
|
||||
public ModuleDefaultVcsRootPolicy(@NotNull Project project) {
|
||||
final class ModuleDefaultVcsRootPolicy extends DefaultVcsRootPolicy {
|
||||
ModuleDefaultVcsRootPolicy(@NotNull Project project) {
|
||||
super(project);
|
||||
|
||||
MyModulesListener listener = new MyModulesListener();
|
||||
@@ -66,14 +66,14 @@ public class ModuleDefaultVcsRootPolicy extends DefaultVcsRootPolicy {
|
||||
return result;
|
||||
}
|
||||
|
||||
private class MyModulesListener implements ModuleRootListener, ModuleListener, AdditionalLibraryRootsListener {
|
||||
private final class MyModulesListener implements ModuleRootListener, ModuleListener, AdditionalLibraryRootsListener {
|
||||
@Override
|
||||
public void rootsChanged(@NotNull ModuleRootEvent event) {
|
||||
scheduleMappedRootsUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moduleAdded(@NotNull Project project, @NotNull Module module) {
|
||||
public void modulesAdded(@NotNull Project project, @NotNull List<Module> modules) {
|
||||
scheduleMappedRootsUpdate();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ class LibraryPropertiesTest {
|
||||
val elementAsString = "<properties data=\"$propertyData\" />"
|
||||
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.workspaceModel.ide
|
||||
|
||||
import com.intellij.openapi.application.runWriteActionAndWait
|
||||
@@ -50,7 +50,7 @@ class ModifiableRootModelBridgeTest {
|
||||
@Test(expected = Test.None::class)
|
||||
fun `getting module root model from modifiable module`() {
|
||||
runWriteActionAndWait {
|
||||
val moduleModifiableModel = ModuleManager.getInstance(projectModel.project).modifiableModel
|
||||
val moduleModifiableModel = ModuleManager.getInstance(projectModel.project).getModifiableModel()
|
||||
val newModule = moduleModifiableModel.newModule(projectModel.projectRootDir.resolve("myModule/myModule.iml"),
|
||||
EmptyModuleType.EMPTY_MODULE) as ModuleBridge
|
||||
|
||||
@@ -68,7 +68,7 @@ class ModifiableRootModelBridgeTest {
|
||||
@Test(expected = Test.None::class)
|
||||
fun `get modifiable models of renamed module`() {
|
||||
runWriteActionAndWait {
|
||||
val moduleModifiableModel = ModuleManager.getInstance(projectModel.project).modifiableModel
|
||||
val moduleModifiableModel = ModuleManager.getInstance(projectModel.project).getModifiableModel()
|
||||
val newModule = moduleModifiableModel.newModule(projectModel.projectRootDir.resolve("myModule/myModule.iml"),
|
||||
EmptyModuleType.EMPTY_MODULE) as ModuleBridge
|
||||
moduleModifiableModel.commit()
|
||||
|
||||
+16
-16
@@ -82,7 +82,7 @@ class ModuleBridgesTest {
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
|
||||
val module = moduleManager.modifiableModel.let {
|
||||
val module = moduleManager.getModifiableModel().let {
|
||||
val m = it.newModule(File(project.basePath, "xxx.iml").path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
it.commit()
|
||||
m
|
||||
@@ -103,7 +103,7 @@ class ModuleBridgesTest {
|
||||
arrayOf(contentRootUrl.url)
|
||||
)
|
||||
|
||||
moduleManager.modifiableModel.let {
|
||||
moduleManager.getModifiableModel().let {
|
||||
it.disposeModule(module)
|
||||
it.commit()
|
||||
}
|
||||
@@ -115,7 +115,7 @@ class ModuleBridgesTest {
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
|
||||
val modulesModifiableModel = moduleManager.modifiableModel
|
||||
val modulesModifiableModel = moduleManager.getModifiableModel()
|
||||
try {
|
||||
val m = modulesModifiableModel.newModule(File(project.basePath, "xxx.iml").path, ModuleType.EMPTY.id) as ModuleBridge
|
||||
val rootModel = m.rootManager.modifiableModel
|
||||
@@ -143,7 +143,7 @@ class ModuleBridgesTest {
|
||||
runBlocking {
|
||||
val module = withContext(Dispatchers.EDT) {
|
||||
runWriteAction {
|
||||
val model = moduleManager.modifiableModel
|
||||
val model = moduleManager.getModifiableModel()
|
||||
val module = model.newModule(oldNameFile.path, ModuleType.EMPTY.id)
|
||||
model.commit()
|
||||
module
|
||||
@@ -159,7 +159,7 @@ class ModuleBridgesTest {
|
||||
|
||||
withContext(Dispatchers.EDT) {
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
val model = moduleManager.modifiableModel
|
||||
val model = moduleManager.getModifiableModel()
|
||||
assertSame(module, model.findModuleByName(oldModuleName))
|
||||
assertNull(model.getModuleToBeRenamed(oldModuleName))
|
||||
|
||||
@@ -212,7 +212,7 @@ class ModuleBridgesTest {
|
||||
|
||||
val (antModule, mavenModule) = withContext(Dispatchers.EDT) {
|
||||
runWriteAction {
|
||||
val model = moduleManager.modifiableModel
|
||||
val model = moduleManager.getModifiableModel()
|
||||
val antModule = model.newModule(antModuleFile.path, ModuleType.EMPTY.id)
|
||||
val mavenModule = model.newModule(mavenModuleFile.path, ModuleType.EMPTY.id)
|
||||
model.commit()
|
||||
@@ -232,7 +232,7 @@ class ModuleBridgesTest {
|
||||
|
||||
withContext(Dispatchers.EDT) {
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
val model = moduleManager.modifiableModel
|
||||
val model = moduleManager.getModifiableModel()
|
||||
model.renameModule(antModule, gradleModuleName)
|
||||
model.commit()
|
||||
}
|
||||
@@ -287,7 +287,7 @@ class ModuleBridgesTest {
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
|
||||
val module = moduleManager.modifiableModel.let {
|
||||
val module = moduleManager.getModifiableModel().let {
|
||||
val m = it.newModule(File(project.basePath, "xxx.iml").path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
it.commit()
|
||||
m
|
||||
@@ -314,7 +314,7 @@ class ModuleBridgesTest {
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
|
||||
val module = moduleManager.modifiableModel.let {
|
||||
val module = moduleManager.getModifiableModel().let {
|
||||
val m = it.newModule(File(project.basePath, "xxx.iml").path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
it.commit()
|
||||
m
|
||||
@@ -631,7 +631,7 @@ class ModuleBridgesTest {
|
||||
|
||||
val module = withContext(Dispatchers.EDT) {
|
||||
runWriteAction {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -674,7 +674,7 @@ class ModuleBridgesTest {
|
||||
val antLibraryFolder = "ant-lib"
|
||||
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -705,7 +705,7 @@ class ModuleBridgesTest {
|
||||
fun `test disposed module doesn't appear in rootsChanged`() = WriteCommandAction.runWriteCommandAction(project) {
|
||||
val moduleName = "build"
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -726,7 +726,7 @@ class ModuleBridgesTest {
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
val moduleManager = ModuleManager.getInstance(project) as ModuleManagerBridgeImpl
|
||||
|
||||
moduleManager.modifiableModel.let { modifiableModel ->
|
||||
moduleManager.getModifiableModel().let { modifiableModel ->
|
||||
modifiableModel.newModule(File(project.basePath, "xxx.iml").path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
modifiableModel.commit()
|
||||
}
|
||||
@@ -754,7 +754,7 @@ class ModuleBridgesTest {
|
||||
fun `remove module without removing module library`() = WriteCommandAction.runWriteCommandAction(project) {
|
||||
val moduleManager = ModuleManager.getInstance(project) as ModuleManagerBridgeImpl
|
||||
|
||||
val module = moduleManager.modifiableModel.let { modifiableModel ->
|
||||
val module = moduleManager.getModifiableModel().let { modifiableModel ->
|
||||
val module = modifiableModel.newModule(File(project.basePath, "xxx.iml").path, EmptyModuleType.getInstance().id)
|
||||
modifiableModel.commit()
|
||||
module as ModuleBridge
|
||||
@@ -785,13 +785,13 @@ class ModuleBridgesTest {
|
||||
fun `readd module`() = WriteCommandAction.runWriteCommandAction(project) {
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
|
||||
val module = moduleManager.modifiableModel.let { modifiableModel ->
|
||||
val module = moduleManager.getModifiableModel().let { modifiableModel ->
|
||||
val module = modifiableModel.newModule(File(project.basePath, "xxx.iml").path, EmptyModuleType.getInstance().id)
|
||||
modifiableModel.commit()
|
||||
module as ModuleBridge
|
||||
}
|
||||
|
||||
val newModule = moduleManager.modifiableModel.let { modifiableModel ->
|
||||
val newModule = moduleManager.getModifiableModel().let { modifiableModel ->
|
||||
modifiableModel.disposeModule(module)
|
||||
val newModule = modifiableModel.newModule(File(project.basePath, "xxx.iml").path, EmptyModuleType.getInstance().id)
|
||||
modifiableModel.commit()
|
||||
|
||||
+8
-8
@@ -56,7 +56,7 @@ class ModuleLibraryBridgeTest {
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
|
||||
val module = WriteCommandAction.writeCommandAction(project).compute<ModuleBridge, RuntimeException> {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -102,7 +102,7 @@ class ModuleLibraryBridgeTest {
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
|
||||
val module = WriteCommandAction.writeCommandAction(project).compute<ModuleBridge, RuntimeException> {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -166,7 +166,7 @@ class ModuleLibraryBridgeTest {
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
|
||||
val rootModel = WriteCommandAction.writeCommandAction(project).compute<ModifiableRootModel, RuntimeException> {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -257,7 +257,7 @@ class ModuleLibraryBridgeTest {
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
|
||||
val module = WriteCommandAction.writeCommandAction(project).compute<ModuleBridge, RuntimeException> {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -329,7 +329,7 @@ class ModuleLibraryBridgeTest {
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
|
||||
val moduleRootManager = WriteCommandAction.writeCommandAction(project).compute<ModuleRootManager, RuntimeException> {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -366,7 +366,7 @@ class ModuleLibraryBridgeTest {
|
||||
val gradleLibraryName = "gradle-lib"
|
||||
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -412,7 +412,7 @@ class ModuleLibraryBridgeTest {
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
|
||||
val module = WriteCommandAction.writeCommandAction(project).compute<ModuleBridge, RuntimeException> {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
@@ -453,7 +453,7 @@ class ModuleLibraryBridgeTest {
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
|
||||
val module = WriteCommandAction.writeCommandAction(project).compute<ModuleBridge, RuntimeException> {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
|
||||
+2
-2
@@ -335,7 +335,7 @@ class ProjectLibraryBridgeTest {
|
||||
assertTrue(iprFile.readText().contains(antLibraryName))
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let {
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let {
|
||||
val module = it.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
it.commit()
|
||||
module
|
||||
@@ -386,7 +386,7 @@ class ProjectLibraryBridgeTest {
|
||||
val moduleFile = File(project.basePath, "$moduleName.iml")
|
||||
val library = runBlocking { createProjectLibrary(antLibraryName, withRoots = false) }
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
val module = ModuleManager.getInstance(project).modifiableModel.let { moduleModel ->
|
||||
val module = ModuleManager.getInstance(project).getModifiableModel().let { moduleModel ->
|
||||
val module = moduleModel.newModule(moduleFile.path, EmptyModuleType.getInstance().id) as ModuleBridge
|
||||
moduleModel.commit()
|
||||
module
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.workspaceModel.ide
|
||||
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx
|
||||
@@ -127,7 +127,7 @@ class WorkspaceModelPerformanceTest(private val modulesCount: Int) {
|
||||
private fun hundredModulesRemove(modules: MutableList<Module>,
|
||||
moduleManager: ModuleManager) {
|
||||
modules.forEach {
|
||||
val modifiableModel = moduleManager.modifiableModel
|
||||
val modifiableModel = moduleManager.getModifiableModel()
|
||||
modifiableModel.disposeModule(it)
|
||||
modifiableModel.commit()
|
||||
}
|
||||
@@ -178,7 +178,7 @@ class WorkspaceModelPerformanceTest(private val modulesCount: Int) {
|
||||
private fun hundredModulesCreation(moduleManager: ModuleManager,
|
||||
modules: MutableList<Module>) {
|
||||
(1..100).forEach {
|
||||
val modifiableModel = moduleManager.modifiableModel
|
||||
val modifiableModel = moduleManager.getModifiableModel()
|
||||
modules.add(modifiableModel.newModule(File(project.basePath, "$TEST_MODULE_PREFIX$it.iml").path, EmptyModuleType.getInstance().id))
|
||||
modifiableModel.commit()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.plugins.gradle.importing;
|
||||
|
||||
import com.intellij.ide.highlighter.ModuleFileType;
|
||||
@@ -173,7 +173,7 @@ public class GradleMiscImportingTest extends GradleJavaImportingTestCase {
|
||||
);
|
||||
assertModules("project", "project.main", "project.test");
|
||||
|
||||
edt(() -> ModuleManager.getInstance(myProject).setUnloadedModules(Collections.singletonList("project.main")));
|
||||
edt(() -> ModuleManager.getInstance(myProject).setUnloadedModulesSync(Collections.singletonList("project.main")));
|
||||
assertModules("project", "project.test");
|
||||
|
||||
importProject();
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package org.jetbrains.kotlin.idea.testFramework
|
||||
|
||||
@@ -262,7 +262,7 @@ class ModuleDescription(val moduleName: String) {
|
||||
val moduleVirtualFile = LocalFileSystem.getInstance().refreshAndFindFileByNioFile(modulePath) ?: error("unable to find ${modulePath}")
|
||||
runWriteAction {
|
||||
val moduleManager = ModuleManager.getInstance(project)
|
||||
val module = with(moduleManager.modifiableModel) {
|
||||
val module = with(moduleManager.getModifiableModel()) {
|
||||
val imlPath = modulePath.resolve("$moduleName${ModuleFileType.DOT_DEFAULT_EXTENSION}")
|
||||
val module = newModule(imlPath, ModuleTypeId.JAVA_MODULE)
|
||||
PsiTestUtil.addSourceRoot(module, moduleVirtualFile.findFileByRelativePath(src) ?: error("no '$src' in $this"))
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.tools.projectWizard.wizard
|
||||
|
||||
import com.intellij.ide.RecentProjectsManager
|
||||
@@ -107,7 +107,7 @@ class NewProjectWizardModuleBuilder : EmptyModuleBuilder() {
|
||||
runWriteAction {
|
||||
wizard.jdk?.let { jdk -> JavaSdkUtil.applyJdkToProject(project, jdk) }
|
||||
}
|
||||
val modulesModel = model ?: ModuleManager.getInstance(project).modifiableModel
|
||||
val modulesModel = model ?: ModuleManager.getInstance(project).getModifiableModel()
|
||||
val success = wizard.apply(
|
||||
services = buildList {
|
||||
+IdeaServices.createScopeDependent(project)
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package org.jetbrains.kotlin.idea.test
|
||||
|
||||
@@ -63,7 +63,7 @@ abstract class KotlinMultiFileTestCase : MultiFileTestCase() {
|
||||
|
||||
override fun prepareProject(rootDir: VirtualFile) {
|
||||
if (isMultiModule) {
|
||||
val model = ModuleManager.getInstance(project).modifiableModel
|
||||
val model = ModuleManager.getInstance(project).getModifiableModel()
|
||||
|
||||
VfsUtilCore.visitChildrenRecursively(
|
||||
rootDir,
|
||||
|
||||
+6
-2
@@ -583,9 +583,13 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent
|
||||
private void projectClosed() {
|
||||
initLock.lock();
|
||||
try {
|
||||
if (!isInitialized.getAndSet(false)) return;
|
||||
if (!isInitialized.getAndSet(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Disposer.dispose(myImportingQueue);
|
||||
if (myImportingQueue != null) {
|
||||
Disposer.dispose(myImportingQueue);
|
||||
}
|
||||
|
||||
myWatcher.stop();
|
||||
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ internal val Project.trustedProjectFlow: Flow<Boolean>
|
||||
internal val Project.nativeModulesFlow: Flow<List<Module>>
|
||||
get() = messageBusFlow(ProjectTopics.MODULES, { getNativeModules() }) {
|
||||
object : ModuleListener {
|
||||
override fun moduleAdded(project: Project, module: Module) {
|
||||
override fun modulesAdded(project: Project, modules: List<Module>) {
|
||||
trySend(getNativeModules())
|
||||
}
|
||||
|
||||
|
||||
+21
-30
@@ -81,8 +81,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Key<String> getFileDataKey() {
|
||||
public @NotNull Key<String> getFileDataKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@@ -92,19 +91,16 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDefaultValue() {
|
||||
public @NotNull String getDefaultValue() {
|
||||
return LanguageLevel.getDefault().toPythonVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getImmediateValue(@NotNull Project project, @Nullable VirtualFile file) {
|
||||
public @Nullable String getImmediateValue(@NotNull Project project, @Nullable VirtualFile file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Sdk getFileSdk(@NotNull Project project, @NotNull VirtualFile file) {
|
||||
private static @Nullable Sdk getFileSdk(@NotNull Project project, @NotNull VirtualFile file) {
|
||||
final Module module = ModuleUtilCore.findModuleForFile(file, project);
|
||||
if (module != null) {
|
||||
return PythonSdkUtil.findPythonSdk(module);
|
||||
@@ -114,8 +110,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Sdk findSdkForFileOutsideTheProject(Project project, VirtualFile file) {
|
||||
private static @Nullable Sdk findSdkForFileOutsideTheProject(Project project, VirtualFile file) {
|
||||
if (file != null) {
|
||||
final List<OrderEntry> orderEntries = ProjectRootManager.getInstance(project).getFileIndex().getOrderEntriesForFile(file);
|
||||
for (OrderEntry orderEntry : orderEntries) {
|
||||
@@ -128,8 +123,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getImmediateValue(@NotNull Module module) {
|
||||
public @NotNull String getImmediateValue(@NotNull Module module) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() && LanguageLevel.FORCE_LANGUAGE_LEVEL != null) {
|
||||
return LanguageLevel.FORCE_LANGUAGE_LEVEL.toPythonVersion();
|
||||
}
|
||||
@@ -189,7 +183,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
return PythonFileType.INSTANCE.equals(FileTypeRegistry.getInstance().getFileTypeByFileName(child.getNameSequence()));
|
||||
}
|
||||
|
||||
private static void clearSdkPathCache(@NotNull final VirtualFile child) {
|
||||
private static void clearSdkPathCache(final @NotNull VirtualFile child) {
|
||||
final Project[] projects = ProjectManager.getInstance().getOpenProjects();
|
||||
for (Project project : projects) {
|
||||
final Sdk sdk = getFileSdk(project, child);
|
||||
@@ -201,7 +195,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRootsChanged(@NotNull final Project project) {
|
||||
public void afterRootsChanged(final @NotNull Project project) {
|
||||
final Map<Module, Sdk> moduleSdks = getPythonModuleSdks(project);
|
||||
final boolean needToReparseOpenFiles = ContainerUtil.exists(moduleSdks.entrySet(), entry -> {
|
||||
final Module module = entry.getKey();
|
||||
@@ -224,10 +218,11 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<@NotNull Module, @NotNull Sdk> getPythonModuleSdks(@NotNull Project project) {
|
||||
final ModuleManager moduleManager = ModuleManager.getInstance(project);
|
||||
if (moduleManager == null) return Collections.emptyMap();
|
||||
private static @NotNull Map<@NotNull Module, @NotNull Sdk> getPythonModuleSdks(@NotNull Project project) {
|
||||
ModuleManager moduleManager = ModuleManager.Companion.getInstanceIfDefined(project);
|
||||
if (moduleManager == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
final Map<Module, Sdk> result = new LinkedHashMap<>();
|
||||
for (Module module : moduleManager.getModules()) {
|
||||
@@ -284,8 +279,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
results.add(new UpdateRootTask(project, root, languageLevel, shouldSuppressSizeLimit));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static LanguageLevel guessLanguageLevelWithCaching(@NotNull Project project, @NotNull Collection<? extends @NotNull Sdk> pythonModuleSdks) {
|
||||
private static @NotNull LanguageLevel guessLanguageLevelWithCaching(@NotNull Project project, @NotNull Collection<? extends @NotNull Sdk> pythonModuleSdks) {
|
||||
LanguageLevel languageLevel = LanguageLevel.fromPythonVersion(project.getUserData(KEY));
|
||||
if (languageLevel == null) {
|
||||
languageLevel = guessLanguageLevel(pythonModuleSdks);
|
||||
@@ -299,8 +293,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
project.putUserData(KEY, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static LanguageLevel guessLanguageLevel(@NotNull Collection<? extends @NotNull Sdk> pythonModuleSdks) {
|
||||
private static @NotNull LanguageLevel guessLanguageLevel(@NotNull Collection<? extends @NotNull Sdk> pythonModuleSdks) {
|
||||
LanguageLevel maxLevel = null;
|
||||
for (Sdk sdk : pythonModuleSdks) {
|
||||
final LanguageLevel level = PythonRuntimeService.getInstance().getLanguageLevelForSdk(sdk);
|
||||
@@ -319,8 +312,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
*
|
||||
* @see LanguageLevel#forElement
|
||||
*/
|
||||
@NotNull
|
||||
public static LanguageLevel getLanguageLevelForVirtualFile(@NotNull Project project, @NotNull VirtualFile virtualFile) {
|
||||
public static @NotNull LanguageLevel getLanguageLevelForVirtualFile(@NotNull Project project, @NotNull VirtualFile virtualFile) {
|
||||
if (virtualFile instanceof VirtualFileWindow) {
|
||||
virtualFile = ((VirtualFileWindow)virtualFile).getDelegate();
|
||||
}
|
||||
@@ -339,9 +331,9 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
}
|
||||
|
||||
private final class UpdateRootTask implements Runnable {
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final VirtualFile myRoot;
|
||||
@NotNull private final LanguageLevel myLanguageLevel;
|
||||
private final @NotNull Project myProject;
|
||||
private final @NotNull VirtualFile myRoot;
|
||||
private final @NotNull LanguageLevel myLanguageLevel;
|
||||
private final boolean myShouldSuppressSizeLimit;
|
||||
|
||||
UpdateRootTask(@NotNull Project project, @NotNull VirtualFile root, @NotNull LanguageLevel languageLevel,
|
||||
@@ -401,8 +393,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
file.putUserData(KEY, languageLevel == null ? null : languageLevel.toPythonVersion());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static LanguageLevel specifiedFileLanguageLevel(@Nullable VirtualFile file) {
|
||||
private static @Nullable LanguageLevel specifiedFileLanguageLevel(@Nullable VirtualFile file) {
|
||||
if (file == null) return null;
|
||||
|
||||
final LanguageLevel specified = LanguageLevel.fromPythonVersion(file.getUserData(KEY));
|
||||
@@ -421,7 +412,7 @@ public final class PythonLanguageLevelPusher implements FilePropertyPusher<Strin
|
||||
}
|
||||
|
||||
private final class MyDumbModeTask extends DumbModeTask {
|
||||
private @NotNull final Project project;
|
||||
private final @NotNull Project project;
|
||||
private final @NotNull Map<Module, Sdk> moduleSdks;
|
||||
private final SimpleMessageBusConnection connection;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user