IJPL-232406 Remove ProjectExtension

GitOrigin-RevId: 4940b5614a90b18fd37eafdf3df68edcbe96b4c3
This commit is contained in:
Ilya Korennoy
2026-01-29 15:57:58 +04:00
committed by intellij-monorepo-bot
parent 05eff311a7
commit e4dc204f65
6 changed files with 59 additions and 49 deletions

View File

@@ -9,9 +9,12 @@ import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.roots.ProjectExtension;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.platform.backend.workspace.WorkspaceModel;
import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener;
import com.intellij.platform.backend.workspace.WorkspaceModelTopics;
import com.intellij.platform.workspace.jps.entities.ProjectSettingsEntity;
import com.intellij.platform.workspace.storage.VersionedStorageChange;
import com.intellij.pom.java.JavaRelease;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.ObjectUtils;
@@ -39,6 +42,15 @@ public final class LanguageLevelProjectExtensionImpl extends LanguageLevelProjec
public LanguageLevelProjectExtensionImpl(final Project project) {
myProject = project;
myProject.getMessageBus().simpleConnect().subscribe(WorkspaceModelTopics.CHANGED, new WorkspaceModelChangeListener() {
@Override
public void changed(@NotNull VersionedStorageChange event) {
if (!event.getChanges(ProjectSettingsEntity.class).isEmpty()) {
projectSdkChanged(ProjectRootManager.getInstance(myProject).getProjectSdk());
}
}
});
}
public static LanguageLevelProjectExtensionImpl getInstanceImpl(Project project) {
@@ -166,16 +178,4 @@ public final class LanguageLevelProjectExtensionImpl extends LanguageLevelProjec
setLanguageLevelInternal(null, null);
}
static final class MyProjectExtension extends ProjectExtension {
private final LanguageLevelProjectExtensionImpl myInstance;
MyProjectExtension(@NotNull Project project) {
myInstance = ((LanguageLevelProjectExtensionImpl)getInstance(project));
}
@Override
public void projectSdkChanged(@Nullable Sdk sdk) {
myInstance.projectSdkChanged(sdk);
}
}
}

View File

@@ -0,0 +1,45 @@
// Copyright 2000-2026 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;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.JavaProjectTestCase;
public class LanguageLevelProjectExtensionTest extends JavaProjectTestCase {
public void testLanguageLevelChangesWhenProjectSdkChanges() {
LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(myProject);
Sdk jdk17 = IdeaTestUtil.getMockJdk17();
WriteAction.run(() -> ProjectJdkTable.getInstance().addJdk(jdk17, getTestRootDisposable()));
// Initialize: set language level to JDK 17 with default=true
// This enables automatic language level updates when SDK changes
WriteAction.run(() -> {
extension.setLanguageLevel(LanguageLevel.JDK_1_7);
extension.setDefault(true);
});
WriteAction.run(() -> ProjectRootManager.getInstance(myProject).setProjectSdk(jdk17));
assertTrue("Language level should be default", extension.isDefault());
assertEquals("Language level should match JDK 1.7",
LanguageLevel.JDK_1_7, extension.getLanguageLevel());
Sdk jdk18 = IdeaTestUtil.getMockJdk18();
WriteAction.run(() -> ProjectJdkTable.getInstance().addJdk(jdk18, getTestRootDisposable()));
// Change project SDK to JDK 1.8 - this should trigger language level update
WriteAction.run(() -> ProjectRootManager.getInstance(myProject).setProjectSdk(jdk18));
// Verify language level changed to JDK_1_8
assertTrue("Language level should still be default", extension.isDefault());
assertEquals("Language level should match JDK 1.8",
LanguageLevel.JDK_1_8, extension.getLanguageLevel());
}
}

View File

@@ -36,7 +36,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.projectRoots.SimpleJavaSdkType;
import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.roots.ProjectExtension;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.serialization.ObjectSerializer;
import com.intellij.ui.PlaceHolder;
@@ -116,7 +115,6 @@ public final class RemoteExternalSystemCommunicationManager implements ExternalS
ContainerUtil.addIfNotNull(classPath, getJarPathForClass(Project.class)); //intellij.platform.core
ContainerUtil.addIfNotNull(classPath, getJarPathForClass(PlaceHolder.class)); //intellij.platform.editor
ContainerUtil.addIfNotNull(classPath, getJarPathForClass(DependencyScope.class)); //intellij.platform.projectModel
ContainerUtil.addIfNotNull(classPath, getJarPathForClass(ProjectExtension.class)); //intellij.platform.projectModel.impl
ContainerUtil.addIfNotNull(classPath, getJarPathForClass(Alarm.class)); //intellij.platform.ide
ContainerUtil.addIfNotNull(classPath, getJarPathForClass(ExtensionPointName.class)); //intellij.platform.extensions
ContainerUtil.addIfNotNull(classPath, getJarPathForClass(StorageUtilKt.class)); //intellij.platform.ide.impl

View File

@@ -2,7 +2,6 @@
<extensionPoints>
<extensionPoint name="additionalLibraryRootsProvider" interface="com.intellij.openapi.roots.AdditionalLibraryRootsProvider"
dynamic="true"/>
<extensionPoint name="projectExtension" interface="com.intellij.openapi.roots.ProjectExtension" area="IDEA_PROJECT" dynamic="true"/>
<extensionPoint name="workspaceModel.moduleExtensionBridgeFactory"
interface="com.intellij.workspaceModel.ide.legacyBridge.ModuleExtensionBridgeFactory"
dynamic="true"/>

View File

@@ -1,21 +0,0 @@
// Copyright 2000-2023 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.projectRoots.Sdk;
import org.jdom.Element;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Provides a way to store additional configuration for a project. Plugins must not use this class, but use project-level
* <a href="https://plugins.jetbrains.com/docs/intellij/plugin-services.html">services</a> implementing {@link com.intellij.openapi.components.PersistentStateComponent}
* instead.
*
* <p>This class is used for some data which is historically stored as part of {@code ProjectRootManager} configuration in .idea/misc.xml file.</p>
*/
@ApiStatus.Internal
public abstract class ProjectExtension {
public void projectSdkChanged(@Nullable Sdk sdk) {
}
}

View File

@@ -1,10 +1,9 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2026 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
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.State
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.extensions.ProjectExtensionPointName
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.ModuleListener
@@ -36,8 +35,6 @@ import java.util.concurrent.ConcurrentHashMap
private val LOG = logger<ProjectRootManagerImpl>()
private val EP_NAME = ProjectExtensionPointName<ProjectExtension>("com.intellij.projectExtension")
@State(name = "ProjectRootManager")
@ApiStatus.Internal
open class ProjectRootManagerImpl(
@@ -314,14 +311,6 @@ open class ProjectRootManagerImpl(
// There is no mergeRootsChangesDuring because currently it has a bug: "after" event will never fire if mergeRootsChangesDuring
// is invoked while another rootsChange event (caused by the WSM change) is in progress (see RootsChangedTest).
actionToRunWhenProjectJdkChanges.run()
fireJdkChanged()
}
private fun fireJdkChanged() {
val sdk = getProjectSdk()
for (extension in EP_NAME.getExtensions(project)) {
extension.projectSdkChanged(sdk)
}
}
@get:ApiStatus.Internal